diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 1ef99d6125..22db9f1514 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -51,16 +51,16 @@ AppDir: - libgles2 # if QT:BOOL=ON - libglvnd0 # if QT:BOOL=ON - libglx0 # if QT:BOOL=ON + - libgomp1 - libgs9 - libpng16-16 - libqt5core5a # if QT:BOOL=ON - libqt5gui5 # if QT:BOOL=ON - libqt5widgets5 # if QT:BOOL=ON - libsixel1 # if CLI:BOOL=ON - - libslirp0 # if SLIRP_EXTERNAL:BOOL=ON + - libslirp0 - libsndio7.0 # if OPENAL:BOOL=ON - libvdeplug-dev # -dev also pulls in libvdeplug2. -dev is required to get the proper .so symlink to the library - - libwayland-client0 # if QT:BOOL=ON - libx11-6 # if QT:BOOL=ON - libx11-xcb1 # if QT:BOOL=ON - libxcb1 # if QT:BOOL=ON diff --git a/.ci/build.sh b/.ci/build.sh index e425cc65a7..1b1e5825e6 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -24,8 +24,8 @@ # - For Windows (MSYS MinGW) builds: # - Packaging requires 7-Zip on Program Files # - Packaging the Ghostscript DLL requires 32-bit and/or 64-bit Ghostscript on Program Files -# - Packaging the FluidSynth DLL requires it to be at /home/86Box/dll32/libfluidsynth.dll -# and/or /home/86Box/dll64/libfluidsynth64.dll (for 32-bit and 64-bit builds respectively) +# - Packaging the XAudio2 DLL for FAudio requires it to be at /home/86Box/dll32/xaudio2*.dll +# and/or /home/86Box/dll64/xaudio2*.dll (for 32-bit and 64-bit builds respectively) # - For Linux builds: # - Only Debian and derivatives are supported # - dpkg and apt-get are called through sudo to manage dependencies; make sure those @@ -259,6 +259,7 @@ case $arch in esac [ ! -e "cmake/$toolchain.cmake" ] && toolchain=flags-gcc toolchain_file="cmake/$toolchain.cmake" +toolchain_file_libs= # Perform platform-specific setup. strip_binary=strip @@ -287,7 +288,6 @@ then echo [-] Using MSYSTEM [$MSYSTEM] # Install dependencies only if we're in a new build and/or architecture. - freetype_dll="$cache_dir/freetype.$MSYSTEM.dll" if check_buildtag "$MSYSTEM" then # Update databases and keyring only if we're in a new build. @@ -332,9 +332,6 @@ then # Clean pacman cache when running under Jenkins to save disk space. [ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg - # Generate a new freetype DLL for this architecture. - rm -f "$freetype_dll" - # Save build tag to skip this later. Doing it here (once everything is # in place) is important to avoid potential issues with retried builds. save_buildtag "$MSYSTEM" @@ -543,12 +540,25 @@ then # Attempt to install dependencies. sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log - # Stop if no port version activation errors were found. + # Check for port activation errors. stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10) - [ -z $stuck_dep ] && break + if [ -n "$stuck_dep" ] + then + # Deactivate the stuck dependency and try again. + sudo "$macports/bin/port" -f deactivate "$stuck_dep" + continue + fi + + stuck_dep=$(grep " Please deactivate this port first, or " macports.log | cut -d" " -f5 | tr -d :) + if [ -n "$stuck_dep" ] + then + # Activate the stuck dependency and try again. + sudo "$macports/bin/port" -f activate "$stuck_dep" + continue + fi - # Deactivate the stuck dependency and try again. - sudo "$macports/bin/port" -f deactivate $stuck_dep + # Stop if no errors were found. + break done # Remove MacPorts error detection log. @@ -569,6 +579,7 @@ else arm32) arch_deb="armhf";; *) arch_deb="$arch";; esac + grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version # Establish general dependencies. pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream" @@ -577,7 +588,7 @@ else pkgs="$pkgs build-essential" else # Add foreign architecture if required. - if ! dpkg --print-foreign-architectures | grep -Fx "$arch_deb" + if ! dpkg --print-foreign-architectures | grep -Fqx "$arch_deb" then sudo dpkg --add-architecture "$arch_deb" @@ -594,7 +605,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 + 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 do libpkgs="$libpkgs $pkg:$arch_deb" length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c) @@ -615,10 +626,7 @@ else *) libdir="$arch_triplet";; esac - # Create CMake cross toolchain file. The file is saved on a fixed location for - # the library builds we do later, since running CMake again on a library we've - # already built before will *not* update its toolchain file path; therefore, we - # cannot point them to our working directory, which may change across builds. + # Create CMake cross toolchain file. toolchain_file_new="$cache_dir/toolchain.$arch_deb.cmake" cat << EOF > "$toolchain_file_new" set(CMAKE_SYSTEM_NAME Linux) @@ -646,6 +654,14 @@ EOF toolchain_file="$toolchain_file_new" strip_binary="$arch_triplet-strip" + # Create a separate toolchain file for library compilation without including + # our own toolchain files, letting libraries set their own C(XX)FLAGS instead. + # The file is saved on a fixed location, since running CMake again on a library + # we've already built before will *not* update its toolchain file path; therefore, + # we cannot point them to our working directory, which may change across builds. + toolchain_file_libs="$cache_dir/toolchain.$arch_deb.libs.cmake" + grep -Ev "^include\(" "$toolchain_file" > "$toolchain_file_libs" + # Install dependencies only if we're in a new build and/or architecture. if check_buildtag "$arch_deb" then @@ -668,9 +684,6 @@ EOF else echo [-] Not installing dependencies again fi - - # Link against the system libslirp instead of compiling ours. - cmake_flags_extra="$cmake_flags_extra -D SLIRP_EXTERNAL=ON" fi # Point CMake to the toolchain file. @@ -790,10 +803,6 @@ then sevenzip="$pf/7-Zip/7z.exe" [ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)" - # Archive freetype from cache or generate it from local MSYS installation. - [ ! -e "$freetype_dll" ] && .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a "$freetype_dll" - cp -p "$freetype_dll" archive_tmp/freetype.dll - # Archive Ghostscript DLL from local official distribution installation. for gs in "$pf"/gs/gs*.*.* do @@ -804,8 +813,8 @@ then "$sevenzip" e -y -o"archive_tmp" "$discord_zip" "lib/$arch_discord/discord_game_sdk.dll" [ ! -e "archive_tmp/discord_game_sdk.dll" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] - # Archive other DLLs from local directory. - cp -p "/home/$project/dll$arch/"* archive_tmp/ + # Archive XAudio2 DLL if required. + grep -q "OPENAL:BOOL=ON" build/CMakeCache.txt || cp -p "/home/$project/dll$arch/xaudio2"* archive_tmp/ # Archive executable, while also stripping it if requested. if [ $strip -ne 0 ] @@ -885,11 +894,6 @@ else cwd_root="$(pwd)" check_buildtag "libs.$arch_deb" - cp cmake/flags-gcc.cmake cmake/flags-gcc.cmake.old - sed -i -e 's/ -Werror=.*\([" ]\)/\1/g' cmake/flags-gcc.cmake # temporary hack for -Werror=old-style-definition non-compliance on FluidSynth and SDL2 - sed -i -e 's/ C;CXX/ IGNORED/' cmake/flags-gcc.cmake # workaround for dynamic c(xx)flags system overwriting library flags and breaking (at least) openal-soft - sed -i -e 's/_INIT / /g' cmake/flags-gcc.cmake # still append our own flags - if grep -q "OPENAL:BOOL=ON" build/CMakeCache.txt then # Build openal-soft 1.23.1 manually to fix audio issues. This is a temporary @@ -906,7 +910,7 @@ else sed -i -e 's/PW_KEY_CONFIG_NAME/"config.name"/g' "$prefix/alc/backends/pipewire.cpp" prefix_build="$prefix/build-$arch_deb" - cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake -G Ninja -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 cmake --install "$prefix_build" || exit 99 @@ -922,7 +926,7 @@ else wget -qO - https://github.com/FNA-XNA/FAudio/archive/refs/tags/22.03.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi prefix_build="$prefix/build-$arch_deb" - cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake -G Ninja -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 cmake --install "$prefix_build" || exit 99 @@ -943,7 +947,7 @@ else wget -qO - https://github.com/thestk/rtmidi/archive/refs/tags/4.0.0.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi prefix_build="$prefix/build-$arch_deb" - cmake -G Ninja -D RTMIDI_API_JACK=OFF -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake -G Ninja -D RTMIDI_API_JACK=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 cmake --install "$prefix_build" || exit 99 @@ -957,7 +961,7 @@ else 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 \ - -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" \ + -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 cmake --install "$prefix_build" || exit 99 @@ -988,12 +992,24 @@ else -D SDL_ATOMIC=OFF -D SDL_EVENTS=ON -D SDL_HAPTIC=OFF -D SDL_POWER=OFF -D SDL_THREADS=ON -D SDL_TIMERS=ON -D SDL_FILE=OFF \ -D SDL_LOADSO=ON -D SDL_CPUINFO=ON -D SDL_FILESYSTEM=$sdl_ui -D SDL_DLOPEN=OFF -D SDL_SENSOR=OFF -D SDL_LOCALE=OFF \ \ - -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" \ + -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 cmake --install "$prefix_build" || exit 99 - mv cmake/flags-gcc.cmake.old cmake/flags-gcc.cmake + # We rely on the host to provide Vulkan libs to sidestep any potential + # dependency issues. While Qt expects libvulkan.so, at least Debian only + # ships libvulkan.so.1 without a symlink, so make our own as a workaround. + # The relative paths prevent appimage-builder from flattening the links. + mkdir -p "archive_tmp/usr/lib/$libdir" + relroot="../../../../../../../../../../../../../../../../../../../../../../../../../../../../.." + ln -s "$relroot/usr/lib/libvulkan.so.1" "archive_tmp/usr/lib/libvulkan.so" + ln -s "$relroot/usr/lib/$libdir/libvulkan.so.1" "archive_tmp/usr/lib/$libdir/libvulkan.so" + + # The FluidSynth packaged by Debian bullseye is ABI incompatible with + # the newer version we compile, despite sharing a major version. Since we + # don't run into the one breaking ABI change they made, just symlink it. + ln -s "$(readlink "archive_tmp/usr/lib/libfluidsynth.so.3")" "archive_tmp/usr/lib/libfluidsynth.so.2" # Archive Discord Game SDK library. 7z e -y -o"archive_tmp/usr/lib" "$discord_zip" "lib/$arch_discord/discord_game_sdk.so" diff --git a/.ci/dependencies_macports.txt b/.ci/dependencies_macports.txt index e78d4a6da9..5ec71d07cd 100644 --- a/.ci/dependencies_macports.txt +++ b/.ci/dependencies_macports.txt @@ -13,4 +13,5 @@ qt5 wget fluidsynth ghostscript +libslirp vde2 diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index df49323522..22601b643a 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -8,5 +8,7 @@ SDL2 zlib libpng rtmidi +libslirp +fluidsynth qt5-static qt5-translations diff --git a/.ci/static2dll.sh b/.ci/static2dll.sh deleted file mode 100755 index 0308987527..0000000000 --- a/.ci/static2dll.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/bin/sh -# -# 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. -# -# Script for converting MinGW static libraries into a DLL. -# -# -# Authors: RichardG, -# -# Copyright 2021 RichardG. -# - -def_file="static2dll.def" -seen_file="static2dll.seen" -libs_file="static2dll.libs" - -find_lib() { - # Try to find a static library's file. - local msystem_lib="/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/lib/lib" - if [ -e "$msystem_lib$1.a" ] - then - echo "$msystem_lib$1.a" - elif [ -e "$msystem_lib$1.dll.a" ] - then - echo "$msystem_lib$1.dll.a" - else - # Return dynamic reference to the library. - echo "-l$1" - return 1 - fi -} - -add_lib() { - # Always make sure this lib is listed after the last lib that depends on it. - old_libs=$(cat "$libs_file") - rm -f "$libs_file" - for lib in $old_libs - do - [ "$lib" != "$*" ] && echo "$lib" >> "$libs_file" - done - echo "$*" >> "$libs_file" - - # Add libstdc++ in the end if required. - if echo "$*" | grep -q "/" - then - grep -Eq -- "__cxa_|__gxx_" "$1" 2> /dev/null && add_lib -static -lstdc++ - fi - - # Add libiconv for libintl. - if echo "$*" | grep -q "libintl" - then - add_lib $(find_lib iconv) - fi - - # Add libuuid for glib. - if echo "$*" | grep -q "libglib" - then - add_lib $(find_lib uuid) - fi -} - -run_pkgconfig() { - local cache_file="static2dll.$1.cache" - if [ -e "$cache_file" ] - then - cat "$cache_file" - else - pkg-config --static --libs "$1" 2> /dev/null | tee "$cache_file" - fi -} - -parse_pkgconfig() { - # Parse arguments. - local layers=$1 - shift - local input_lib_name=$1 - shift - - # Don't process the same file again. - grep -q '^'$input_lib_name'$' "$seen_file" && return - echo $input_lib_name >> "$seen_file" - - echo "$layers" parse_pkgconfig $input_lib_name - - # Parse pkg-config arguments. - for arg in $* - do - local arg_base="$(echo $arg | cut -c1-2)" - if [ "x$arg_base" = "x-l" ] - then - # Don't process the same lib again. - local lib_name="$(echo $arg | cut -c3-)" - [ "x$lib_name" == "x$input_lib_name" ] && continue - - # Add lib path. - add_lib "$(find_lib $lib_name)" - - # Get this lib's dependencies through pkg-config. - local pkgconfig="$(run_pkgconfig "$lib_name")" - [ $? -eq 0 ] && parse_pkgconfig "$layers"'>' "$lib_name" $pkgconfig || echo $lib_name >> "$seen_file" - elif [ "x$(echo $arg_base | cut -c1)" = "x-" ] - then - # Ignore other arguments. - continue - else - # Add lib path. - add_lib "$arg" - fi - done -} - -# Parse arguments. -case $1 in - -p) # -p pkg_config_name static_lib_path out_dll - shift - base_pkgconfig=$(run_pkgconfig "$1") - base_path="$2" - base_name="$1" - ;; - - *) # pc_path static_lib_path out_dll - base_pkgconfig="$(grep ^Libs.private: $1 | cut -d: -f2-)" - base_path="$2" - base_name="$2" - ;; -esac - -# Check arguments. -if [ -z "$base_pkgconfig" -o -z "$base_path" -o -z "$base_name" ] -then - echo Usage: - echo static2dll.sh -p {pkgconfig_package_name} {static_lib_path} {out_dll_name} - echo static2dll.sh {pc_file_path} {static_lib_path} {out_dll_name} - exit 1 -fi - -# Produce .def file. -echo LIBRARY $(basename "$3") > "$def_file" -echo EXPORTS >> "$def_file" -nm "$base_path" | grep " [TC] " | sed "/ _/s// /" | awk '{ print $3 }' >> "$def_file" - -# Parse dependencies recursively. -rm -f "$seen_file" "$libs_file" "$libs_file.tmp" -touch "$seen_file" "$libs_file" -parse_pkgconfig '>' $base_name $base_pkgconfig - -# Produce final DLL. -dllwrap --def "$def_file" -o "$3" -Wl,--allow-multiple-definition "$base_path" $(cat "$libs_file") -status=$? -[ $status -eq 0 ] && rm -f "$def_file" "$seen_file" "$libs_file" "static2dll.*.cache" - -# Update final DLL timestamp. -touch -r "$base_path" "$3" - -exit $status diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..32eb262c92 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,21 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.cc text +*.cpp text +*.h text +*.hpp text +*.rc text + + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.ico binary +*.png binary +*.jpg binary +*.dat diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2326a920ca..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. Windows 10] - - 86Box version: [e.g. v3.7.1 build 4032; saying "Latest from Jenkins" isn't helpful] - - Build information: [i.e. new/old dynarec, architecture and build type] - -**Additional context** -Add any other context about the problem here. If you are using an Optimized build, make sure to try the regular build too before filing a bug report! diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..cdbc0a56f3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,80 @@ +name: Bug Report +description: File a bug report +title: "Title" +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! + validations: + required: true + - type: textarea + attributes: + label: Configuration file + description: Please copy and paste your machine configuration file (`86box.cfg`). This will be automatically formatted into code, so no need for backticks. + render: ini + validations: + required: true + - type: input + attributes: + label: Operating system + description: What is your host operating system? + placeholder: e.g. Windows 10 + validations: + required: true + - type: input + attributes: + label: CPU + description: What is your host CPU? + placeholder: e.g. AMD Ryzen 5 5600G + validations: + required: true + - type: input + attributes: + label: 86Box version + description: What version of 86Box are you running? (Saying "Latest from Jenkins" is not helpful.) + placeholder: e.g. v4.0 build 5000 + validations: + required: true + - type: dropdown + attributes: + label: Build architecture + description: 86Box for what architecture are you using? + options: + - Linux - ARM (32-bit) + - Linux - ARM (64-bit) + - Linux - x64 (64-bit) + - Linux - x86 (32-bit) + - macOS - Universal (Intel and Apple Silicon) + - Windows - x64 (64-bit) + - Windows - x86 (32-bit) + validations: + required: true + - type: checkboxes + attributes: + label: Build type + description: What type of build are you using? + options: + - label: New recompiler + - label: Debug build + - type: dropdown + attributes: + label: Download source + description: Where did you download 86Box from? + options: + - Official website (Jenkins, GitHub) + - Manager auto-update + - I built 86Box myself (please tell us more about your build configuration) + - I got 86Box from a third party repository (please tell us where) + validations: + required: true + - type: textarea + attributes: + label: Additional context + description: Is there anything else you want to tell us? diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index cc1ec7f8e3..c03c507641 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,8 @@ blank_issues_enabled: false contact_links: - - name: Question + - name: Machine Request + url: https://github.com/86Box/86Box/issues/3577#issue-comment-box + about: Please submit machine addition requests under this tracking issue. + - name: Feature Request or Question url: https://github.com/86Box/86Box/discussions - about: Please ask and answer questions here. + about: Please submit feature requests and ask questions here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 4fe86d5ec8..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: feature -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 16b56cc10e..fd81701a72 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -1,4 +1,4 @@ -name: MSYS2 Makefile +name: MSYS2 Makefile (Windows, Legacy) on: @@ -16,7 +16,9 @@ on: jobs: msys2: - name: "Windows MSYS2 Makefile (Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" + # Negative condition disables the job + if: false + name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" runs-on: windows-2022 @@ -90,10 +92,11 @@ jobs: libpng:p openal:p rtmidi:p - libvncserver:p + libslirp:p + fluidsynth:p - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: make run: >- diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 49ea8c8903..0000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,458 +0,0 @@ -name: CMake - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/cmake.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/cmake.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - msys2: - name: "Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - static: on - - name: Qt GUI - qt: on - static: off - slug: -Qt - packages: >- - qt5-base:p - qt5-tools:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libvncserver:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v1 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: | - cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: build/artifacts/** - - llvm-windows: - name: "Windows vcpkg/LLVM (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }})" - if: 0 - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - - name: Qt GUI - qt: on - slug: -Qt - target: - - name: x86 - triplet: x86-windows-static - toolchain: ./cmake/llvm-win32-i686.cmake - vcvars: x64_x86 - - name: x64 - triplet: x64-windows-static - toolchain: ./cmake/llvm-win32-x86_64.cmake - vcvars: x64 - - name: ARM64 - triplet: arm64-windows-static - toolchain: ./cmake/llvm-win32-aarch64.cmake - vcvars: x64_arm64 - exclude: - - dynarec: - new: off - target: - name: ARM64 - - steps: - - name: Prepare VS environment - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.target.vcvars }} - - - name: Add LLVM to path - run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH - - - name: Download Ninja - run: > - Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip && - Expand-Archive ninja-win.zip -DestinationPath . - - - name: Setup NuGet Credentials - run: > - & (C:/vcpkg/vcpkg fetch nuget | tail -n 2) - sources add - -source "https://nuget.pkg.github.com/86Box/index.json" - -storepasswordincleartext - -name "GitHub" - -username "86Box" - -password "${{ secrets.GITHUB_TOKEN }}" - - - name: Fix MSVC atomic headers - run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del - - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v1 - - - name: Configure CMake - run: > - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} - -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} - -D VCPKG_HOST_TRIPLET=x64-windows - -D VCPKG_USE_HOST_TOOLS=ON - - - name: Fix Qt - if: matrix.ui.qt == 'on' - run: | - $qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake" - (Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath - - - name: Reconfigure CMake - if: matrix.ui.qt == 'on' - run: | - cmake clean build - - - name: Build - run: | - build-wrapper-win-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner -# if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' - path: build/artifacts/** - - linux: - name: "Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: ubuntu-22.04 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qtbase5-dev - qtbase5-private-dev - qttools5-dev - libevdev-dev - libxkbcommon-x11-dev - - steps: - - name: Install dependencies - run: >- - sudo apt update && sudo apt install - build-essential - ninja-build - libfreetype-dev - libsdl2-dev - libpng-dev - libc6-dev - librtmidi-dev - libopenal-dev - libvncserver-dev - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v1 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - - - name: Build - run: | - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner -# if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' - path: build/artifacts/** - - macos11: - name: "macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: macos-11 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: debug - slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qt@5 - - steps: - - name: Install dependencies - run: >- - brew install - ninja - freetype - sdl2 - libpng - rtmidi - openal-soft - libvncserver - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v1 - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D Qt5_ROOT=$(brew --prefix qt@5) - -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) - -D OpenAL_ROOT=$(brew --prefix openal-soft) - - - name: Build - run: | - build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner -# if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: | - cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' - path: build/artifacts/** diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml new file mode 100644 index 0000000000..12cb21303b --- /dev/null +++ b/.github/workflows/cmake_linux.yml @@ -0,0 +1,121 @@ +name: CMake (Linux) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + linux: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: ubuntu-22.04 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + static: on + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qtbase5-dev + qtbase5-private-dev + qttools5-dev + libevdev-dev + libxkbcommon-x11-dev + + steps: + - name: Install dependencies + run: >- + sudo apt update && sudo apt install + build-essential + ninja-build + libfreetype-dev + libsdl2-dev + libpng-dev + libc6-dev + librtmidi-dev + libopenal-dev + libslirp-dev + libfluidsynth-dev + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + + - name: Build + run: | + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner +# if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml new file mode 100644 index 0000000000..e51c652a41 --- /dev/null +++ b/.github/workflows/cmake_macos.yml @@ -0,0 +1,126 @@ +name: CMake (macos) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + macos12: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: macos-12 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + static: on + src-packages: >- + libsndfile + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qt@5 + src-packages: >- + libsndfile + + steps: + - name: Install source dependencies + run: >- + brew reinstall -s + ${{ matrix.ui.src-packages }} + + - name: Install dependencies + run: >- + brew install + ninja + freetype + sdl2 + libpng + rtmidi + openal-soft + fluidsynth + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D Qt5_ROOT=$(brew --prefix qt@5) + -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) + -D OpenAL_ROOT=$(brew --prefix openal-soft) + + - name: Build + run: | + build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_llvm.yml b/.github/workflows/cmake_windows_llvm.yml new file mode 100644 index 0000000000..a49f9488a1 --- /dev/null +++ b/.github/workflows/cmake_windows_llvm.yml @@ -0,0 +1,163 @@ +name: CMake (Windows, vcpkg/LLVM) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + llvm-windows: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }}" + if: 0 + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Win32 GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + target: + - name: x86 + triplet: x86-windows-static + toolchain: ./cmake/llvm-win32-i686.cmake + vcvars: x64_x86 + - name: x64 + triplet: x64-windows-static + toolchain: ./cmake/llvm-win32-x86_64.cmake + vcvars: x64 +# - name: ARM +# triplet: arm-windows-static +# toolchain: ./cmake/llvm-win32-arm.cmake +# vcvars: x64_arm + - name: ARM64 + triplet: arm64-windows-static + toolchain: ./cmake/llvm-win32-aarch64.cmake + vcvars: x64_arm64 + exclude: + - dynarec: + new: off + target: + name: ARM64 + + steps: + - name: Prepare VS environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.target.vcvars }} + + - name: Add LLVM to path + run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH + + - name: Download Ninja + run: > + Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip && + Expand-Archive ninja-win.zip -DestinationPath . + + - name: Setup NuGet Credentials + run: > + & (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2) + sources add + -source "https://nuget.pkg.github.com/86Box/index.json" + -storepasswordincleartext + -name "GitHub" + -username "86Box" + -password "${{ secrets.GITHUB_TOKEN }}" + + - name: Fix MSVC atomic headers + run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: > + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} + -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} + -D VCPKG_HOST_TRIPLET=x64-windows + -D VCPKG_USE_HOST_TOOLS=ON + + - name: Fix Qt + if: matrix.ui.qt == 'on' + run: | + $qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake" + (Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath + + - name: Reconfigure CMake + if: matrix.ui.qt == 'on' + run: | + cmake clean build + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: | + cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml new file mode 100644 index 0000000000..c7d77307cd --- /dev/null +++ b/.github/workflows/cmake_windows_msys2.yml @@ -0,0 +1,145 @@ +name: CMake (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + msys2: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: debug + slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Qt GUI + qt: on + static: on + slug: -Qt + packages: >- + qt5-static:p +# qt5-base:p +# qt5-tools:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake + - msystem: MINGW32 + prefix: mingw-w64-i686 + toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@v2 + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 107755af62..0000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,298 +0,0 @@ -name: CodeQL - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/codeql.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/codeql.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - analyze-msys2: - name: "Analyze Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" - - runs-on: windows-2022 - - permissions: - actions: read - contents: read - security-events: write - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Win32 GUI - qt: off - static: on - - name: Qt GUI - qt: on - static: off - slug: -Qt - packages: >- - qt5-base:p - qt5-tools:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake - - msystem: UCRT64 - prefix: mingw-w64-ucrt-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libvncserver:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: cmake --build build - - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" - - analyze-linux: - - name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: ubuntu-22.04 - - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qtbase5-dev - qtbase5-private-dev - qttools5-dev - libevdev-dev - libxkbcommon-x11-dev - - steps: - - name: Install dependencies - run: >- - sudo apt update && sudo apt install - build-essential - ninja-build - libfreetype-dev - libsdl2-dev - libpng-dev - libc6-dev - librtmidi-dev - libopenal-dev - libvncserver-dev - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - - - name: Build - run: cmake --build build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" - - analyze-macos11: - name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" - - runs-on: macos-11 - - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: true - matrix: - language: [ 'cpp' ] - build: -# - name: Regular -# preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev - preset: experimental - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - slug: -Qt - packages: >- - qt@5 - - steps: - - name: Install dependencies - run: >- - brew install - ninja - freetype - sdl2 - libpng - rtmidi - openal-soft - libvncserver - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D Qt5_ROOT=$(brew --prefix qt@5) - -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) - -D OpenAL_ROOT=$(brew --prefix openal-soft) - - - name: Build - run: cmake --build build - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml new file mode 100644 index 0000000000..d92d117673 --- /dev/null +++ b/.github/workflows/codeql_linux.yml @@ -0,0 +1,111 @@ +name: CodeQL Analysis (Linux) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-linux: + + name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" + + runs-on: ubuntu-22.04 + + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qtbase5-dev + qtbase5-private-dev + qttools5-dev + libevdev-dev + libxkbcommon-x11-dev + + steps: + - name: Install dependencies + run: >- + sudo apt update && sudo apt install + build-essential + ninja-build + libfreetype-dev + libsdl2-dev + libpng-dev + libc6-dev + librtmidi-dev + libopenal-dev + libslirp-dev + libfluidsynth-dev + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + + - name: Build + run: cmake --build build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml new file mode 100644 index 0000000000..cef8c48289 --- /dev/null +++ b/.github/workflows/codeql_macos.yml @@ -0,0 +1,107 @@ +name: CodeQL Analysis (macos) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-macos12: + + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + + runs-on: macos-12 + + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: SDL GUI + qt: off + - name: Qt GUI + qt: on + slug: -Qt + packages: >- + qt@5 + + steps: + - name: Install dependencies + run: >- + brew install + ninja + freetype + sdl2 + libpng + rtmidi + openal-soft + fluidsynth + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ./cmake/flags-gcc-x86_64.cmake + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D Qt5_ROOT=$(brew --prefix qt@5) + -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) + -D OpenAL_ROOT=$(brew --prefix openal-soft) + + - name: Build + run: cmake --build build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml new file mode 100644 index 0000000000..dc18544c70 --- /dev/null +++ b/.github/workflows/codeql_windows_msys2.yml @@ -0,0 +1,140 @@ +name: CodeQL Analysis (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/codeql.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + analyze-msys2: + + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + permissions: + actions: read + contents: read + security-events: write + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + language: [ 'cpp' ] + build: +# - name: Regular +# preset: regular +# - name: Debug +# preset: debug +# slug: -Debug + - name: Dev + preset: experimental + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Win32 GUI + qt: off + static: on + - name: Qt GUI + qt: on + static: off + slug: -Qt + packages: >- + qt5-base:p + qt5-tools:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake + - msystem: MINGW32 + prefix: mingw-w64-i686 + toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: cmake --build build + + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 8070ff263c..cacf1aaa49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,16 +30,12 @@ if(NOT DEFINED OPENAL OR OPENAL) list(APPEND VCPKG_MANIFEST_FEATURES "openal") endif() -if(SLIRP_EXTERNAL) - list(APPEND VCPKG_MANIFEST_FEATURES "slirp") -endif() - if(MUNT_EXTERNAL) list(APPEND VCPKG_MANIFEST_FEATURES "munt") endif() project(86Box - VERSION 4.0 + VERSION 4.1.1 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) @@ -157,9 +153,9 @@ 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(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) @@ -201,7 +197,7 @@ if(NOT EMU_BUILD_NUM) set(EMU_BUILD_NUM 0) endif() if(NOT EMU_COPYRIGHT_YEAR) - set(EMU_COPYRIGHT_YEAR 2022) + set(EMU_COPYRIGHT_YEAR 2024) endif() add_subdirectory(src) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..4f4f32b2e2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contribution guidelines +The 86Box project welcomes contributions from anyone, as long as some basic guidelines are followed. + +## Emulated hardware +In order to accept new emulated hardware, the following criteria must be met: + +* A ROM must be available and be added to [our ROM repository](https://github.com/86Box/roms) +* Documentation must be available or it must be feasible to reverse engineer with a reasonable amount of time and effort +* It must be feasible to implement with a reasonable amount of time and effort +* It has to fall inside the project's scope + +## Questions +If you're unsure about any aspect of contributing, don't hesitate to get in touch via any of our official communities linked in our [readme](README.md#community) or [GitHub Discussions](https://github.com/86Box/86Box/discussions). diff --git a/README.md b/README.md index e251356ed7..370bc940ee 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,16 @@ 86Box ===== + [![Build Status](https://ci.86box.net/job/86Box/badge/icon)](https://ci.86box.net/job/86Box/) +[![License](https://img.shields.io/github/license/86Box/86Box)](COPYING) [![Latest release](https://img.shields.io/github/release/86Box/86Box.svg)](https://github.com/86Box/86Box/releases) [![Downloads](https://img.shields.io/github/downloads/86Box/86Box/total.svg)](https://github.com/86Box/86Box/releases) **86Box** is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus. Features -------- + * Easy to use interface inspired by mainstream hypervisor software -* Low level emulation of 8086-based processors up to the Pentium with focus on accuracy +* Low level emulation of 8086-based processors up to the Mendocino-era Celeron with focus on accuracy * Great range of customizability of virtual machines * Many available systems, such as the very first IBM PC 5150 from 1981, or the more obscure IBM PS/2 line of systems based on the Micro Channel Architecture * Lots of supported peripherals including video adapters, sound cards, network adapters, hard disk controllers, and SCSI adapters @@ -16,18 +19,18 @@ Features Minimum system requirements and recommendations ----------------------------------------------- -* Intel Core 2 or AMD Athlon 64 processor -* Windows version: Windows 7 Service Pack 1, Windows 8.1 or Windows 10 + +* Intel Core 2 or AMD Athlon 64 processor or newer +* Windows version: Windows 7 Service Pack 1 or later * Linux version: Ubuntu 16.04, Debian 9.0 or other distributions from 2016 onwards -* macOS version: macOS High Sierra 10.13 -* 4 GB of RAM +* macOS version: macOS High Sierra 10.13 or newer +* 4 GB of RAM or higher Performance may vary depending on both host and guest configuration. Most emulation logic is executed in a single thread; therefore, systems with better IPC (instructions per clock) generally should be able to emulate higher clock speeds. It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines. + * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) -* [86Box Manager Lite](https://github.com/insanemal/86box_manager_py) by [Insanemal](https://github.com/insanemal) -* [WinBox for 86Box](https://github.com/86Box/WinBox-for-86Box) by Laci bá' (Windows only) * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested) * [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only) @@ -35,26 +38,35 @@ It is also possible to use 86Box on its own with the `--vmpath`/`-P` command lin Getting started --------------- + See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for an overview of the emulator's features and user interface. Community --------- + We operate an IRC channel and a Discord server for discussing 86Box, its development and anything related to retro computing. We look forward to hearing from you! [![Visit our IRC channel](https://kiwiirc.com/buttons/irc.ringoflightning.net/86Box.png)](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#86Box) [![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/QXK9XTv) +Contributions +--------- + +We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed. + Licensing --------- + 86Box is released under the [GNU General Public License, version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) or later. For more information, see the `COPYING` file in the root of the repository. The emulator can also optionally make use of [munt](https://github.com/munt/munt), [FluidSynth](https://www.fluidsynth.org/), [Ghostscript](https://www.ghostscript.com/) and [Discord Game SDK](https://discord.com/developers/docs/game-sdk/sdk-starter-guide), which are distributed under their respective licenses. Donations --------- + We do not charge you for the emulator but donations are still welcome: -https://paypal.me/86Box. +. You can also support the project on Patreon: -https://www.patreon.com/86box. +. diff --git a/cmake/flags-gcc-armv7.cmake b/cmake/flags-gcc-armv7.cmake index 828fb1a210..070e5e52a6 100644 --- a/cmake/flags-gcc-armv7.cmake +++ b/cmake/flags-gcc-armv7.cmake @@ -14,7 +14,7 @@ # Copyright 2021 David Hrdlička. # -string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") -string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/debian/changelog b/debian/changelog index 1bca318dd1..00179d4660 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.0) UNRELEASED; urgency=medium +86box (4.1.1) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Tue, 28 Feb 2023 00:02:16 -0500 + -- Jasmine Iwanek Fri, 23 Feb 2024 07:23:12 +0100 diff --git a/debian/control b/debian/control index 78a92bf8f3..d67f5965ba 100644 --- a/debian/control +++ b/debian/control @@ -1,18 +1,21 @@ Source: 86box Section: otherosfs Priority: optional -Maintainer: Mariusz Kurek +Maintainer: Jasmine Iwanek Build-Depends: cmake (>= 3.21), debhelper-compat (= 13), libevdev-dev, + libfluidsynth-dev, libfreetype-dev, libopenal-dev, libqt5opengl5-dev, librtmidi-dev, libsdl2-dev, libslirp-dev, + libxkbcommon-x11-dev, ninja-build, - qttools5-dev + qttools5-dev, + qtbase5-private-dev Standards-Version: 4.6.0 Homepage: https://86box.net/ #Vcs-Browser: https://salsa.debian.org/debian/86box @@ -26,4 +29,6 @@ Depends: ${shlibs:Depends}, sse2-support [i386] Recommends: libpcap0.8-dev Description: An emulator for classic IBM PC clones -#TODO: insert long description, indented with spaces + 86Box is a low level x86 emulator that runs older operating systems and software + designed for IBM PC systems and compatibles from 1981 through + fairly recent system designs based on the PCI bus. \ No newline at end of file diff --git a/debian/copyright b/debian/copyright index 22817edc5b..58c9077fa0 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,7 +8,8 @@ Copyright: License: GPL-2.0+ Files: debian/* -Copyright: 2022 Mariusz Kurek +Copyright: 2023 Jasmine Iwanek + 2022 Lili Kurek License: GPL-2.0+ License: GPL-2.0+ diff --git a/debian/rules b/debian/rules index f01d81dcde..1ee4be4edf 100644 --- a/debian/rules +++ b/debian/rules @@ -25,7 +25,10 @@ endif dh $@ --buildsystem cmake+ninja override_dh_auto_configure: - dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -DSLIRP_EXTERNAL=on + dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -B . + +override_dh_auto_build: + dh_auto_build --buildsystem cmake+ninja override_dh_auto_test: diff --git a/debian/source/format b/debian/source/format index 163aaf8d82..89ae9db8f8 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) diff --git a/doc/specifications/86box-unit-tester.md b/doc/specifications/86box-unit-tester.md new file mode 100644 index 0000000000..48817b27cd --- /dev/null +++ b/doc/specifications/86box-unit-tester.md @@ -0,0 +1,267 @@ +# 86Box Unit Tester device specification v1.0.0 + +By GreaseMonkey + other 86Box contributors, 2024. +This specification, including any code samples included, has been released into the Public Domain under the Creative Commons CC0 licence version 1.0 or later, as described here: + +The 86Box Unit Tester is a facility for allowing one to unit-test various parts of 86Box's emulation which would otherwise not be exposed to the emulated system. + +The original purpose of this was to make it possible to analyse and verify aspects of the monitor framebuffers in order to detect and prevent regressions in certain pieces of video hardware. + +---------------------------------------------------------------------------- + +## Versioning + +This specification follows the rules of Semantic Versioning 2.0.0 as documented here: + +The format is `major.minor.patch`. + +- Before you mess with this specification, talk to the other contributors first! +- Any changes need to be tracked in the Version History below, mostly in the event that this document escapes into the wild and doesn't have the Git history attached to it. +- If it clarifies something without introducing any behaviour changes (e.g. formatting changes, spelling fixes), increment the patch version. +- If it introduces a backwards-compatible change, increment the minor version and reset the patch version to 0. +- If it introduces a backwards-incompatible change, increment the major version and reset the minor and patch versions to 0. + - If you make a mistake and accidentally introduce a backward-incompatible change, fix the mistake and increment the minor version. + - To clarify, modifications to *this* section are to be classified as a *patch* version update. +- If you understand SemVer 2.0.0, you may also do other things to the version number according to the specification. + +And lastly, the 3 golden rules of protocol specifications: + +1. If it's not documented, it doesn't exist. +2. If it's not documented but somehow exists, it's a bug. +3. If it's a bug, it needs to be fixed. (Yes, I'm talking to you. You who introduced the bug. Go fix it.) + +The checklist: + +- Work out what kind of version number this document needs. +- Update the version number at the top of the file. +- Add an entry to the "Version History" section below describing roughly what was changed. + +---------------------------------------------------------------------------- + +## Version History + +Dates are based on what day it was in UTC at the time of publication. + +New entries are placed at the top. That is, immediately following this paragraph. + +### v1.0.0 (2024-01-08) +Initial release. Authored by GreaseMonkey. + +---------------------------------------------------------------------------- + +## Conventions + +### Integer types + +- `i8` denotes a signed 8-bit value. +- `u8` denotes an unsigned 8-bit value. +- `w8` denotes an 8-bit value which wraps around. +- `x8` denotes an 8-bit value where the signedness is irrelevant. +- `e8` ("either") denotes an 8-bit value where the most significant bit is clear - in effect, this is a 7-bit unsigned value, and can be interepreted identically as a signed 8-bit value. +- `u16L` denotes a little-endian unsigned 16-bit value. +- `u16B` would denote a big-endian unsigned 16-bit value if we had any big-endian values. +- `[N]T` denotes an array of `N` values of type `T`, whatever `N` and `T` are. + +---------------------------------------------------------------------------- + +## Usage + +### Accessing the device and configuring the I/O base address + +Find an area in I/O space where 2 addresses are confirmed (or assumed) to be unused. +There is no need for the 2 addresses to be 2-byte-aligned. + +Send the following sequence of bytes to port 0x80 with INTERRUPTS DISABLED: + + '8', '6', 'B', 'o', 'x', (IOBASE & 0xFF), (IOBASE >> 8) + +Alternatively denoted in hex: + + 38 36 42 6F 78 yy xx + +There are no timing constraints. This is an emulator, after all. + +To confirm that this has happened, read the status port at IOBASE+0x00. +If it's 0xFF, then the device is most likely not present. +Otherwise, one can potentially assume that it exists and has been configured successfully. +(You *did* make sure that the space was unused *before* doing this, right?) + +IOBASE is allowed to overlap the trigger port, but please don't do this! + +### Hiding the device + +Set the I/O base address to 0xFFFF using the above method. + +### Executing commands + +The ports at IOBASE+0x00 and IOBASE+0x01 are all 8 bits wide. + +Writing to IOBASE+0x00 cancels any in-flight commands and sends a new command. + +Reading from IOBASE+0x00 reads the status: + +- bit 0: There is data to be read from this device + - If one reads with this bit clear, the returned data will be 0xFF. +- bit 1: The device is expecting data to be sent to it + - If one writes with this bit clear, the data will be ignored. +- bit 2: There is no command in flight + - If this is set, then bits 0 and 1 will be clear. +- bit 3: The previously-sent command does not exist. +- bits 4 .. 7: Reserved, should be 0. + +Writing to IOBASE+0x01 provides data to the device if said data is needed. + +Reading from IOBASE+0x01 fetches the next byte data to the device if said data is needed. + +### General flow of executing a command: + +This is how most commands will work. + +- Write the command to IOBASE+0x00. +- If data needs to be written or read: + - Read the status from IOBASE+0x00 and confirm that bit 2 is clear. + If it is set, then the command may not exist. + Check bit 3 if that's the case. +- If data needs to be written: + - Write all the data one needs to write. +- If data needs to be read: + - Read the status from IOBASE+0x00 and wait until bit 0 is set. + If it is set, then the command may not exist. + Check bit 3 if that's the case. + - Keep reading bytes until one is satisfied. +- Otherwise: + - Read the status from IOBASE+0x00 and wait until any of the bottom 3 bits are set. + +---------------------------------------------------------------------------- + +## Command reference + +### 0x00: No-op + +This does nothing, takes no input, and gives no output. + +This is an easy way to reset the status to 0x04 (no command in flight, not waiting for reads or writes, and no errors). + +### 0x01: Capture Screen Snapshot + +Captures a snapshot of the current screen state and stores it in the current snapshot buffer. + +The initial state of the screen snapshot buffer has an image area of 0x0, an overscanned area of 0x0, and an image start offset of (0,0). + +Input: + +* u8 monitor + - 0x00 = no monitor - clear the screen snapshot + - 0x01 = primary monitor + - 0x02 = secondary monitor + - Any monitor which is not available is treated as 0x00, and clears the screen snapshot. + +Output: + +* `e16L` image width in pixels +* `e16L` image height in pixels +* `e16L` overscanned width in pixels +* `e16L` overscanned height in pixels +* `e16L` X offset of image start +* `e16L` Y offset of image start + +If there is no screen snapshot, then all values will be 0 as per the initial screen snapshot buffer state. + +### 0x02: Read Screen Snapshot Rectangle + +Returns a rectangular snapshot of the screen snapshot buffer as an array of 32bpp 8:8:8:8 B:G:R:X pixels. + +Input: + +* `e16L` w: rectangle width in pixels +* `e16L` h: rectangle height in pixels +* `i16L` x: X offset relative to image start +* `i16L` y: Y offset relative to image start + +Output: + +* `[h][w][4]u8`: image data + - `[y][x][0]` is the blue component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][1]` is the green component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][2]` is the red component, or 0x00 if the pixel is outside the snapshot area. + - `[y][x][3]` is 0x00, or 0xFF if the pixel is outside the snapshot area. + +### 0x03: Verify Screen Snapshot Rectangle + +As per 0x02 "Read Screen Snapshot Rectangle", except instead of returning the pixel data, it returns a CRC-32 of the data. + +The CRC is as per zlib's `crc32()` function. Specifically, one uses a right-shifting Galois LFSR with a polynomial of 0xEDB88320, bytes XORed against the least significant byte, the initial seed is 0xFFFFFFFF, and all bits of the output are inverted. + +(Rationale: There are better CRCs, but this one is ubiquitous and still really good... and we don't need to protect against deliberate tampering.) + +Input: + +* `e16L` w: rectangle width in pixels +* `e16L` h: rectangle height in pixels +* `i16L` x: X offset relative to image start +* `i16L` y: Y offset relative to image start + +Output: + +* `u32L` crc: CRC-32 of rectangle data + +### 0x04: Exit 86Box + +Exits 86Box, unless this command is disabled. + +- If the command is enabled, then program execution terminates immediately. +- If the command is disabled, it still counts as having executed correctly, but program execution continues. This makes it useful to show a "results" screen for a unit test. + +Input: + +* u8 exit code: + - The actual exit code is clamped to no greater than the maximum valid exit code. + - In practice, this is probably going to be 0x7F. + +---------------------------------------------------------------------------- + +## Implementation notes + +### Port 0x80 sequence detection + +In order to ensure that one can always trigger the activation sequence, there are effectively two finite state machines in action. + +FSM1: +- Wait for 8. +- Wait for 6. +- Wait for B. +- Wait for o. +- Wait for x. + Once received, set FSM2 to "Wait for low byte", + then go back to "Wait for 8". + +If at any point an 8 arrives, jump to the "Wait for 6" step. + +Otherwise, if any other unexpected byte arrives, jump to the "Wait for 8" step. + +FSM2: +- Idle. +- Wait for low byte. Once received, store this in a temporary location. +- Wait for high byte. + Once received, replace IOBASE with this byte in the high byte and the temporary value in the low byte, + then go back to "Idle". + +---------------------------------------------------------------------------- + +## Extending the protocol + +### Adding new commands + +Commands 0x01 through 0x7F accept a single command byte. + +Command bytes 0x80 through 0xFB are reserved for 16-bit command IDs, to be written in a similar way to this: + +- Write the first command byte (0x80 through 0xFF) to the command register. +- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C. +- Otherwise, the status is set to 0x0 +- Write the next command byte (0x00 through 0xFF) to the data register. +- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C. +- Otherwise, the command exists and the status is set according to the command. + +Command bytes 0xFC through 0xFF are reserved for if we somehow need more than 16 bits worth of command ID. + diff --git a/src/86box.c b/src/86box.c index e2541f55d8..8218c208cf 100644 --- a/src/86box.c +++ b/src/86box.c @@ -30,10 +30,10 @@ #include #include #include +#include #ifndef _WIN32 # include -# include #endif #ifdef __APPLE__ # include @@ -65,6 +65,7 @@ #include <86box/machine.h> #include <86box/bugger.h> #include <86box/postcard.h> +#include <86box/unittester.h> #include <86box/isamem.h> #include <86box/isartc.h> #include <86box/lpt.h> @@ -111,7 +112,7 @@ /* Stuff that used to be globally declared in plat.h but is now extern there and declared here instead. */ -int dopause; /* system is paused */ +int dopause = 1; /* system is paused */ atomic_flag doresize; /* screen resize requested */ volatile int is_quit; /* system exit requested */ uint64_t timer_freq; @@ -123,7 +124,6 @@ int tracing_on = 0; /* Commandline options. */ int dump_on_exit = 0; /* (O) dump regs on exit */ -int do_dump_config = 0; /* (O) dump config on load */ int start_in_fullscreen = 0; /* (O) start in fullscreen */ #ifdef _WIN32 int force_debug = 0; /* (O) force debug output */ @@ -141,10 +141,15 @@ char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */ rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ char log_path[1024] = { '\0' }; /* (O) full path of logfile */ char vm_name[1024] = { '\0' }; /* (O) display name of the VM */ +int do_nothing = 0; +int dump_missing = 0; +int clear_cmos = 0; #ifdef USE_INSTRUMENT -uint8_t instru_enabled = 0; -uint64_t instru_run_ms = 0; +uint8_t instru_enabled = 0; +uint64_t instru_run_ms = 0; #endif +int clear_flash = 0; +int auto_paused = 0; /* Configuration values. */ int window_remember; @@ -152,7 +157,8 @@ int vid_resize; /* (C) allow r int invert_display = 0; /* (C) invert the display */ int suppress_overscan = 0; /* (C) suppress overscans */ int scale = 0; /* (C) screen scale factor */ -int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */ +int dpi_scale = 0; /* (C) DPI scaling of the emulated + screen */ int vid_api = 0; /* (C) video renderer */ int vid_cga_contrast = 0; /* (C) video */ int video_fullscreen = 0; /* (C) video */ @@ -164,18 +170,21 @@ int video_filter_method = 1; /* (C) video * int video_vsync = 0; /* (C) video */ int video_framerate = -1; /* (C) video */ char video_shader[512] = { '\0' }; /* (C) video */ -bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of pass-through for serial ports */ +bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of + pass-through for serial ports */ int bugger_enabled = 0; /* (C) enable ISAbugger */ int postcard_enabled = 0; /* (C) enable POST card */ +int unittester_enabled = 0; /* (C) enable unit tester device */ int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */ int isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */ int show_second_monitors = 1; /* (C) show non-primary monitors */ int sound_is_float = 1; /* (C) sound uses FP values */ int voodoo_enabled = 0; /* (C) video option */ -int ibm8514_enabled = 0; /* (C) video option */ -int xga_enabled = 0; /* (C) video option */ -uint32_t mem_size = 0; /* (C) memory size (Installed on system board)*/ +int ibm8514_standalone_enabled = 0; /* (C) video option */ +int xga_standalone_enabled = 0; /* (C) video option */ +uint32_t mem_size = 0; /* (C) memory size (Installed on + system board)*/ uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */ int cpu_use_dynarec = 0; /* (C) cpu uses/needs Dyna */ int cpu = 0; /* (C) cpu type */ @@ -188,8 +197,12 @@ int confirm_save = 1; /* (C) enable int enable_discord = 0; /* (C) enable Discord integration */ int pit_mode = -1; /* (C) force setting PIT mode */ int fm_driver = 0; /* (C) select FM sound driver */ -int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */ -int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */ +int open_dir_usr_path = 0; /* (C) default file open dialog directory + of usr_path */ +int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings + also apply when maximized. */ +int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus + loss */ /* Statistics. */ extern int mmuflush; @@ -208,19 +221,26 @@ char exe_path[2048]; /* path (dir) of executable */ char usr_path[1024]; /* path (dir) of user data */ char cfg_path[1024]; /* full path of config file */ FILE *stdlog = NULL; /* file to log output to */ -// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ -// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +#if 0 +int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ +int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +#endif int config_changed; /* config has changed */ int title_update; int framecountx = 0; int hard_reset_pending = 0; -// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ -// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ -// int efscrnsz_y = SCREEN_RES_Y; +#if 0 +int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ +int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ +int efscrnsz_y = SCREEN_RES_Y; +#endif static wchar_t mouse_msg[3][200]; +static volatile atomic_int do_pause_ack = 0; +static volatile atomic_int pause_ack = 0; + #ifndef RELEASE_BUILD static char buff[1024]; static int seen = 0; @@ -394,6 +414,31 @@ pc_log(const char *fmt, ...) # define pc_log(fmt, ...) #endif +static void +delete_nvr_file(uint8_t flash) +{ + char *fn = NULL; + int c; + + /* Set up the NVR file's name. */ + c = strlen(machine_get_internal_name()) + 5; + fn = (char *) malloc(c + 1); + + if (fn == NULL) + fatal("Error allocating memory for the removal of the %s file\n", + flash ? "BIOS flash" : "CMOS"); + + if (flash) + sprintf(fn, "%s.bin", machine_get_internal_name()); + else + sprintf(fn, "%s.nvr", machine_get_internal_name()); + + remove(nvr_path(fn)); + + free(fn); + fn = NULL; +} + /* * Perform initial startup of the PC. * @@ -404,19 +449,19 @@ pc_log(const char *fmt, ...) int pc_init(int argc, char *argv[]) { - char *ppath = NULL; - char *rpath = NULL; - char *cfg = NULL; - char *p; - char temp[2048]; - char *fn[FDD_NUM] = { NULL }; - char drive = 0; - char *temp2 = NULL; - struct tm *info; - time_t now; - int c; - int lvmp = 0; - int i; + char *ppath = NULL; + char *rpath = NULL; + char *cfg = NULL; + char *p; + char temp[2048]; + char *fn[FDD_NUM] = { NULL }; + char drive = 0; + char *temp2 = NULL; + char *what; + const struct tm *info; + time_t now; + int c; + int lvmp = 0; #ifdef ENABLE_NG int ng = 0; #endif @@ -467,7 +512,7 @@ pc_init(int argc, char *argv[]) if (!strcasecmp(argv[c], "--help") || !strcasecmp(argv[c], "-?")) { usage: - for (i = 0; i < FDD_NUM; i++) { + for (uint8_t i = 0; i < FDD_NUM; i++) { if (fn[i] != NULL) { free(fn[i]); fn[i] = NULL; @@ -476,34 +521,40 @@ pc_init(int argc, char *argv[]) printf("\nUsage: 86box [options] [cfg-file]\n\n"); printf("Valid options are:\n\n"); - printf("-? or --help - show this information\n"); - printf("-C or --config path - set 'path' to be config file\n"); + printf("-? or --help - show this information\n"); + printf("-C or --config path - set 'path' to be config file\n"); #ifdef _WIN32 - printf("-D or --debug - force debug output logging\n"); + printf("-D or --debug - force debug output logging\n"); #endif #if 0 - printf("-E or --nographic - forces the old behavior\n"); + printf("-E or --nographic - forces the old behavior\n"); #endif - printf("-F or --fullscreen - start in fullscreen mode\n"); - printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n"); + printf("-F or --fullscreen - start in fullscreen mode\n"); + printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n"); #ifdef _WIN32 - printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n"); + printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n"); #endif - printf("-I or --image d:path - load 'path' as floppy image on drive d\n"); - printf("-L or --logfile path - set 'path' to be the logfile\n"); - printf("-N or --noconfirm - do not ask for confirmation on quit\n"); - printf("-O or --dumpcfg - dump config file after loading\n"); - printf("-P or --vmpath path - set 'path' to be root for vm\n"); - printf("-R or --rompath path - set 'path' to be ROM path\n"); - printf("-S or --settings - show only the settings dialog\n"); - printf("-V or --vmname name - overrides the name of the running VM\n"); - printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); + printf("-I or --image d:path - load 'path' as floppy image on drive d\n"); +#ifdef USE_INSTRUMENT + printf("-J or --instrument name - set 'name' to be the profiling instrument\n"); +#endif + printf("-K or --keycodes codes - set 'codes' to be the uncapture combination\n"); + printf("-L or --logfile path - set 'path' to be the logfile\n"); + printf("-M or --missing - dump missing machines and video cards\n"); + printf("-N or --noconfirm - do not ask for confirmation on quit\n"); + printf("-P or --vmpath path - set 'path' to be root for vm\n"); + printf("-R or --rompath path - set 'path' to be ROM path\n"); +#ifndef USE_SDL_UI + printf("-S or --settings - show only the settings dialog\n"); +#endif + printf("-V or --vmname name - overrides the name of the running VM\n"); + printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); + printf("-Y or --donothing - do not show any UI or run the emulation\n"); + printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); printf("\nA config file can be specified. If none is, the default file will be used.\n"); return 0; } else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) { lvmp = 1; - } else if (!strcasecmp(argv[c], "--dumpcfg") || !strcasecmp(argv[c], "-O")) { - do_dump_config = 1; #ifdef _WIN32 } else if (!strcasecmp(argv[c], "--debug") || !strcasecmp(argv[c], "-D")) { force_debug = 1; @@ -562,10 +613,38 @@ pc_init(int argc, char *argv[]) goto usage; strcpy(vm_name, argv[++c]); +#ifndef USE_SDL_UI } else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) { settings_only = 1; +#endif } else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) { confirm_exit_cmdl = 0; + } else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) { + dump_missing = 1; + } else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) { + do_nothing = 1; + } else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) { + if ((c + 1) == argc) + goto usage; + + sscanf(argv[++c], "%03hX,%03hX,%03hX,%03hX,%03hX,%03hX", + &key_prefix_1_1, &key_prefix_1_2, &key_prefix_2_1, &key_prefix_2_2, + &key_uncapture_1, &key_uncapture_2); + } else if (!strcasecmp(argv[c], "--clearboth") || !strcasecmp(argv[c], "-X")) { + if ((c + 1) == argc) + goto usage; + + what = argv[++c]; + + if (!strcasecmp(what, "cmos")) + clear_cmos = 1; + else if (!strcasecmp(what, "flash")) + clear_flash = 1; + else if (!strcasecmp(what, "both")) { + clear_cmos = 1; + clear_flash = 1; + } else + goto usage; #ifdef _WIN32 } else if (!strcasecmp(argv[c], "--hwnd") || !strcasecmp(argv[c], "-H")) { @@ -575,9 +654,8 @@ pc_init(int argc, char *argv[]) uid = (uint32_t *) &unique_id; shwnd = (uint32_t *) &source_hwnd; sscanf(argv[++c], "%08X%08X,%08X%08X", uid + 1, uid, shwnd + 1, shwnd); - } else if (!strcasecmp(argv[c], "--lang") || !strcasecmp(argv[c], "-G")) { - #endif + } else if (!strcasecmp(argv[c], "--lang") || !strcasecmp(argv[c], "-G")) { // This function is currently unimplemented for *nix but has placeholders. lang_init = plat_language_code(argv[++c]); @@ -587,13 +665,13 @@ pc_init(int argc, char *argv[]) // The return value of 0 only means that the code is invalid, // not related to that translation is exists or not for the // selected language. - } else if (!strcasecmp(argv[c], "--test")) { + } else if (!strcasecmp(argv[c], "--test") || !strcasecmp(argv[c], "-T")) { /* some (undocumented) test function here.. */ /* .. and then exit. */ return 0; #ifdef USE_INSTRUMENT - } else if (!strcasecmp(argv[c], "--instrument")) { + } else if (!strcasecmp(argv[c], "--instrument") || !strcasecmp(argv[c], "-J")) { if ((c + 1) == argc) goto usage; instru_enabled = 1; @@ -776,7 +854,19 @@ pc_init(int argc, char *argv[]) /* Load the configuration file. */ config_load(); - for (i = 0; i < FDD_NUM; i++) { + /* Clear the CMOS and/or BIOS flash file, if we were started with + the relevant parameter(s). */ + if (clear_cmos) { + delete_nvr_file(0); + clear_cmos = 0; + } + + if (clear_flash) { + delete_nvr_file(1); + clear_flash = 0; + } + + for (uint8_t i = 0; i < FDD_NUM; i++) { if (fn[i] != NULL) { if (strlen(fn[i]) <= 511) strncpy(floppyfns[i], fn[i], 511); @@ -801,7 +891,7 @@ pc_speed_changed(void) if (cpu_s->cpu_type >= CPU_286) pit_set_clock(cpu_s->rspeed); else - pit_set_clock(14318184.0); + pit_set_clock((uint32_t) 14318184.0); } void @@ -823,27 +913,29 @@ pc_init_modules(void) wchar_t temp[512]; char tempc[512]; -#ifdef PRINT_MISSING_MACHINES_AND_VIDEO_CARDS - c = m = 0; - while (machine_get_internal_name_ex(c) != NULL) { - m = machine_available(c); - if (!m) - pclog("Missing machine: %s\n", machine_getname_ex(c)); - c++; - } + if (dump_missing) { + dump_missing = 0; - c = m = 0; - while (video_get_internal_name(c) != NULL) { - memset(tempc, 0, sizeof(tempc)); - device_get_name(video_card_getdevice(c), 0, tempc); - if ((c > 1) && !(tempc[0])) - break; - m = video_card_available(c); - if (!m) - pclog("Missing video card: %s\n", tempc); - c++; + c = m = 0; + while (machine_get_internal_name_ex(c) != NULL) { + m = machine_available(c); + if (!m) + pclog("Missing machine: %s\n", machine_getname_ex(c)); + c++; + } + + c = m = 0; + while (video_get_internal_name(c) != NULL) { + memset(tempc, 0, sizeof(tempc)); + device_get_name(video_card_getdevice(c), 0, tempc); + if ((c > 1) && !(tempc[0])) + break; + m = video_card_available(c); + if (!m) + pclog("Missing video card: %s\n", tempc); + c++; + } } -#endif pc_log("Scanning for ROM images:\n"); c = m = 0; @@ -915,11 +1007,15 @@ pc_init_modules(void) #ifdef USE_DYNAREC # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(0); + } # endif codegen_init(); # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(1); + } # endif #endif @@ -938,6 +1034,11 @@ pc_init_modules(void) machine_status_init(); + if (do_nothing) { + do_nothing = 0; + exit(-1); + } + return 1; } @@ -947,6 +1048,7 @@ pc_send_ca(uint16_t sc) keyboard_input(1, 0x1D); /* Ctrl key pressed */ keyboard_input(1, 0x38); /* Alt key pressed */ keyboard_input(1, sc); + usleep(50000); keyboard_input(0, sc); keyboard_input(0, 0x38); /* Alt key released */ keyboard_input(0, 0x1D); /* Ctrl key released */ @@ -1045,19 +1147,9 @@ pc_reset_hard_init(void) /* Initialize the actual machine and its basic modules. */ machine_init(); - /* Reset and reconfigure the serial ports. */ - serial_standalone_init(); - serial_passthrough_init(); - - /* Reset and reconfigure the Sound Card layer. */ - sound_card_reset(); - - /* Reset any ISA RTC cards. */ - isartc_reset(); - - fdc_card_init(); - - fdd_reset(); + /* Reset some basic devices. */ + speaker_init(); + shadowbios = 0; /* * Once the machine has been initialized, all that remains @@ -1068,10 +1160,19 @@ pc_reset_hard_init(void) * that will be a call to device_reset_all() later ! */ - /* Reset some basic devices. */ - speaker_init(); + /* Reset and reconfigure the Sound Card layer. */ + sound_card_reset(); + + /* Initialize parallel devices. */ + /* note: PLIP LPT side has to be initialized before the network side */ lpt_devices_init(); - shadowbios = 0; + + /* Reset and reconfigure the Network Card layer. */ + network_reset(); + + /* Reset and reconfigure the serial ports. */ + serial_standalone_init(); + serial_passthrough_init(); /* * Reset the mouse, this will attach it to any port needed. @@ -1081,25 +1182,33 @@ pc_reset_hard_init(void) /* Reset the Hard Disk Controller module. */ hdc_reset(); + fdc_card_init(); + + fdd_reset(); + /* Reset the CD-ROM Controller module. */ cdrom_interface_reset(); /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); - cdrom_hard_reset(); + scsi_disk_hard_reset(); - zip_hard_reset(); + cdrom_hard_reset(); mo_hard_reset(); - scsi_disk_hard_reset(); + zip_hard_reset(); - /* Reset and reconfigure the Network Card layer. */ - network_reset(); + /* Reset any ISA RTC cards. */ + isartc_reset(); + + /* Initialize the Voodoo cards here inorder to minimize + the chances of the SCSI controller ending up on the bridge. */ + video_voodoo_init(); if (joystick_type) - gameport_update_joystick_type(); + gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */ ui_sb_update_panes(); @@ -1115,6 +1224,17 @@ pc_reset_hard_init(void) device_add(&bugger_device); if (postcard_enabled) device_add(&postcard_device); + if (unittester_enabled) + device_add(&unittester_device); + + if (IS_ARCH(machine, MACHINE_BUS_PCI)) { + pci_register_cards(); + device_reset_all(DEVICE_PCI); + } + + /* Mark IDE shadow drives (slaves with a present master) as such in case + the IDE controllers present are not some form of PCI. */ + ide_drives_set_shadow(); /* Reset the CPU module. */ resetx86(); @@ -1141,9 +1261,9 @@ pc_reset_hard_init(void) void update_mouse_msg(void) { - wchar_t wcpufamily[2048]; - wchar_t wcpu[2048]; - wchar_t wmachine[2048]; + wchar_t wcpufamily[2048]; + wchar_t wcpu[2048]; + wchar_t wmachine[2048]; wchar_t *wcp; mbstowcs(wmachine, machine_getname(), strlen(machine_getname()) + 1); @@ -1182,7 +1302,7 @@ pc_reset_hard(void) } void -pc_close(thread_t *ptr) +pc_close(UNUSED(thread_t *ptr)) { /* Wait a while so things can shut down. */ plat_delay_ms(200); @@ -1193,10 +1313,6 @@ pc_close(thread_t *ptr) /* Terminate the UI thread. */ is_quit = 1; -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_close(); -#endif - nvr_save(); config_save(); @@ -1253,6 +1369,15 @@ _ui_window_title(void *s) } #endif +void +ack_pause(void) +{ + if (atomic_load(&do_pause_ack)) { + atomic_store(&do_pause_ack, 0); + atomic_store(&pause_ack, 1); + } +} + void pc_run(void) { @@ -1268,11 +1393,16 @@ pc_run(void) /* Run a block of code. */ startblit(); - cpu_exec(cpu_s->rspeed / 100); + cpu_exec((int32_t) cpu_s->rspeed / 100); + ack_pause(); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ - // if (gdbstub_step == GDBSTUB_EXEC) + if (gdbstub_step == GDBSTUB_EXEC) { +#endif + if (!mouse_timed) + mouse_process(); +#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ + } #endif - // mouse_process(); joystick_process(); endblit(); @@ -1284,7 +1414,7 @@ pc_run(void) } if (title_update) { - mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_mode >= 1)) ? 2 : !!mouse_capture; + mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ @@ -1413,6 +1543,9 @@ set_screen_size_monitor(int x, int y, int monitor_index) monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3); monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3); break; + + default: + break; } plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index); @@ -1433,14 +1566,14 @@ reset_screen_size_monitor(int monitor_index) void reset_screen_size(void) { - for (int i = 0; i < MONITORS_NUM; i++) + for (uint8_t i = 0; i < MONITORS_NUM; i++) set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_efscrnsz_y); } void set_screen_size_natural(void) { - for (int i = 0; i < MONITORS_NUM; i++) + for (uint8_t i = 0; i < MONITORS_NUM; i++) set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_unscaled_size_y); } @@ -1455,3 +1588,18 @@ get_actual_size_y(void) { return (efscrnsz_y); } + +void +do_pause(int p) +{ + int old_p = dopause; + + if ((p == 1) && !old_p) + do_pause_ack = p; + dopause = !!p; + if ((p == 1) && !old_p) { + while (!atomic_load(&pause_ack)) + ; + } + atomic_store(&pause_ack, 0); +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3809ead738..ec32d7548a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,7 +20,8 @@ endif() add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c - mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c ini.c) + mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c + machine_status.c ini.c) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1) @@ -228,5 +229,6 @@ if (QT) elseif(WIN32) add_subdirectory(win) else() + add_compile_definitions(USE_SDL_UI) add_subdirectory(unix) endif() diff --git a/src/acpi.c b/src/acpi.c index 539da644b8..93cb715423 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -39,6 +39,10 @@ #include <86box/machine.h> #include <86box/i2c.h> #include <86box/video.h> +#include <86box/smbus.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/sis_55xx.h> int acpi_rtc_status = 0; atomic_int acpi_pwrbut_pressed = 0; @@ -46,6 +50,10 @@ int acpi_enabled = 0; static double cpu_to_acpi; +static int acpi_power_on = 0; +static uint64_t acpi_last_clock = 0ULL; +static int acpi_count = 0; + #ifdef ENABLE_ACPI_LOG int acpi_do_log = ENABLE_ACPI_LOG; @@ -80,65 +88,152 @@ acpi_timer_get(acpi_t *dev) return clock & 0xffffff; } +static uint8_t +acpi_gp_timer_get(acpi_t *dev) +{ + uint64_t clock = acpi_clock_get(); + clock -= acpi_last_clock; + if (clock >= acpi_count) + clock = 0x00; + else + clock &= 0xff; + return clock; +} + static double acpi_get_overflow_period(acpi_t *dev) { uint64_t timer = acpi_clock_get(); uint64_t overflow_time; - if (dev->regs.timer32) { + if (dev->regs.timer32) overflow_time = (timer + 0x80000000LL) & ~0x7fffffffLL; - } else { + else overflow_time = (timer + 0x800000LL) & ~0x7fffffLL; - } uint64_t time_to_overflow = overflow_time - timer; return ((double) time_to_overflow / (double) ACPI_TIMER_FREQ) * 1000000.0; } +static void +acpi_timer_update(acpi_t *dev, bool enable) +{ + if (enable) + timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + else + timer_stop(&dev->timer); +} + static void acpi_timer_overflow(void *priv) { acpi_t *dev = (acpi_t *) priv; dev->regs.pmsts |= TMROF_STS; acpi_update_irq(dev); + acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); } static void -acpi_timer_update(acpi_t *dev, bool enable) +acpi_gp_timer_update(acpi_t *dev, bool enable, int count) { if (enable) { - timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); - } else { + acpi_last_clock = acpi_clock_get(); + acpi_count = count; + timer_on_auto(&dev->gp_timer, (1000000.0 / (double) ACPI_TIMER_FREQ) * ((double) count)); + } else timer_stop(&dev->timer); +} + +void +acpi_sis5595_smi_raise(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->regs.leg_en & 0x20) { + dev->regs.leg_sts |= 0x20; + smi_raise(); + } +} + +static void +acpi_gp_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor == VEN_SIS_5595_1997) { + dev->regs.gpe_sts |= 0x20000000; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + acpi_sis5595_smi_raise(dev); + } else if (dev->vendor == VEN_SIS_5595) { + dev->regs.gpe_sts |= 0x00000400; + dev->regs.leg_sts |= 0x20; + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_14 |= 0x2000; + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + smi_raise(); + } +} + +static void +acpi_per_timer(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + if (dev->vendor >= VEN_SIS_5595_1997) { + dev->regs.leg_sts |= 0x04; + acpi_sis5595_smi_raise(dev); + } else { + dev->regs.reg_25 |= 0x04; + smi_raise(); } + timer_on_auto(&dev->per_timer, 16000000.0); } void acpi_update_irq(acpi_t *dev) { int sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); - if (dev->vendor == VEN_SMC) - sci_level |= (dev->regs.pmsts & BM_STS); + sis_55xx_common_t *sis = (sis_55xx_common_t *) dev->priv; - if (sci_level) { - if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin); - else if (dev->irq_mode == 2) - pci_set_mirq(5, dev->mirq_is_level); - else - pci_set_mirq(0xf0 | dev->irq_line, 1); - } else { - if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin); - else if (dev->irq_mode == 2) - pci_clear_mirq(5, dev->mirq_is_level); - else - pci_clear_mirq(0xf0 | dev->irq_line, 1); + switch (dev->vendor) { + case VEN_SMC: + sci_level |= (dev->regs.pmsts & BM_STS); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + if ((sis != NULL) && (sis->pmu_regs != NULL)) { + sci_level |= (sis->pmu_regs[0x80] | sis->pmu_regs[0x81] | + sis->pmu_regs[0x82] | sis->pmu_regs[0x83]); + } + break; } - acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); + if ((dev->regs.pmcntrl & 0x01) && sci_level) switch (dev->irq_mode) { + default: + picintlevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } else switch (dev->irq_mode) { + default: + picintclevel(1 << dev->irq_line, &dev->irq_state); + break; + case 1: + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case 2: + pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); + break; + case -1: + break; + } } void @@ -169,9 +264,9 @@ acpi_raise_smi(void *priv, int do_smi) } static uint32_t -acpi_reg_read_common_regs(int size, uint16_t addr, void *p) +acpi_reg_read_common_regs(UNUSED(int size), uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; uint32_t ret = 0x00000000; int shift16; int shift32; @@ -211,6 +306,9 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p) update_tsc(); #endif break; + + default: + break; } #ifdef ENABLE_ACPI_LOG @@ -221,12 +319,12 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_ali(int size, uint16_t addr, void *p) +acpi_reg_read_ali(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint32_t ret = 0x00000000; - int shift16; - int shift32; + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; addr &= 0x3f; shift16 = (addr & 1) << 3; @@ -277,7 +375,7 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p) ret = dev->regs.pmcntrl; break; default: - ret = acpi_reg_read_common_regs(size, addr, p); + ret = acpi_reg_read_common_regs(size, addr, priv); break; } @@ -289,12 +387,12 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_intel(int size, uint16_t addr, void *p) +acpi_reg_read_intel(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint32_t ret = 0x00000000; - int shift16; - int shift32; + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; addr &= 0x3f; shift16 = (addr & 1) << 3; @@ -374,7 +472,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) ret = dev->regs.gporeg[addr & 3]; break; default: - ret = acpi_reg_read_common_regs(size, addr, p); + ret = acpi_reg_read_common_regs(size, addr, priv); break; } @@ -386,12 +484,12 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_via_common(int size, uint16_t addr, void *p) +acpi_reg_read_via_common(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint32_t ret = 0x00000000; - int shift16; - int shift32; + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; addr &= 0xff; shift16 = (addr & 1) << 3; @@ -470,7 +568,7 @@ acpi_reg_read_via_common(int size, uint16_t addr, void *p) ret = (dev->regs.gptren >> shift32) & 0xff; break; default: - ret = acpi_reg_read_common_regs(size, addr, p); + ret = acpi_reg_read_common_regs(size, addr, priv); break; } @@ -482,9 +580,9 @@ acpi_reg_read_via_common(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_via(int size, uint16_t addr, void *p) +acpi_reg_read_via(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; uint32_t ret = 0x00000000; int shift16; @@ -527,7 +625,7 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) ret = (dev->regs.gpi_val >> shift16) & 0xff; break; default: - ret = acpi_reg_read_via_common(size, addr, p); + ret = acpi_reg_read_via_common(size, addr, priv); break; } @@ -539,12 +637,12 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_via_596b(int size, uint16_t addr, void *p) +acpi_reg_read_via_596b(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint32_t ret = 0x00000000; - int shift16; - int shift32; + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; addr &= 0x7f; shift16 = (addr & 1) << 3; @@ -577,7 +675,7 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) ret = (dev->regs.gpo_val >> shift32) & 0xff; break; default: - ret = acpi_reg_read_via_common(size, addr, p); + ret = acpi_reg_read_via_common(size, addr, priv); break; } @@ -589,13 +687,13 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) } static uint32_t -acpi_reg_read_smc(int size, uint16_t addr, void *p) +acpi_reg_read_smc(int size, uint16_t addr, void *priv) { uint32_t ret = 0x00000000; addr &= 0x0f; - ret = acpi_reg_read_common_regs(size, addr, p); + ret = acpi_reg_read_common_regs(size, addr, priv); #ifdef ENABLE_ACPI_LOG if (size != 1) @@ -605,11 +703,11 @@ acpi_reg_read_smc(int size, uint16_t addr, void *p) } static uint32_t -acpi_aux_reg_read_smc(int size, uint16_t addr, void *p) +acpi_aux_reg_read_smc(UNUSED(int size), uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint32_t ret = 0x00000000; - int shift16; + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; addr &= 0x07; shift16 = (addr & 1) << 3; @@ -638,18 +736,246 @@ acpi_aux_reg_read_smc(int size, uint16_t addr, void *p) /* Miscellaneous Control Register */ ret = dev->regs.glbctl & 0xff; break; + + default: + break; } acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); return ret; } +static uint32_t +acpi_reg_read_sis_5582(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x14: + case 0x15: + ret = (dev->regs.reg_14 >> shift16) & 0xff; + break; + case 0x16: + case 0x17: + ret = (dev->regs.reg_16 >> shift16) & 0xff; + break; + case 0x18: + case 0x19: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1a: + case 0x1b: + ret = (dev->regs.reg_18 >> shift16) & 0xff; + break; + case 0x1c: + case 0x1d: + ret = (dev->regs.reg_1c >> shift16) & 0xff; + break; + case 0x20: + ret = dev->regs.smi_cmd; + break; + case 0x24: + ret = dev->regs.reg_24; + break; + case 0x25: + ret = dev->regs.reg_25; + break; + case 0x26: + ret = dev->regs.reg_26; + break; + case 0x28: + ret = dev->regs.smi_en_val; + break; + case 0x29: + ret = dev->regs.smi_dis_val; + break; + case 0x2a: + ret = dev->regs.mail_box; + break; + case 0x2b: + ret = dev->regs.reg_2b; + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + +static uint32_t +acpi_reg_read_sis_5595(int size, uint16_t addr, void *priv) +{ + const acpi_t *dev = (acpi_t *) priv; + uint32_t ret = 0x00000000; + int shift16; + int shift32; + + addr &= 0x3f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + ret = (dev->regs.reg_0c >> shift32) & 0xff; + break; + case 0x10: + ret = dev->regs.enter_c2_ps; + break; + case 0x11: + ret = dev->regs.enter_c3_ps; + break; + case 0x12: + ret = dev->regs.reg_12; + break; + case 0x13: + ret = dev->regs.reg_13; + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + ret = (dev->regs.gpe_sts >> shift32) & 0xff; + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + ret = (dev->regs.gpe_en >> shift32) & 0xff; + break; + case 0x1c: + case 0x1d: + case 0x1e: + ret = (dev->regs.gpe_pin >> shift32) & 0xff; + break; + case 0x1f: + ret = acpi_gp_timer_get((acpi_t *) dev) & 0xff; +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + ret = (dev->regs.gpe_io >> shift32) & 0xff; + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + ret = (dev->regs.gpe_pol >> shift32) & 0xff; + break; + case 0x28: + case 0x29: + ret = (dev->regs.gpe_mul >> shift16) & 0xff; + break; + case 0x2a: + case 0x2b: + ret = (dev->regs.gpe_ctl >> shift16) & 0xff; + break; + case 0x2c: + case 0x2d: + ret = (dev->regs.gpe_smi >> shift16) & 0xff; + break; + case 0x2e: + case 0x2f: + ret = (dev->regs.gpe_rl >> shift16) & 0xff; + break; + case 0x30: + ret = dev->regs.leg_sts; + break; + case 0x31: + ret = dev->regs.leg_en; + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_cmd; + else + ret = 0x00; + break; + case 0x33: + ret = dev->regs.tst_ctl; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_en_val; + else + ret = dev->regs.reg_34; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + ret = dev->regs.smi_dis_val; + else + ret = dev->regs.smi_cmd; + break; + case 0x36: + ret = dev->regs.mail_box; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_index(dev->smbus); + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) + ret = smbus_sis5595_read_data(dev->smbus); + break; + default: + ret = acpi_reg_read_common_regs(size, addr, priv); + break; + } + +#ifdef ENABLE_ACPI_LOG + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); +#endif + return ret; +} + static void -acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int sus_typ; + uint8_t old; addr &= 0x3f; #ifdef ENABLE_ACPI_LOG @@ -676,6 +1002,7 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ + old = dev->regs.pmcntrl & 0xff; if ((addr == 0x05) && (val & 0x20)) { sus_typ = dev->suspend_types[(val >> 2) & 7]; acpi_log("ACPI suspend type %d flags %02X\n", (val >> 2) & 7, sus_typ); @@ -713,19 +1040,25 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) /* Since the UI doesn't have a power button at the moment, pause emulation, then trigger a resume event so that the system resumes after unpausing. */ - plat_pause(1); + plat_pause(2); /* 2 means do not wait for pause as + we're already in the CPU thread. */ timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); } } dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; + if ((addr == 0x04) && ((old ^ val) & 0x01)) + acpi_update_irq(dev); + break; + + default: break; } } static void -acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int shift32; @@ -778,11 +1111,11 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001; break; case 0x30: - /* PM2_CNTRL - Power Management 2 Control Register( */ + /* PM2_CNTRL - Power Management 2 Control Register */ dev->regs.pmcntrl = val & 1; break; default: - acpi_reg_write_common_regs(size, addr, val, p); + acpi_reg_write_common_regs(size, addr, val, priv); /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) dev->regs.gpcntrl &= ~0x0002; @@ -795,9 +1128,9 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) } static void -acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int shift32; @@ -878,7 +1211,7 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gporeg[addr & 3] = val; break; default: - acpi_reg_write_common_regs(size, addr, val, p); + acpi_reg_write_common_regs(size, addr, val, priv); /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) dev->regs.glbctl &= ~0x0002; @@ -892,9 +1225,9 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) } static void -acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int shift32; @@ -965,7 +1298,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9; break; default: - acpi_reg_write_common_regs(size, addr, val, p); + acpi_reg_write_common_regs(size, addr, val, priv); /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) dev->regs.glbctl &= ~0x0002; @@ -986,9 +1319,9 @@ acpi_i2c_set(acpi_t *dev) } static void -acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int shift32; @@ -1044,15 +1377,15 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift16)) | (val << shift16)) & 0xffff; break; default: - acpi_reg_write_via_common(size, addr, val, p); + acpi_reg_write_via_common(size, addr, val, priv); break; } } static void -acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; int shift32; @@ -1102,20 +1435,20 @@ acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff; break; default: - acpi_reg_write_via_common(size, addr, val, p); + acpi_reg_write_via_common(size, addr, val, priv); break; } } static void -acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; addr &= 0x0f; acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); - acpi_reg_write_common_regs(size, addr, val, p); + acpi_reg_write_common_regs(size, addr, val, priv); /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) dev->regs.glbctl &= ~0x0001; @@ -1127,9 +1460,9 @@ acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p) } static void -acpi_aux_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p) +acpi_aux_reg_write_smc(UNUSED(int size), uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; int shift16; addr &= 0x07; @@ -1171,76 +1504,476 @@ acpi_aux_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p) acpi_update_irq(dev); } break; + + default: + break; + } +} + +void +acpi_sis5582_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + dev->regs.reg_25 |= 0x02; + if (dev->regs.reg_26 & 0x02) + smi_raise(); +} + +static void +acpi_reg_write_sis_5582(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x007e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.reg_16 & 0x2000), val); + break; + case 0x14: + case 0x15: + dev->regs.reg_14 &= ~((val << shift32) & 0xff9f); + break; + case 0x16: + case 0x17: + dev->regs.reg_16 = ((dev->regs.reg_16 & ~(0xff << shift16)) | (val << shift16)) & 0xff1f; + break; + case 0x18: + case 0x19: + dev->regs.reg_18 = ((dev->regs.reg_18 & ~(0xff << shift16)) | (val << shift16)) & 0x07ff; + break; + case 0x1a: + case 0x1b: + dev->regs.reg_1a = ((dev->regs.reg_1a & ~(0xff << shift16)) | (val << shift16)) & 0x0387; + break; + case 0x1c: + case 0x1d: + dev->regs.reg_1c = ((dev->regs.reg_1c & ~(0xff << shift16)) | (val << shift16)) & 0x3f7f; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_1c & 0x0400) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x20: + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.reg_25 |= 0x08; + if (dev->regs.reg_26 & 0x08) + smi_raise(); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.reg_25 |= 0x10; + if (dev->regs.reg_26 & 0x10) + smi_raise(); + } + break; + case 0x24: + dev->regs.reg_24 = val & 0x43; + break; + case 0x25: + dev->regs.reg_25 &= ~(val & 0x1f); + break; + case 0x26: + old = dev->regs.reg_26; + dev->regs.reg_26 = val & 0x3f; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x28: + dev->regs.smi_en_val = val; + break; + case 0x29: + dev->regs.smi_dis_val = val; + break; + case 0x2a: + dev->regs.mail_box = val; + break; + case 0x2b: + dev->regs.reg_2b = val & 0x01; + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_1c &= ~0x0400; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.reg_25 |= 0x01; + if (dev->regs.reg_26 & 0x01) + acpi_raise_smi(dev, 1); + } + break; + } +} + +void +acpi_sis5595_pmu_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_sis5595_smi_raise(dev); + else if (dev->regs.gpe_en & 0x00001000) { + dev->regs.gpe_sts |= 0x00001000; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_smbus_event(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.gpe_en & 0x00000800) { + dev->regs.gpe_sts |= 0x00000800; + acpi_sis5595_smi_raise(dev); + } +} + +void +acpi_sis5595_software_smi(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + if (dev->regs.leg_en & 0x01) { + dev->regs.leg_sts |= 0x01; + acpi_sis5595_smi_raise(dev); + } +} + +static void +acpi_reg_write_sis_5595(int size, uint16_t addr, uint8_t val, void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + int shift16; + int shift32; + uint8_t old; + uint8_t do_smi = 0; + + addr &= 0x3f; +#ifdef ENABLE_ACPI_LOG + if (size != 1) + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); +#endif + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->regs.reg_0c &= ~((val << shift32) & 0x001e); + break; + case 0x10: + dev->regs.enter_c2_ps = val; + break; + case 0x11: + dev->regs.enter_c3_ps = val; + break; + case 0x12: + dev->regs.reg_12 = val & 0x01; + break; + case 0x13: + dev->regs.reg_13 = val; + /* Setting BIOS_RLS also sets GBL_STS and generates SMI. */ + if (dev->regs.reg_13 & 0x02) { + dev->regs.pmsts |= 0x20; + if (dev->regs.pmen & 0x20) + acpi_update_irq(dev); + } + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_sts &= ~((val << shift32) & 0xff03ffbf); + else + dev->regs.gpe_sts &= ~((val << shift32) & 0xff83ffff); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | (val << shift32)); + else + dev->regs.gpe_en = ((dev->regs.gpe_en & ~(0xff << shift32)) | + (val << shift32)) & 0xff83ffff; + break; + case 0x1c: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0xff << shift32)) | ((val & 0xff) << shift32)); + break; + case 0x1d: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x1e: + dev->regs.gpe_pin = ((dev->regs.gpe_pin & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x1f: + dev->regs.gp_tmr = val; + acpi_gp_timer_update(dev, (val != 0x00) && (dev->regs.gpe_en & 0x00000400), val); + break; + case 0x20: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x9f << shift32)) | ((val & 0x9f) << shift32)); + break; + case 0x21: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x22: + dev->regs.gpe_io = ((dev->regs.gpe_io & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x24: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0xbf << shift32)) | ((val & 0xbf) << shift32)); + break; + case 0x25: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x0f << shift32)) | ((val & 0x0f) << shift32)); + break; + case 0x26: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x03 << shift32)) | ((val & 0x03) << shift32)); + break; + case 0x27: + dev->regs.gpe_pol = ((dev->regs.gpe_pol & ~(0x10 << shift32)) | ((val & 0x10) << shift32)); + break; + case 0x28: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0xf9 << shift16)) | ((val & 0xf9) << shift16)); + break; + case 0x29: + dev->regs.gpe_mul = ((dev->regs.gpe_mul & ~(0x13 << shift16)) | ((val & 0x13) << shift16)); + break; + case 0x2a: + case 0x2b: + dev->regs.gpe_ctl = ((dev->regs.gpe_ctl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2c: + case 0x2d: + dev->regs.gpe_smi = ((dev->regs.gpe_smi & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x2e: + case 0x2f: + dev->regs.gpe_rl = ((dev->regs.gpe_rl & ~(0xff << shift16)) | ((val & 0xff) << shift16)); + break; + case 0x30: + dev->regs.leg_sts &= ~val; + break; + case 0x31: + old = dev->regs.leg_en; + dev->regs.leg_en = val; + if (!(old & 0x04) && (val & 0x04)) + timer_on_auto(&dev->per_timer, 16000000.0); + else if ((old & 0x04) && !(val & 0x04)) + timer_stop(&dev->per_timer); + break; + case 0x32: + if (dev->vendor == VEN_SIS_5595_1997) { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + if (val == dev->regs.smi_en_val) { + dev->regs.leg_sts |= 0x08; + if (dev->regs.leg_en & 0x08) + acpi_sis5595_smi_raise(dev); + } else if (val == dev->regs.smi_dis_val) { + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + } + break; + case 0x33: + dev->regs.tst_ctl = val & 0x01; + break; + case 0x34: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_en_val = val; + else + dev->regs.reg_34 = val; + break; + case 0x35: + if (dev->vendor == VEN_SIS_5595_1997) + dev->regs.smi_dis_val = val; + else { + /* SMI Command Port */ + dev->regs.smi_cmd = val; + dev->regs.leg_sts |= 0x10; + if (dev->regs.leg_en & 0x10) + acpi_sis5595_smi_raise(dev); + } + break; + case 0x36: + dev->regs.mail_box = val; + break; + case 0x38: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.index = val; + smbus_sis5595_write_index(dev->smbus, val); + } + break; + case 0x39: + if (dev->vendor == VEN_SIS_5595) { + dev->regs.reg_ff = val & 0x3f; + smbus_sis5595_write_data(dev->smbus, val); + if (val & 0x20) { /* Set GPIO5_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000008; + do_smi |= (dev->regs.gpe_en & 0x00000004); + } else if (val & 0x10) { /* Set GPIO10_STS of GPE_STS */ + dev->regs.gpe_sts |= 0x00000004; + do_smi |= (dev->regs.gpe_en & 0x00000008); + } else if (val & 0x08) { /* Set RI_STS in GPE_STS */ + dev->regs.gpe_sts |= 0x00000002; + do_smi |= (dev->regs.gpe_en & 0x00000002); + } else if (val & 0x04) /* Set WAK_STS of PM1_STS */ + dev->regs.pmsts |= 0x8000; + else if (val & 0x02) { /* Set RTC_STS of PM1_STS */ + dev->regs.pmsts |= 0x0400; + do_smi |= (dev->regs.pmen & 0x0400); + } else if (val & 0x01) { /* Set PWRBTN_STS of PM1_STS */ + dev->regs.pmsts |= 0x0100; + do_smi |= (dev->regs.pmen & 0x0100); + } + + if (do_smi) + acpi_sis5595_smi_raise(dev); + } + break; + default: + acpi_reg_write_common_regs(size, addr, val, priv); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.reg_13 &= ~0x02; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.leg_sts |= 0x01; + if (dev->regs.leg_en & 0x01) + acpi_sis5595_smi_raise(dev); + } + break; } } static uint32_t -acpi_reg_read_common(int size, uint16_t addr, void *p) +acpi_reg_read_common(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; + const acpi_t *dev = (acpi_t *) priv; uint8_t ret = 0xff; - if (dev->vendor == VEN_ALI) - ret = acpi_reg_read_ali(size, addr, p); - else if (dev->vendor == VEN_VIA) - ret = acpi_reg_read_via(size, addr, p); - else if (dev->vendor == VEN_VIA_596B) - ret = acpi_reg_read_via_596b(size, addr, p); - else if (dev->vendor == VEN_INTEL) - ret = acpi_reg_read_intel(size, addr, p); - else if (dev->vendor == VEN_SMC) - ret = acpi_reg_read_smc(size, addr, p); + switch (dev->vendor) { + case VEN_ALI: + ret = acpi_reg_read_ali(size, addr, priv); + break; + case VEN_VIA: + ret = acpi_reg_read_via(size, addr, priv); + break; + case VEN_VIA_596B: + ret = acpi_reg_read_via_596b(size, addr, priv); + break; + case VEN_INTEL: + ret = acpi_reg_read_intel(size, addr, priv); + break; + case VEN_SMC: + ret = acpi_reg_read_smc(size, addr, priv); + break; + case VEN_SIS_5582: + ret = acpi_reg_read_sis_5582(size, addr, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + ret = acpi_reg_read_sis_5595(size, addr, priv); + break; + } return ret; } static void -acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + const acpi_t *dev = (acpi_t *) priv; - if (dev->vendor == VEN_ALI) - acpi_reg_write_ali(size, addr, val, p); - else if (dev->vendor == VEN_VIA) - acpi_reg_write_via(size, addr, val, p); - else if (dev->vendor == VEN_VIA_596B) - acpi_reg_write_via_596b(size, addr, val, p); - else if (dev->vendor == VEN_INTEL) - acpi_reg_write_intel(size, addr, val, p); - else if (dev->vendor == VEN_SMC) - acpi_reg_write_smc(size, addr, val, p); + switch (dev->vendor) { + case VEN_ALI: + acpi_reg_write_ali(size, addr, val, priv); + break; + case VEN_VIA: + acpi_reg_write_via(size, addr, val, priv); + break; + case VEN_VIA_596B: + acpi_reg_write_via_596b(size, addr, val, priv); + break; + case VEN_INTEL: + acpi_reg_write_intel(size, addr, val, priv); + break; + case VEN_SMC: + acpi_reg_write_smc(size, addr, val, priv); + break; + case VEN_SIS_5582: + acpi_reg_write_sis_5582(size, addr, val, priv); + break; + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + acpi_reg_write_sis_5595(size, addr, val, priv); + break; + } } static uint32_t -acpi_aux_reg_read_common(int size, uint16_t addr, void *p) +acpi_aux_reg_read_common(int size, uint16_t addr, void *priv) { - acpi_t *dev = (acpi_t *) p; + const acpi_t *dev = (acpi_t *) priv; uint8_t ret = 0xff; if (dev->vendor == VEN_SMC) - ret = acpi_aux_reg_read_smc(size, addr, p); + ret = acpi_aux_reg_read_smc(size, addr, priv); return ret; } static void -acpi_aux_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) +acpi_aux_reg_write_common(int size, uint16_t addr, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + const acpi_t *dev = (acpi_t *) priv; if (dev->vendor == VEN_SMC) - acpi_aux_reg_write_smc(size, addr, val, p); + acpi_aux_reg_write_smc(size, addr, val, priv); } static uint32_t -acpi_reg_readl(uint16_t addr, void *p) +acpi_reg_readl(uint16_t addr, void *priv) { uint32_t ret = 0x00000000; - ret = acpi_reg_read_common(4, addr, p); - ret |= (acpi_reg_read_common(4, addr + 1, p) << 8); - ret |= (acpi_reg_read_common(4, addr + 2, p) << 16); - ret |= (acpi_reg_read_common(4, addr + 3, p) << 24); + ret = acpi_reg_read_common(4, addr, priv); + ret |= (acpi_reg_read_common(4, addr + 1, priv) << 8); + ret |= (acpi_reg_read_common(4, addr + 2, priv) << 16); + ret |= (acpi_reg_read_common(4, addr + 3, priv) << 24); acpi_log("ACPI: Read L %08X from %04X\n", ret, addr); @@ -1248,12 +1981,12 @@ acpi_reg_readl(uint16_t addr, void *p) } static uint16_t -acpi_reg_readw(uint16_t addr, void *p) +acpi_reg_readw(uint16_t addr, void *priv) { uint16_t ret = 0x0000; - ret = acpi_reg_read_common(2, addr, p); - ret |= (acpi_reg_read_common(2, addr + 1, p) << 8); + ret = acpi_reg_read_common(2, addr, priv); + ret |= (acpi_reg_read_common(2, addr + 1, priv) << 8); acpi_log("ACPI: Read W %08X from %04X\n", ret, addr); @@ -1261,11 +1994,11 @@ acpi_reg_readw(uint16_t addr, void *p) } static uint8_t -acpi_reg_read(uint16_t addr, void *p) +acpi_reg_read(uint16_t addr, void *priv) { uint8_t ret = 0x00; - ret = acpi_reg_read_common(1, addr, p); + ret = acpi_reg_read_common(1, addr, priv); acpi_log("ACPI: Read B %02X from %04X\n", ret, addr); @@ -1273,14 +2006,14 @@ acpi_reg_read(uint16_t addr, void *p) } static uint32_t -acpi_aux_reg_readl(uint16_t addr, void *p) +acpi_aux_reg_readl(uint16_t addr, void *priv) { uint32_t ret = 0x00000000; - ret = acpi_aux_reg_read_common(4, addr, p); - ret |= (acpi_aux_reg_read_common(4, addr + 1, p) << 8); - ret |= (acpi_aux_reg_read_common(4, addr + 2, p) << 16); - ret |= (acpi_aux_reg_read_common(4, addr + 3, p) << 24); + ret = acpi_aux_reg_read_common(4, addr, priv); + ret |= (acpi_aux_reg_read_common(4, addr + 1, priv) << 8); + ret |= (acpi_aux_reg_read_common(4, addr + 2, priv) << 16); + ret |= (acpi_aux_reg_read_common(4, addr + 3, priv) << 24); acpi_log("ACPI: Read Aux L %08X from %04X\n", ret, addr); @@ -1288,12 +2021,12 @@ acpi_aux_reg_readl(uint16_t addr, void *p) } static uint16_t -acpi_aux_reg_readw(uint16_t addr, void *p) +acpi_aux_reg_readw(uint16_t addr, void *priv) { uint16_t ret = 0x0000; - ret = acpi_aux_reg_read_common(2, addr, p); - ret |= (acpi_aux_reg_read_common(2, addr + 1, p) << 8); + ret = acpi_aux_reg_read_common(2, addr, priv); + ret |= (acpi_aux_reg_read_common(2, addr + 1, priv) << 8); acpi_log("ACPI: Read Aux W %04X from %04X\n", ret, addr); @@ -1301,11 +2034,11 @@ acpi_aux_reg_readw(uint16_t addr, void *p) } static uint8_t -acpi_aux_reg_read(uint16_t addr, void *p) +acpi_aux_reg_read(uint16_t addr, void *priv) { uint8_t ret = 0x00; - ret = acpi_aux_reg_read_common(1, addr, p); + ret = acpi_aux_reg_read_common(1, addr, priv); acpi_log("ACPI: Read Aux B %02X from %04X\n", ret, addr); @@ -1313,59 +2046,59 @@ acpi_aux_reg_read(uint16_t addr, void *p) } static void -acpi_reg_writel(uint16_t addr, uint32_t val, void *p) +acpi_reg_writel(uint16_t addr, uint32_t val, void *priv) { acpi_log("ACPI: Write L %08X to %04X\n", val, addr); - acpi_reg_write_common(4, addr, val & 0xff, p); - acpi_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p); - acpi_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p); - acpi_reg_write_common(4, addr + 3, (val >> 24) & 0xff, p); + acpi_reg_write_common(4, addr, val & 0xff, priv); + acpi_reg_write_common(4, addr + 1, (val >> 8) & 0xff, priv); + acpi_reg_write_common(4, addr + 2, (val >> 16) & 0xff, priv); + acpi_reg_write_common(4, addr + 3, (val >> 24) & 0xff, priv); } static void -acpi_reg_writew(uint16_t addr, uint16_t val, void *p) +acpi_reg_writew(uint16_t addr, uint16_t val, void *priv) { acpi_log("ACPI: Write W %04X to %04X\n", val, addr); - acpi_reg_write_common(2, addr, val & 0xff, p); - acpi_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p); + acpi_reg_write_common(2, addr, val & 0xff, priv); + acpi_reg_write_common(2, addr + 1, (val >> 8) & 0xff, priv); } static void -acpi_reg_write(uint16_t addr, uint8_t val, void *p) +acpi_reg_write(uint16_t addr, uint8_t val, void *priv) { acpi_log("ACPI: Write B %02X to %04X\n", val, addr); - acpi_reg_write_common(1, addr, val, p); + acpi_reg_write_common(1, addr, val, priv); } static void -acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p) +acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *priv) { acpi_log("ACPI: Write Aux L %08X to %04X\n", val, addr); - acpi_aux_reg_write_common(4, addr, val & 0xff, p); - acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p); - acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p); - acpi_aux_reg_write_common(4, addr + 3, (val >> 24) & 0xff, p); + acpi_aux_reg_write_common(4, addr, val & 0xff, priv); + acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, priv); + acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, priv); + acpi_aux_reg_write_common(4, addr + 3, (val >> 24) & 0xff, priv); } static void -acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p) +acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *priv) { acpi_log("ACPI: Write Aux W %04X to %04X\n", val, addr); - acpi_aux_reg_write_common(2, addr, val & 0xff, p); - acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p); + acpi_aux_reg_write_common(2, addr, val & 0xff, priv); + acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, priv); } static void -acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p) +acpi_aux_reg_write(uint16_t addr, uint8_t val, void *priv) { acpi_log("ACPI: Write Aux B %02X to %04X\n", val, addr); - acpi_aux_reg_write_common(1, addr, val, p); + acpi_aux_reg_write_common(1, addr, val, priv); } void @@ -1374,9 +2107,12 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) int size; switch (dev->vendor) { + default: case VEN_ALI: case VEN_INTEL: - default: + case VEN_SIS_5582: + case VEN_SIS_5595_1997: + case VEN_SIS_5595: size = 0x040; break; case VEN_SMC: @@ -1545,9 +2281,9 @@ acpi_pwrbtn_timer(void *priv) } static void -acpi_apm_out(uint16_t port, uint8_t val, void *p) +acpi_apm_out(uint16_t port, uint8_t val, void *priv) { - acpi_t *dev = (acpi_t *) p; + acpi_t *dev = (acpi_t *) priv; acpi_log("[%04X:%08X] APM write: %04X = %02X (AX = %04X, BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, AX, BX, CX); @@ -1557,7 +2293,9 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p) if (port == 0x0001) { acpi_log("ALi SOFT SMI# status set (%i)\n", dev->apm->do_smi); dev->apm->cmd = val; - // acpi_raise_smi(dev, dev->apm->do_smi); +#if 0 + acpi_raise_smi(dev, dev->apm->do_smi); +#endif if (dev->apm->do_smi) smi_raise(); dev->regs.ali_soft_smi = 1; @@ -1575,10 +2313,10 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p) } static uint8_t -acpi_apm_in(uint16_t port, void *p) +acpi_apm_in(uint16_t port, void *priv) { - acpi_t *dev = (acpi_t *) p; - uint8_t ret = 0xff; + const acpi_t *dev = (acpi_t *) priv; + uint8_t ret = 0xff; port &= 0x0001; @@ -1605,7 +2343,10 @@ acpi_reset(void *priv) acpi_t *dev = (acpi_t *) priv; memset(&dev->regs, 0x00, sizeof(acpi_regs_t)); - dev->regs.gpireg[0] = 0xff; + /* PC Chips M773: + - Bit 3: 80-conductor cable on unknown IDE channel (active low) + - Bit 1: 80-conductor cable on unknown IDE channel (active low) */ + dev->regs.gpireg[0] = !strcmp(machine_get_internal_name(), "m773") ? 0xf5 : 0xff; dev->regs.gpireg[1] = 0xff; /* A-Trend ATC7020BXII: - Bit 3: 80-conductor cable on secondary IDE channel (active low) @@ -1639,10 +2380,34 @@ acpi_reset(void *priv) dev->regs.gpi_val |= 0x00000004; } - /* Power on always generates a resume event. */ - dev->regs.pmsts |= 0x8000; + if (acpi_power_on) { + /* Power on always generates a resume event. */ + dev->regs.pmsts |= 0x8100; + acpi_power_on = 0; + } + + /* The Gateway Tomahawk requires the LID polarity bit to be set. */ + if (!strcmp(machine_get_internal_name(), "tomahawk")) + dev->regs.glbctl |= 0x02000000; acpi_rtc_status = 0; + + acpi_update_irq(dev); + dev->irq_state = 0; + + timer_disable(&dev->gp_timer); + + acpi_last_clock = 0ULL; + acpi_count = 0; + + timer_disable(&dev->per_timer); + + if ((dev->vendor == VEN_SIS_5595_1997) || (dev->vendor == VEN_SIS_5595)) { + dev->regs.reg_13 = 0x20; + dev->regs.gp_tmr = 0xff; + dev->regs.gpe_io = 0x00030b9f; + dev->regs.gpe_mul = 0x1001; + } } static void @@ -1655,6 +2420,33 @@ acpi_speed_changed(void *priv) if (timer_enabled) timer_on_auto(&dev->timer, acpi_get_overflow_period(dev)); + + if ((dev->vendor & 0xffff) == 0x1039) { + if (timer_is_on(&dev->gp_timer)) { + timer_stop(&dev->gp_timer); + + if (dev->vendor == VEN_SIS_5595_1997) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x20000000), acpi_count); + else if (dev->vendor == VEN_SIS_5595) + acpi_gp_timer_update(dev, (dev->regs.gpe_en & 0x00000400), acpi_count); + else + acpi_gp_timer_update(dev, (dev->regs.reg_16 & 0x2000), acpi_count); + } + + if (timer_is_on(&dev->per_timer)) { + timer_stop(&dev->per_timer); + + timer_on_auto(&dev->per_timer, 16000000.0); + } + } +} + +void * +acpi_get_smbus(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + return dev->smbus; } static void @@ -1680,7 +2472,7 @@ acpi_init(const device_t *info) dev = (acpi_t *) malloc(sizeof(acpi_t)); if (dev == NULL) - return (NULL); + return NULL; memset(dev, 0x00, sizeof(acpi_t)); cpu_to_acpi = ACPI_TIMER_FREQ / cpuclock; @@ -1709,6 +2501,7 @@ acpi_init(const device_t *info) dev->suspend_types[2] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; dev->suspend_types[3] = SUS_SUSPEND; dev->suspend_types[5] = SUS_POWER_OFF; /* undocumented, used for S4/S5 by ASUS P5A ACPI table */ + dev->suspend_types[7] = SUS_POWER_OFF; /* undocumented, used for S5 by Gigabyte GA-5AX ACPI table */ break; case VEN_VIA: @@ -1731,6 +2524,31 @@ acpi_init(const device_t *info) dev->suspend_types[3] = SUS_SUSPEND | SUS_RESET_CACHE; dev->suspend_types[4] = SUS_SUSPEND; break; + + case VEN_SIS_5582: + dev->suspend_types[0] = SUS_SUSPEND; /* S1 */ + dev->suspend_types[4] = SUS_POWER_OFF; /* S5 */ + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + break; + + case VEN_SIS_5595_1997: + case VEN_SIS_5595: + dev->suspend_types[1] = SUS_SUSPEND; + dev->suspend_types[2] = SUS_SUSPEND; + dev->suspend_types[3] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[4] = SUS_POWER_OFF; + dev->suspend_types[5] = SUS_POWER_OFF; + + timer_add(&dev->gp_timer, acpi_gp_timer, dev, 0); + timer_add(&dev->per_timer, acpi_per_timer, dev, 0); + + dev->smbus = device_add(&sis5595_smbus_device); + break; + + default: + break; } timer_add(&dev->timer, acpi_timer_overflow, dev, 0); @@ -1741,7 +2559,9 @@ acpi_init(const device_t *info) acpi_reset(dev); - acpi_enabled = 1; + acpi_enabled = 1; + acpi_power_on = 1; + return dev; } @@ -1814,3 +2634,45 @@ const device_t acpi_smc_device = { .force_redraw = NULL, .config = NULL }; + +const device_t acpi_sis_5582_device = { + .name = "SiS 5582 ACPI", + .internal_name = "acpi_sis_5582", + .flags = DEVICE_PCI, + .local = VEN_SIS_5582, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_1997_device = { + .name = "SiS 5595 (1997) ACPI", + .internal_name = "acpi_sis_5595_1997", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595_1997, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t acpi_sis_5595_device = { + .name = "SiS 5595 ACPI", + .internal_name = "acpi_sis_5595", + .flags = DEVICE_PCI, + .local = VEN_SIS_5595, + .init = acpi_init, + .close = acpi_close, + .reset = acpi_reset, + { .available = NULL }, + .speed_changed = acpi_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/apm.c b/src/apm.c index 76fc242573..d7ce262a3f 100644 --- a/src/apm.c +++ b/src/apm.c @@ -52,9 +52,9 @@ apm_set_do_smi(apm_t *dev, uint8_t do_smi) } static void -apm_out(uint16_t port, uint8_t val, void *p) +apm_out(uint16_t port, uint8_t val, void *priv) { - apm_t *dev = (apm_t *) p; + apm_t *dev = (apm_t *) priv; apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX); @@ -69,10 +69,10 @@ apm_out(uint16_t port, uint8_t val, void *p) } static uint8_t -apm_in(uint16_t port, void *p) +apm_in(uint16_t port, void *priv) { - apm_t *dev = (apm_t *) p; - uint8_t ret = 0xff; + const apm_t *dev = (apm_t *) priv; + uint8_t ret = 0xff; port &= 0x0001; @@ -87,24 +87,23 @@ apm_in(uint16_t port, void *p) } static void -apm_reset(void *p) +apm_reset(void *priv) { - apm_t *dev = (apm_t *) p; + apm_t *dev = (apm_t *) priv; dev->cmd = dev->stat = 0x00; } static void -apm_close(void *p) +apm_close(void *priv) { - apm_t *dev = (apm_t *) p; + apm_t *dev = (apm_t *) priv; free(dev); } -static void - * - apm_init(const device_t *info) +static void * +apm_init(const device_t *info) { apm_t *dev = (apm_t *) malloc(sizeof(apm_t)); memset(dev, 0, sizeof(apm_t)); diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 37128fbccf..ea025de2ac 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -145,13 +145,11 @@ cdrom_interface_reset(void) cdrom_interface_current); /* If we have a valid controller, add its device. */ - if (!controllers[cdrom_interface_current].device) - return; - - device_add(controllers[cdrom_interface_current].device); + if ((cdrom_interface_current > 0) && controllers[cdrom_interface_current].device) + device_add(controllers[cdrom_interface_current].device); } -char * +const char * cdrom_interface_get_internal_name(int cdinterface) { return device_get_internal_name(controllers[cdinterface].device); @@ -163,7 +161,7 @@ cdrom_interface_get_from_internal_name(char *s) int c = 0; while (controllers[c].device != NULL) { - if (!strcmp((char *) controllers[c].device->internal_name, s)) + if (!strcmp(controllers[c].device->internal_name, s)) return c; c++; } @@ -422,6 +420,8 @@ cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type) case 0x80: pos = bcd2bin((pos >> 24) & 0xff); break; + default: + break; } dev->seek_pos = pos; @@ -442,7 +442,7 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) { int ret = 1; - if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING)) { + if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) { cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id); if (dev->cd_status == CD_STATUS_PLAYING) dev->seek_pos += (len >> 11); @@ -529,7 +529,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) f = pos & 0xff; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/ msf_from_bcd(&m, &s, &f); if (pos == 0xffffff) { @@ -543,7 +543,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) f = len & 0xff; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/ msf_from_bcd(&m, &s, &f); len = MSFtoLBA(m, s, f) - 150; @@ -557,6 +557,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) len += pos; } + dev->audio_muted_soft = 0; /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { @@ -569,7 +570,6 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) dev->cd_end = len; dev->cd_status = CD_STATUS_PLAYING; dev->cd_buflen = 0; - return 1; } @@ -579,6 +579,7 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) int m = 0; int s = 0; int f = 0; + uint32_t pos2 = 0; if (dev->cd_status == CD_STATUS_DATA_ONLY) return 0; @@ -611,15 +612,86 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) } dev->seek_pos = (pos >> 24) & 0xff; break; + default: + break; } - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ + pos2 = pos - 1; + if (pos2 == 0xffffffff) + pos2 = pos + 1; + + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos2) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: Track Search: LBA %08X not on an audio track\n", dev->id, pos); + dev->audio_muted_soft = 1; + if (dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + } else + dev->audio_muted_soft = 0; + + cdrom_log("Track Search Toshiba: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; } +uint8_t +cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) +{ + int m = 0; + int s = 0; + int f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + f = bcd2bin((pos >> 24) & 0xff); + s = bcd2bin((pos >> 16) & 0xff); + m = bcd2bin((pos >> 8) & 0xff); + if (pos == 0xffffffff) { + pos = dev->seek_pos; + } else + pos = MSFtoLBA(m, s, f) - 150; + + dev->seek_pos = pos; + + dev->audio_muted_soft = 0; + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + + dev->cd_buflen = 0; + dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; + return 1; +} + +uint8_t +cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos) +{ + int m = 0; + int s = 0; + int f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + f = bcd2bin((pos >> 24) & 0xff); + s = bcd2bin((pos >> 16) & 0xff); + m = bcd2bin((pos >> 8) & 0xff); + pos = MSFtoLBA(m, s, f) - 150; + dev->cd_end = pos; + + dev->audio_muted_soft = 0; + dev->cd_buflen = 0; + dev->cd_status = CD_STATUS_PLAYING; + return 1; +} + uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) { @@ -652,13 +724,11 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) } dev->cd_end = pos; break; + default: + break; } - cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status); - - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ - + cdrom_log("Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; @@ -698,8 +768,11 @@ cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type) case 0x80: dev->seek_pos = (pos >> 24) & 0xff; break; + default: + break; } + dev->audio_muted_soft = 0; /* Do this at this point, since it's at this point that we know the actual LBA position to start playing from. */ if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { @@ -743,7 +816,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) ret = 0x13; } - cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, ret, dev->seek_pos, dev->cd_end); + cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, ret, dev->seek_pos, dev->cd_end); if (b[pos] > 1) { cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret); @@ -758,7 +831,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) b[pos] = 0; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ { + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ m = subc.abs_m; s = subc.abs_s; f = subc.abs_f; @@ -777,7 +850,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) b[pos] = 0; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ { + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ m = subc.rel_m; s = subc.rel_s; f = subc.rel_f; @@ -812,36 +885,61 @@ void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf) { subchannel_t subc; - int pos = 0; uint32_t dat; dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end); + cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf); - b[pos++] = subc.attr; - b[pos++] = subc.track; - b[pos++] = subc.index; + b[0] = subc.attr; + b[1] = subc.track; + b[2] = subc.index; if (msf) { - b[pos++] = subc.rel_m; - b[pos++] = subc.rel_s; - b[pos++] = subc.rel_f; - b[pos++] = subc.abs_m; - b[pos++] = subc.abs_s; - b[pos++] = subc.abs_f; + b[3] = subc.rel_m; + b[4] = subc.rel_s; + b[5] = subc.rel_f; + b[6] = subc.abs_m; + b[7] = subc.abs_s; + b[8] = subc.abs_f; } else { dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; + b[3] = (dat >> 16) & 0xff; + b[4] = (dat >> 8) & 0xff; + b[5] = dat & 0xff; dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; + b[6] = (dat >> 16) & 0xff; + b[7] = (dat >> 8) & 0xff; + b[8] = dat & 0xff; } } +uint8_t +cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b) +{ + uint8_t ret; + subchannel_t subc; + + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + ret = 0x05; + else { + if (dev->cd_status == CD_STATUS_PLAYING) + ret = dev->sound_on ? 0x00 : 0x02; + else if (dev->cd_status == CD_STATUS_PAUSED) + ret = 0x01; + else + ret = 0x03; + } + + b[0] = 0; + b[1] = bin2bcd(subc.abs_m); + b[2] = bin2bcd(subc.abs_s); + b[3] = bin2bcd(subc.abs_f); + + return ret; +} uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) @@ -879,21 +977,44 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) return ret; } +void +cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b) +{ + subchannel_t subc; + + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + + b[0] = subc.attr; + b[1] = bin2bcd(subc.track); + b[2] = bin2bcd(subc.index); + b[3] = bin2bcd(subc.rel_m); + b[4] = bin2bcd(subc.rel_s); + b[5] = bin2bcd(subc.rel_f); + b[6] = bin2bcd(subc.abs_m); + b[7] = bin2bcd(subc.abs_s); + b[8] = bin2bcd(subc.abs_f); +} + uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) { - uint8_t ret; + uint8_t ret; subchannel_t subc; dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - cdrom_log("Get Current Subcode-q Play Status = %02x, op = %02x.\n", dev->cd_status, dev->audio_op); - - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED)) + if ((dev->cd_status == CD_STATUS_DATA_ONLY) || + (dev->cd_status == CD_STATUS_PLAYING_COMPLETED) || + (dev->cd_status == CD_STATUS_STOPPED)) ret = 0x03; else ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op; + /*If a valid audio track is detected with audio on, unmute it.*/ + if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + + cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft); b[0] = subc.attr; b[1] = bin2bcd(subc.track); b[2] = bin2bcd(subc.index); @@ -949,9 +1070,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m /* No suitable starting track, return with error. */ if (first_track == -1) { -#ifdef ENABLE_CDROM_LOG cdrom_log(" [ERROR] No suitable track found\n"); -#endif return -1; } @@ -968,7 +1087,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m b[len++] = 0; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ m = ti.m; s = ti.s; f = ti.f; @@ -1021,7 +1140,7 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf) b[len++] = 0; /* NEC CDR-260 speaks BCD. */ - if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ m = ti.m; s = ti.s; f = ti.f; @@ -1120,9 +1239,7 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf /* No suitable starting track, return with error. */ if (first_track == -1) { -#ifdef ENABLE_CDROM_LOG cdrom_log(" [ERROR] No suitable track found\n"); -#endif return -1; } @@ -1130,8 +1247,8 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); dev->ops->get_track_info(dev, i + 1, 0, &ti); - b[len++] = ti.attr; b[len++] = ti.number; /* track number */ + b[len++] = ti.attr; if (msf) { b[len++] = 0; @@ -1146,7 +1263,6 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf b[len++] = temp; } } - return len; } @@ -1286,6 +1402,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in int m = 0; int s = 0; int f = 0; + uint32_t temp; dev->ops->get_tracks(dev, &first_track, &last_track); @@ -1325,11 +1442,34 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in b[3] = ti.attr; cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr); break; - case 3: - b[0] = 0x00; /*TODO: correct it further, mark it as CD-Audio/CD-ROM disc for now*/ - b[1] = 0; - b[2] = 0; - b[3] = 0; + case 3: /* Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from the Linux kernel */ + switch (dev->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + dev->ops->get_track_info(dev, 1, 0, &ti); + b[0x0e] = 0; + temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + b[0x0f] = temp >> 24; + b[0x10] = temp >> 16; + b[0x11] = temp >> 8; + b[0x12] = temp; + break; + + default: + dev->ops->get_track_info(dev, 1, 0, &ti); + b[0] = 0; + temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + b[1] = temp >> 24; + b[2] = temp >> 16; + b[3] = temp >> 8; + break; + } + break; + default: break; } @@ -1337,7 +1477,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in } static int -track_type_is_valid(uint8_t id, int type, int flags, int audio, int mode2) +track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode2) { if (!(flags & 0x70) && (flags & 0xf8)) { /* 0x08/0x80/0x88 are illegal modes */ cdrom_log("CD-ROM %i: [Any Mode] 0x08/0x80/0x88 are illegal modes\n", id); @@ -1820,8 +1960,18 @@ cdrom_hard_reset(void) dev->cd_status = CD_STATUS_EMPTY; - if (dev->host_drive == 200) + if (dev->host_drive == 200) { +#ifdef _WIN32 + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; +#else + if ((strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; +#endif + cdrom_image_open(dev, dev->image_path); + } } } @@ -1858,10 +2008,8 @@ cdrom_insert(uint8_t id) { cdrom_t *dev = &cdrom[id]; - if (dev->bus_type) { - if (dev->insert) - dev->insert(dev->priv); - } + if (dev->bus_type && dev->insert) + dev->insert(dev->priv); } /* The mechanics of ejecting a CD-ROM from a drive. */ @@ -1912,6 +2060,15 @@ cdrom_reload(uint8_t id) if (dev->prev_host_drive == 200) { /* Reload a previous image. */ strcpy(dev->image_path, dev->prev_image_path); + +#ifdef _WIN32 + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; +#else + if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; +#endif + cdrom_image_open(dev, dev->image_path); cdrom_insert(id); diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 5d82942131..151ddfe9f0 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -68,24 +68,24 @@ cdrom_image_backend_log(const char *fmt, ...) /* Binary file functions. */ static int -bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count) +bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) { - track_file_t *tf = (track_file_t *) p; + track_file_t *tf = (track_file_t *) priv; cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n", - tf->file, seek, count); + tf->fp, seek, count); - if (tf->file == NULL) + if (tf->fp == NULL) return 0; - if (fseeko64(tf->file, seek, SEEK_SET) == -1) { + if (fseeko64(tf->fp, seek, SEEK_SET) == -1) { #ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CDROM: binary_read failed during seek!\n"); #endif return 0; } - if (fread(buffer, count, 1, tf->file) != 1) { + if (fread(buffer, count, 1, tf->fp) != 1) { #ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CDROM: binary_read failed during read!\n"); #endif @@ -96,39 +96,39 @@ bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count) } static uint64_t -bin_get_length(void *p) +bin_get_length(void *priv) { off64_t len; - track_file_t *tf = (track_file_t *) p; + track_file_t *tf = (track_file_t *) priv; - cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->file); + cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp); - if (tf->file == NULL) + if (tf->fp == NULL) return 0; - fseeko64(tf->file, 0, SEEK_END); - len = ftello64(tf->file); - cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->file, len); + fseeko64(tf->fp, 0, SEEK_END); + len = ftello64(tf->fp); + cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len); return len; } static void -bin_close(void *p) +bin_close(void *priv) { - track_file_t *tf = (track_file_t *) p; + track_file_t *tf = (track_file_t *) priv; if (tf == NULL) return; - if (tf->file != NULL) { - fclose(tf->file); - tf->file = NULL; + if (tf->fp != NULL) { + fclose(tf->fp); + tf->fp = NULL; } memset(tf->fn, 0x00, sizeof(tf->fn)); - free(p); + free(priv); } static track_file_t * @@ -144,14 +144,14 @@ bin_init(const char *filename, int *error) memset(tf->fn, 0x00, sizeof(tf->fn)); strncpy(tf->fn, filename, sizeof(tf->fn) - 1); - tf->file = plat_fopen64(tf->fn, "rb"); - cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx\n", tf->fn, tf->file); + tf->fp = plat_fopen64(tf->fn, "rb"); + cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx\n", tf->fn, tf->fp); if (stat(tf->fn, &stats) != 0) { /* Use a blank structure if stat failed. */ memset(&stats, 0, sizeof(struct stat)); } - *error = ((tf->file == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR)); + *error = ((tf->fp == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR)); /* Set the function pointers. */ if (!*error) { @@ -162,7 +162,7 @@ bin_init(const char *filename, int *error) /* From the check above, error may still be non-zero if opening a directory. * The error is set for viso to try and open the directory following this function. * However, we need to make sure the descriptor is closed. */ - if ((tf->file != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { + if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { /* tf is freed by bin_close */ bin_close(tf); } else { @@ -202,8 +202,8 @@ track_file_close(track_t *trk) static void cdi_clear_tracks(cd_img_t *cdi) { - track_file_t *last = NULL; - track_t *cur = NULL; + const track_file_t *last = NULL; + track_t *cur = NULL; if ((cdi->tracks == NULL) || (cdi->tracks_num == 0)) return; @@ -273,7 +273,7 @@ cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_ int cdi_get_audio_track_pre(cd_img_t *cdi, int track) { - track_t *trk = &cdi->tracks[track - 1]; + const track_t *trk = &cdi->tracks[track - 1]; if ((track < 1) || (track > cdi->tracks_num)) return 0; @@ -283,9 +283,9 @@ cdi_get_audio_track_pre(cd_img_t *cdi, int track) /* This replaces both Info and EndInfo, they are specified by a variable. */ int -cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr) +cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - track_t *trk = &cdi->tracks[track - 1]; + const track_t *trk = &cdi->tracks[track - 1]; int pos = trk->start + 150; if ((track < 1) || (track > cdi->tracks_num)) @@ -302,9 +302,9 @@ cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF } int -cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr) +cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, uint32_t *start, uint8_t *attr) { - track_t *trk = &cdi->tracks[track - 1]; + const track_t *trk = &cdi->tracks[track - 1]; if ((track < 1) || (track > cdi->tracks_num)) return 0; @@ -320,8 +320,8 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, int cdi_get_track(cd_img_t *cdi, uint32_t sector) { - track_t *cur; - track_t *next; + const track_t *cur; + const track_t *next; /* There must be at least two tracks - data and lead out. */ if (cdi->tracks_num < 2) @@ -332,6 +332,11 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) for (int i = 0; i < (cdi->tracks_num - 1); i++) { cur = &cdi->tracks[i]; next = &cdi->tracks[i + 1]; + + /* Take into account cue sheets that do not start on sector 0. */ + if ((i == 0) && (sector < cur->start)) + return cur->number; + if ((cur->start <= sector) && (sector < next->start)) return cur->number; } @@ -343,8 +348,8 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - int cur_track = cdi_get_track(cdi, sector); - track_t *trk; + int cur_track = cdi_get_track(cdi, sector); + const track_t *trk; if (cur_track < 1) return 0; @@ -425,8 +430,9 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) return 1; } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); - else + else { return trk->file->read(trk->file, buffer, seek, length); + } } int @@ -483,8 +489,8 @@ cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - track_t *trk; + int track = cdi_get_track(cdi, sector) - 1; + const track_t *trk; if (track < 0) return 0; @@ -496,8 +502,8 @@ cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) int cdi_is_mode2(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - track_t *trk; + int track = cdi_get_track(cdi, sector) - 1; + const track_t *trk; if (track < 0) return 0; @@ -510,8 +516,8 @@ cdi_is_mode2(cd_img_t *cdi, uint32_t sector) int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector) { - int track = cdi_get_track(cdi, sector) - 1; - track_t *trk; + int track = cdi_get_track(cdi, sector) - 1; + const track_t *trk; if (track < 0) return 0; @@ -652,7 +658,7 @@ cdi_cue_get_buffer(char *str, char **line, int up) done = 1; break; } - /*FALLTHROUGH*/ + fallthrough; default: if (up && islower((int) *s)) @@ -787,7 +793,7 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u *total_pregap += cur_pregap; cur->start += *total_pregap; } else { - temp = prev->file->get_length(prev->file) - ((uint64_t) prev->skip); + temp = prev->file->get_length(prev->file) - (prev->skip); prev->length = temp / ((uint64_t) prev->sector_size); if ((temp % prev->sector_size) != 0) prev->length++; diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 2feff2aff4..7ed68cd86c 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -114,13 +114,17 @@ typedef struct _viso_entry_ { } viso_entry_t; typedef struct { - uint64_t vol_size_offsets[2], pt_meta_offsets[2]; - int format, use_version_suffix : 1; + uint64_t vol_size_offsets[2]; + uint64_t pt_meta_offsets[2]; + int format; + uint8_t use_version_suffix : 1; size_t metadata_sectors, all_sectors, entry_map_size, sector_size, file_fifo_pos; uint8_t *metadata; - track_file_t tf; - viso_entry_t *root_dir, **entry_map, *file_fifo[VISO_OPEN_FILES]; + track_file_t tf; + viso_entry_t *root_dir; + viso_entry_t **entry_map; + viso_entry_t *file_fifo[VISO_OPEN_FILES]; } viso_t; static const char rr_eid[] = "RRIP_1991A"; /* identifiers used in ER field for Rock Ridge */ @@ -146,24 +150,24 @@ cdrom_image_viso_log(const char *fmt, ...) #endif static size_t -viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *stream) +viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp) { - uint64_t cur_pos = ftello64(stream); + uint64_t cur_pos = ftello64(fp); size_t ret = 0; - if (fseeko64(stream, offset, SEEK_SET) != -1) - ret = fread(ptr, size, count, stream); - fseeko64(stream, cur_pos, SEEK_SET); + if (fseeko64(fp, offset, SEEK_SET) != -1) + ret = fread(ptr, size, count, fp); + fseeko64(fp, cur_pos, SEEK_SET); return ret; } static size_t -viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *stream) +viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp) { - uint64_t cur_pos = ftello64(stream); + uint64_t cur_pos = ftello64(fp); size_t ret = 0; - if (fseeko64(stream, offset, SEEK_SET) != -1) - ret = fwrite(ptr, size, count, stream); - fseeko64(stream, cur_pos, SEEK_SET); + if (fseeko64(fp, offset, SEEK_SET) != -1) + ret = fwrite(ptr, size, count, fp); + fseeko64(fp, cur_pos, SEEK_SET); return ret; } @@ -245,17 +249,28 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size) c -= 'a' - 'A'; \ break; \ \ - case ' ': \ case '!': \ - case '"': \ + case '#': \ + case '$': \ case '%': \ case '&': \ case '\'': \ case '(': \ case ')': \ + case '-': \ + case '@': \ + case '^': \ + case '`': \ + case '{': \ + case '}': \ + case '~': \ + /* Valid on all sets (non-complying DOS characters). */ \ + break; \ + \ + case ' ': \ + case '"': \ case '+': \ case ',': \ - case '-': \ case '.': \ case '<': \ case '=': \ @@ -329,7 +344,7 @@ viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries } /* Check if this filename is unique, and add a tail if required, while also adding the extension. */ - char tail[8]; + char tail[16]; for (int i = force_tail; i <= 999999; i++) { /* Add tail to the filename if this is not the first run. */ int tail_len = -1; @@ -368,7 +383,7 @@ viso_fill_fn_rr(uint8_t *data, const viso_entry_t *entry, size_t max_len) /* Relocate extension if the original name exceeds the maximum length. */ if (!S_ISDIR(entry->stats.st_mode)) { /* do this on files only */ - char *ext = strrchr(entry->basename, '.'); + const char *ext = strrchr(entry->basename, '.'); if (ext > entry->basename) { len = strlen(ext); if (len >= max_len) @@ -399,7 +414,7 @@ viso_fill_fn_joliet(uint8_t *data, const viso_entry_t *entry, size_t max_len) /* /* Relocate extension if the original name exceeds the maximum length. */ if (!S_ISDIR(entry->stats.st_mode)) { /* do this on files only */ - wchar_t *ext = wcsrchr(utf8dec, L'.'); + const wchar_t *ext = wcsrchr(utf8dec, L'.'); if (ext > utf8dec) { len = wcslen(ext); if (len > max_len) @@ -427,7 +442,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) or way too far into 64-bit space (Linux). Fall back to epoch. */ time_t epoch = 0; time_s = localtime(&epoch); - if (!time_s) + if (UNLIKELY(!time_s)) fatal("VISO: localtime(0) = NULL\n"); /* Force year clamping if the timestamp is known to be outside the supported ranges. */ @@ -629,14 +644,13 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type) if (!(*q & 1)) /* padding for even file ID lengths */ *p++ = 0; break; + + default: + break; } - if ((p - data) > 255) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry); -#else - fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry); -#endif + if (UNLIKELY((p - data) > 255)) + fatal("VISO: Directory record overflow (%" PRIuPTR ") on entry %08" PRIXPTR "\n", (uintptr_t) (p - data), (uintptr_t) entry); data[0] = p - data; /* length */ return data[0]; @@ -649,9 +663,9 @@ viso_compare_entries(const void *a, const void *b) } int -viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count) +viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) { - track_file_t *tf = (track_file_t *) p; + track_file_t *tf = (track_file_t *) priv; viso_t *viso = (viso_t *) tf->priv; /* Handle reads in a sector by sector basis. */ @@ -718,17 +732,18 @@ viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count) } uint64_t -viso_get_length(void *p) +viso_get_length(void *priv) { - track_file_t *tf = (track_file_t *) p; - viso_t *viso = (viso_t *) tf->priv; + track_file_t *tf = (track_file_t *) priv; + const viso_t *viso = (viso_t *) tf->priv; + return ((uint64_t) viso->all_sectors) * viso->sector_size; } void -viso_close(void *p) +viso_close(void *priv) { - track_file_t *tf = (track_file_t *) p; + track_file_t *tf = (track_file_t *) priv; viso_t *viso = (viso_t *) tf->priv; if (viso == NULL) @@ -737,8 +752,8 @@ viso_close(void *p) cdrom_image_viso_log("VISO: close()\n"); /* De-allocate everything. */ - if (tf->file) - fclose(tf->file); + if (tf->fp) + fclose(tf->fp); #ifndef ENABLE_CDROM_IMAGE_VISO_LOG remove(nvr_path(viso->tf.fn)); #endif @@ -788,24 +803,24 @@ viso_init(const char *dirname, int *error) #else plat_tempfile(viso->tf.fn, "viso", ".tmp"); #endif - viso->tf.file = plat_fopen64(nvr_path(viso->tf.fn), "w+b"); - if (!viso->tf.file) + viso->tf.fp = plat_fopen64(nvr_path(viso->tf.fn), "w+b"); + if (!viso->tf.fp) goto end; /* Set up directory traversal. */ cdrom_image_viso_log("VISO: Traversing directories:\n"); - viso_entry_t *entry; - viso_entry_t *last_entry; - viso_entry_t *dir; - viso_entry_t *last_dir; - viso_entry_t *eltorito_dir = NULL; - viso_entry_t *eltorito_entry = NULL; - struct dirent *readdir_entry; - int len; - int eltorito_others_present = 0; - size_t dir_path_len; - uint64_t eltorito_offset = 0; - uint8_t eltorito_type = 0; + viso_entry_t *entry; + viso_entry_t *last_entry; + viso_entry_t *dir; + viso_entry_t *last_dir; + const viso_entry_t *eltorito_dir = NULL; + const viso_entry_t *eltorito_entry = NULL; + struct dirent *readdir_entry; + int len; + int eltorito_others_present = 0; + size_t dir_path_len; + uint64_t eltorito_offset = 0; + uint8_t eltorito_type = 0; /* Fill root directory entry. */ dir_path_len = strlen(dirname); @@ -987,7 +1002,7 @@ viso_init(const char *dirname, int *error) /* Write 16 blank sectors. */ for (int i = 0; i < 16; i++) - fwrite(data, viso->sector_size, 1, viso->tf.file); + fwrite(data, viso->sector_size, 1, viso->tf.fp); /* Get current time for the volume descriptors, and calculate the timezone offset for descriptors and file times to use. */ @@ -997,7 +1012,7 @@ viso_init(const char *dirname, int *error) tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4); /* Get root directory basename for the volume ID. */ - char *basename = path_get_filename(viso->root_dir->path); + const char *basename = path_get_filename(viso->root_dir->path); if (!basename || (basename[0] == '\0')) basename = EMU_NAME; @@ -1010,7 +1025,7 @@ viso_init(const char *dirname, int *error) /* Fill volume descriptor. */ p = data; if (!(viso->format & VISO_FORMAT_ISO)) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */ *p++ = 1 + i; /* type */ memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; @@ -1033,7 +1048,7 @@ viso_init(const char *dirname, int *error) VISO_SKIP(p, 8); /* unused */ - viso->vol_size_offsets[i] = ftello64(viso->tf.file) + (p - data); + viso->vol_size_offsets[i] = ftello64(viso->tf.fp) + (p - data); VISO_LBE_32(p, 0); /* volume space size (filled in later) */ if (i) { @@ -1050,10 +1065,10 @@ viso_init(const char *dirname, int *error) VISO_LBE_16(p, viso->sector_size); /* logical block size */ /* Path table metadata is filled in later. */ - viso->pt_meta_offsets[i] = ftello64(viso->tf.file) + (p - data); + viso->pt_meta_offsets[i] = ftello64(viso->tf.fp) + (p - data); VISO_SKIP(p, 24 + (16 * !(viso->format & VISO_FORMAT_ISO))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */ - viso->root_dir->dr_offsets[i] = ftello64(viso->tf.file) + (p - data); + viso->root_dir->dr_offsets[i] = ftello64(viso->tf.fp) + (p - data); p += viso_fill_dir_record(p, viso->root_dir, viso, VISO_DIR_CURRENT); /* root directory */ int copyright_abstract_len = (viso->format & VISO_FORMAT_ISO) ? 37 : 32; @@ -1105,7 +1120,7 @@ viso_init(const char *dirname, int *error) memset(p, 0x00, viso->sector_size - (p - data)); /* Write volume descriptor. */ - fwrite(data, viso->sector_size, 1, viso->tf.file); + fwrite(data, viso->sector_size, 1, viso->tf.fp); /* Write El Torito boot descriptor. This is an awkward spot for that, but the spec requires it to be the second descriptor. */ @@ -1114,7 +1129,7 @@ viso_init(const char *dirname, int *error) p = data; if (!(viso->format & VISO_FORMAT_ISO)) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */ *p++ = 0; /* type */ memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; @@ -1125,20 +1140,20 @@ viso_init(const char *dirname, int *error) VISO_SKIP(p, 40); /* Save the boot catalog pointer's offset for later. */ - eltorito_offset = ftello64(viso->tf.file) + (p - data); + eltorito_offset = ftello64(viso->tf.fp) + (p - data); /* Blank the rest of the working sector. */ memset(p, 0x00, viso->sector_size - (p - data)); /* Write boot descriptor. */ - fwrite(data, viso->sector_size, 1, viso->tf.file); + fwrite(data, viso->sector_size, 1, viso->tf.fp); } } /* Fill terminator. */ p = data; if (!(viso->format & VISO_FORMAT_ISO)) - VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */ + VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */ *p++ = 0xff; /* type */ memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ p += 5; @@ -1148,22 +1163,22 @@ viso_init(const char *dirname, int *error) memset(p, 0x00, viso->sector_size - (p - data)); /* Write terminator. */ - fwrite(data, viso->sector_size, 1, viso->tf.file); + fwrite(data, viso->sector_size, 1, viso->tf.fp); /* We start seeing a pattern of padding to even sectors here. mkisofs does this, presumably for a very good reason... */ - int write = ftello64(viso->tf.file) % (viso->sector_size * 2); + int write = ftello64(viso->tf.fp) % (viso->sector_size * 2); if (write) { write = (viso->sector_size * 2) - write; memset(data, 0x00, write); - fwrite(data, write, 1, viso->tf.file); + fwrite(data, write, 1, viso->tf.fp); } /* Handle El Torito boot catalog. */ if (eltorito_entry) { /* Write a pointer to this boot catalog to the boot descriptor. */ - *((uint32_t *) data) = cpu_to_le32(ftello64(viso->tf.file) / viso->sector_size); - viso_pwrite(data, eltorito_offset, 4, 1, viso->tf.file); + *((uint32_t *) data) = cpu_to_le32(ftello64(viso->tf.fp) / viso->sector_size); + viso_pwrite(data, eltorito_offset, 4, 1, viso->tf.fp); /* Fill boot catalog validation entry. */ p = data; @@ -1193,21 +1208,21 @@ viso_init(const char *dirname, int *error) *p++ = 0x00; /* reserved */ /* Save offsets to the boot catalog entry's offset and size fields for later. */ - eltorito_offset = ftello64(viso->tf.file) + (p - data); + eltorito_offset = ftello64(viso->tf.fp) + (p - data); /* Blank the rest of the working sector. This includes the sector count, ISO sector offset and 20-byte selection criteria fields at the end. */ memset(p, 0x00, viso->sector_size - (p - data)); /* Write boot catalog. */ - fwrite(data, viso->sector_size, 1, viso->tf.file); + fwrite(data, viso->sector_size, 1, viso->tf.fp); /* Pad to the next even sector. */ - write = ftello64(viso->tf.file) % (viso->sector_size * 2); + write = ftello64(viso->tf.fp) % (viso->sector_size * 2); if (write) { write = (viso->sector_size * 2) - write; memset(data, 0x00, write); - fwrite(data, write, 1, viso->tf.file); + fwrite(data, write, 1, viso->tf.fp); } /* Flag that we shouldn't hide the boot code directory if it contains other files. */ @@ -1220,12 +1235,12 @@ viso_init(const char *dirname, int *error) cdrom_image_viso_log("VISO: Generating path table #%d:\n", i); /* Save this path table's start offset. */ - uint64_t pt_start = ftello64(viso->tf.file); + uint64_t pt_start = ftello64(viso->tf.fp); /* Write this table's sector offset to the corresponding volume descriptor. */ uint32_t pt_temp = pt_start / viso->sector_size; *((uint32_t *) data) = (i & 1) ? cpu_to_be32(pt_temp) : cpu_to_le32(pt_temp); - viso_pwrite(data, viso->pt_meta_offsets[i >> 1] + 8 + (8 * (i & 1)), 4, 1, viso->tf.file); + viso_pwrite(data, viso->pt_meta_offsets[i >> 1] + 8 + (8 * (i & 1)), 4, 1, viso->tf.fp); /* Go through directories. */ dir = viso->root_dir; @@ -1242,7 +1257,7 @@ viso_init(const char *dirname, int *error) /* Save this directory's path table index and offset. */ dir->pt_idx = pt_idx; - dir->pt_offsets[i] = ftello64(viso->tf.file); + dir->pt_offsets[i] = ftello64(viso->tf.fp); /* Fill path table entry. */ p = data; @@ -1278,7 +1293,7 @@ viso_init(const char *dirname, int *error) *p++ = 0x00; /* Write path table entry. */ - fwrite(data, p - data, 1, viso->tf.file); + fwrite(data, p - data, 1, viso->tf.fp); /* Increment path table index and stop if it overflows. */ if (++pt_idx == 0) @@ -1289,17 +1304,17 @@ viso_init(const char *dirname, int *error) } /* Write this table's size to the corresponding volume descriptor. */ - pt_temp = ftello64(viso->tf.file) - pt_start; + pt_temp = ftello64(viso->tf.fp) - pt_start; p = data; VISO_LBE_32(p, pt_temp); - viso_pwrite(data, viso->pt_meta_offsets[i >> 1], 8, 1, viso->tf.file); + viso_pwrite(data, viso->pt_meta_offsets[i >> 1], 8, 1, viso->tf.fp); /* Pad to the next even sector. */ - write = ftello64(viso->tf.file) % (viso->sector_size * 2); + write = ftello64(viso->tf.fp) % (viso->sector_size * 2); if (write) { write = (viso->sector_size * 2) - write; memset(data, 0x00, write); - fwrite(data, write, 1, viso->tf.file); + fwrite(data, write, 1, viso->tf.fp); } } @@ -1318,25 +1333,25 @@ viso_init(const char *dirname, int *error) } /* Pad to the next sector if required. */ - write = ftello64(viso->tf.file) % viso->sector_size; + write = ftello64(viso->tf.fp) % viso->sector_size; if (write) { write = viso->sector_size - write; memset(data, 0x00, write); - fwrite(data, write, 1, viso->tf.file); + fwrite(data, write, 1, viso->tf.fp); } /* Save this directory's child record array's start offset. */ - uint64_t dir_start = ftello64(viso->tf.file); + uint64_t dir_start = ftello64(viso->tf.fp); /* Write this directory's child record array's sector offset to its record... */ uint32_t dir_temp = dir_start / viso->sector_size; p = data; VISO_LBE_32(p, dir_temp); - viso_pwrite(data, dir->dr_offsets[i] + 2, 8, 1, viso->tf.file); + viso_pwrite(data, dir->dr_offsets[i] + 2, 8, 1, viso->tf.fp); /* ...and to its path table entries. */ - viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.file); /* little endian */ - viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.file); /* big endian */ + viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.fp); /* little endian */ + viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.fp); /* big endian */ if (i == max_vd) /* overwrite pt_offsets in the union if we no longer need them */ dir->file = NULL; @@ -1356,15 +1371,15 @@ viso_init(const char *dirname, int *error) viso_fill_dir_record(data, entry, viso, dir_type); /* Entries cannot cross sector boundaries, so pad to the next sector if needed. */ - write = viso->sector_size - (ftello64(viso->tf.file) % viso->sector_size); + write = viso->sector_size - (ftello64(viso->tf.fp) % viso->sector_size); if (write < data[0]) { p = data + (viso->sector_size * 2) - write; memset(p, 0x00, write); - fwrite(p, write, 1, viso->tf.file); + fwrite(p, write, 1, viso->tf.fp); } /* Save this entry's record's offset. This overwrites name_short in the union. */ - entry->dr_offsets[i] = ftello64(viso->tf.file); + entry->dr_offsets[i] = ftello64(viso->tf.fp); /* Write data related to the . and .. pseudo-subdirectories, while advancing the current directory type. */ @@ -1377,13 +1392,13 @@ viso_init(const char *dirname, int *error) } else if (dir_type == VISO_DIR_PARENT) { /* Copy the parent directory's offset and size. The root directory's parent size is a special, self-referential case handled later. */ - viso_pread(data + 2, dir->parent->dr_offsets[i] + 2, 16, 1, viso->tf.file); + viso_pread(data + 2, dir->parent->dr_offsets[i] + 2, 16, 1, viso->tf.fp); dir_type = i ? VISO_DIR_JOLIET : VISO_DIR_REGULAR; } /* Write entry. */ - fwrite(data, data[0], 1, viso->tf.file); + fwrite(data, data[0], 1, viso->tf.fp); next_entry: /* Move on to the next entry, and stop if the end of this directory was reached. */ entry = entry->next; @@ -1392,13 +1407,13 @@ viso_init(const char *dirname, int *error) } /* Write this directory's child record array's size to its parent and . records. */ - dir_temp = ftello64(viso->tf.file) - dir_start; + dir_temp = ftello64(viso->tf.fp) - dir_start; p = data; VISO_LBE_32(p, dir_temp); - viso_pwrite(data, dir->dr_offsets[i] + 10, 8, 1, viso->tf.file); - viso_pwrite(data, dir->first_child->dr_offsets[i] + 10, 8, 1, viso->tf.file); + viso_pwrite(data, dir->dr_offsets[i] + 10, 8, 1, viso->tf.fp); + viso_pwrite(data, dir->first_child->dr_offsets[i] + 10, 8, 1, viso->tf.fp); if (dir->parent == dir) /* write size to .. on root directory as well */ - viso_pwrite(data, dir->first_child->next->dr_offsets[i] + 10, 8, 1, viso->tf.file); + viso_pwrite(data, dir->first_child->next->dr_offsets[i] + 10, 8, 1, viso->tf.fp); /* Move on to the next directory. */ dir_type = VISO_DIR_CURRENT; @@ -1406,11 +1421,11 @@ viso_init(const char *dirname, int *error) } /* Pad to the next even sector. */ - write = ftello64(viso->tf.file) % (viso->sector_size * 2); + write = ftello64(viso->tf.fp) % (viso->sector_size * 2); if (write) { write = (viso->sector_size * 2) - write; memset(data, 0x00, write); - fwrite(data, write, 1, viso->tf.file); + fwrite(data, write, 1, viso->tf.fp); } } @@ -1448,13 +1463,13 @@ viso_init(const char *dirname, int *error) goto end; /* Pad metadata to the new size's next sector. */ - while (ftello64(viso->tf.file) % viso->sector_size) - fwrite(data, orig_sector_size, 1, viso->tf.file); + while (ftello64(viso->tf.fp) % viso->sector_size) + fwrite(data, orig_sector_size, 1, viso->tf.fp); } } /* Start sector counts. */ - viso->metadata_sectors = ftello64(viso->tf.file) / viso->sector_size; + viso->metadata_sectors = ftello64(viso->tf.fp) / viso->sector_size; viso->all_sectors = viso->metadata_sectors; /* Go through files, assigning sectors to them. */ @@ -1488,12 +1503,12 @@ viso_init(const char *dirname, int *error) *((uint16_t *) &data[0]) = cpu_to_le16(1); } *((uint32_t *) &data[2]) = cpu_to_le32(viso->all_sectors * base_factor); - viso_pwrite(data, eltorito_offset, 6, 1, viso->tf.file); + viso_pwrite(data, eltorito_offset, 6, 1, viso->tf.fp); } else { p = data; VISO_LBE_32(p, viso->all_sectors * base_factor); for (int i = 0; i <= max_vd; i++) - viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.file); + viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.fp); } /* Save this file's base offset. This overwrites dr_offsets in the union. */ @@ -1519,22 +1534,22 @@ viso_init(const char *dirname, int *error) p = data; VISO_LBE_32(p, viso->all_sectors); for (int i = 0; i < (sizeof(viso->vol_size_offsets) / sizeof(viso->vol_size_offsets[0])); i++) - viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.file); + viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp); /* Metadata processing is finished, read it back to memory. */ cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size); viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size); if (!viso->metadata) goto end; - fseeko64(viso->tf.file, 0, SEEK_SET); + fseeko64(viso->tf.fp, 0, SEEK_SET); uint64_t metadata_size = viso->metadata_sectors * viso->sector_size; uint64_t metadata_remain = metadata_size; while (metadata_remain > 0) - metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.file); + metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.fp); /* We no longer need the temporary file; close and delete it. */ - fclose(viso->tf.file); - viso->tf.file = NULL; + fclose(viso->tf.fp); + viso->tf.fp = NULL; #ifndef ENABLE_CDROM_IMAGE_VISO_LOG remove(nvr_path(viso->tf.fn)); #endif diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index e7e12bb949..7f4d2645ba 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -33,6 +33,10 @@ #include <86box/plat.h> #include <86box/sound.h> +#define MCD_DEFAULT_IOPORT 0x310 +#define MCD_DEFAULT_IRQ 5 +#define MCD_DEFAULT_DMA 5 + #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 @@ -86,8 +90,9 @@ enum { IRQ_ERROR = 4 }; -typedef struct { - int dma, irq; +typedef struct mcd_t { + int dma; + int irq; int change; int data; uint8_t stat; @@ -116,7 +121,9 @@ typedef struct { /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#ifdef MSFtoLBA #undef MSFtoLBA +#endif #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) #define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4)) @@ -242,9 +249,13 @@ mitsumi_cdrom_in(uint16_t port, void *priv) ret |= FLAG_NOSTAT; pclog("Read port 1: ret = %02x\n", ret | FLAG_UNK); return ret | FLAG_UNK; + case 2: + break; + default: + break; } - return (0xff); + return 0xff; } static void @@ -283,6 +294,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) case 0x10: dev->enable_irq = val; break; + default: + break; } dev->cmdbuf[1] = 0; dev->cmdbuf_count = 2; @@ -297,6 +310,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) if (dev->conf == 1) dev->cmdrd_count++; break; + default: + break; } break; case CMD_READ1X: @@ -316,12 +331,17 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case 5: dev->readmsf = 0; + fallthrough; case 4: case 3: dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3); break; + default: + break; } break; + default: + break; } if (!dev->cmdrd_count) dev->stat = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; @@ -381,10 +401,10 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) } break; case CMD_GET_VER: - dev->cmdbuf[1] = 1; - dev->cmdbuf[2] = 'D'; - dev->cmdbuf[3] = 0; - dev->cmdbuf_count = 4; + dev->cmdbuf[0] = 1; + dev->cmdbuf[1] = 'D'; + dev->cmdbuf[2] = 0; + dev->cmdbuf_count = 3; break; case CMD_EJECT: cdrom_stop(&cdrom); @@ -406,21 +426,25 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) case 1: mitsumi_cdrom_reset(dev); break; + case 2: + break; + default: + break; } } static void * -mitsumi_cdrom_init(const device_t *info) +mitsumi_cdrom_init(UNUSED(const device_t *info)) { mcd_t *dev; dev = malloc(sizeof(mcd_t)); memset(dev, 0x00, sizeof(mcd_t)); - dev->irq = 5; - dev->dma = 5; + dev->irq = MCD_DEFAULT_IRQ; + dev->dma = MCD_DEFAULT_DMA; - io_sethandler(0x310, 2, + io_sethandler(MCD_DEFAULT_IOPORT, 3, mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev); mitsumi_cdrom_reset(dev); diff --git a/src/chipset/82c100.c b/src/chipset/82c100.c index 4d75ca3871..689234ebb0 100644 --- a/src/chipset/82c100.c +++ b/src/chipset/82c100.c @@ -28,23 +28,24 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/nmi.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/rom.h> #include <86box/chipset.h> -typedef struct -{ +typedef struct ems_page_t { int enabled; - uint32_t virt, phys; + uint32_t virt; + uint32_t phys; } ems_page_t; -typedef struct -{ - uint8_t index, access; - uint16_t ems_io_base; - uint32_t ems_window_base; - uint8_t ems_page_regs[4], - regs[256]; +typedef struct ct_82c100_t { + uint8_t index; + uint8_t access; + uint16_t ems_io_base; + uint32_t ems_window_base; + uint8_t ems_page_regs[4]; + uint8_t regs[256]; ems_page_t ems_pages[4]; mem_mapping_t ems_mappings[4]; } ct_82c100_t; @@ -108,7 +109,7 @@ ct_82c100_ems_out(uint16_t port, uint8_t val, void *priv) static uint8_t ct_82c100_ems_in(uint16_t port, void *priv) { - ct_82c100_t *dev = (ct_82c100_t *) priv; + const ct_82c100_t *dev = (ct_82c100_t *) priv; uint8_t ret = 0xff; ret = dev->ems_page_regs[port >> 14]; @@ -119,9 +120,7 @@ ct_82c100_ems_in(uint16_t port, void *priv) static void ct_82c100_ems_update(ct_82c100_t *dev) { - int i; - - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { ct_82c100_log("Disabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14)); io_handler(0, dev->ems_io_base + (i << 14), 1, ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev); @@ -129,7 +128,7 @@ ct_82c100_ems_update(ct_82c100_t *dev) dev->ems_io_base = 0x0208 + (dev->regs[0x4c] & 0xf0); - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { ct_82c100_log("Enabling EMS I/O handler %i at %04X\n", i, dev->ems_io_base + (i << 14)); io_handler(1, dev->ems_io_base + (i << 14), 1, ct_82c100_ems_in, NULL, NULL, ct_82c100_ems_out, NULL, NULL, dev); @@ -221,6 +220,9 @@ ct_82c100_out(uint16_t port, uint8_t val, void *priv) dev->regs[0x4c] = val; ct_82c100_ems_update(dev); break; + + default: + break; } dev->access = 0; } @@ -257,6 +259,9 @@ ct_82c100_in(uint16_t port, void *priv) case 0x4c: ret = dev->regs[dev->index]; break; + + default: + break; } dev->access = 0; } @@ -273,15 +278,15 @@ ct_82c100_in(uint16_t port, void *priv) static uint8_t mem_read_emsb(uint32_t addr, void *priv) { - ems_page_t *page = (ems_page_t *) priv; - uint8_t ret = 0xff; + const ems_page_t *page = (ems_page_t *) priv; + uint8_t ret = 0xff; #ifdef ENABLE_CT_82C100_LOG uint32_t old_addr = addr; #endif addr = addr - page->virt + page->phys; - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ret = ram[addr]; ct_82c100_log("mem_read_emsb(%08X = %08X): %02X\n", old_addr, addr, ret); @@ -292,7 +297,7 @@ mem_read_emsb(uint32_t addr, void *priv) static uint16_t mem_read_emsw(uint32_t addr, void *priv) { - ems_page_t *page = (ems_page_t *) priv; + const ems_page_t *page = (ems_page_t *) priv; uint16_t ret = 0xffff; #ifdef ENABLE_CT_82C100_LOG uint32_t old_addr = addr; @@ -300,7 +305,7 @@ mem_read_emsw(uint32_t addr, void *priv) addr = addr - page->virt + page->phys; - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ret = *(uint16_t *) &ram[addr]; ct_82c100_log("mem_read_emsw(%08X = %08X): %04X\n", old_addr, addr, ret); @@ -311,14 +316,14 @@ mem_read_emsw(uint32_t addr, void *priv) static void mem_write_emsb(uint32_t addr, uint8_t val, void *priv) { - ems_page_t *page = (ems_page_t *) priv; + const ems_page_t *page = (ems_page_t *) priv; #ifdef ENABLE_CT_82C100_LOG uint32_t old_addr = addr; #endif addr = addr - page->virt + page->phys; - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ram[addr] = val; ct_82c100_log("mem_write_emsb(%08X = %08X, %02X)\n", old_addr, addr, val); @@ -327,14 +332,14 @@ mem_write_emsb(uint32_t addr, uint8_t val, void *priv) static void mem_write_emsw(uint32_t addr, uint16_t val, void *priv) { - ems_page_t *page = (ems_page_t *) priv; + const ems_page_t *page = (ems_page_t *) priv; #ifdef ENABLE_CT_82C100_LOG uint32_t old_addr = addr; #endif addr = addr - page->virt + page->phys; - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) *(uint16_t *) &ram[addr] = val; ct_82c100_log("mem_write_emsw(%08X = %08X, %04X)\n", old_addr, addr, val); @@ -349,7 +354,7 @@ ct_82c100_close(void *priv) } static void * -ct_82c100_init(const device_t *info) +ct_82c100_init(UNUSED(const device_t *info)) { ct_82c100_t *dev; diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0a6a5fbe5a..0406ea0b89 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -13,13 +13,16 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c - ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c - intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c - opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c - sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c - via_pipc.c vl82c480.c wd76c10.c) +add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c + ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c + compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c + intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c + opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c + sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c + sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c + via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c + umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 7659136723..9ce29bdff7 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -30,6 +30,7 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/port_92.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> #define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) @@ -57,20 +58,21 @@ acc2168_log(const char *fmt, ...) #endif typedef struct acc2168_t { - uint8_t reg_idx, regs[256]; + uint8_t reg_idx; + uint8_t regs[256]; } acc2168_t; static void acc2168_shadow_recalc(acc2168_t *dev) { - for (uint32_t i = 0; i < 5; i++) + for (uint8_t i = 0; i < 5; i++) mem_set_mem_state_both(SHADOW_ADDR, SHADOW_SIZE, SHADOW_RECALC); } static void -acc2168_write(uint16_t addr, uint8_t val, void *p) +acc2168_write(uint16_t addr, uint8_t val, void *priv) { - acc2168_t *dev = (acc2168_t *) p; + acc2168_t *dev = (acc2168_t *) priv; switch (addr) { case 0xf2: @@ -158,13 +160,15 @@ acc2168_write(uint16_t addr, uint8_t val, void *p) break; } break; + default: + break; } } static uint8_t -acc2168_read(uint16_t addr, void *p) +acc2168_read(uint16_t addr, void *priv) { - acc2168_t *dev = (acc2168_t *) p; + const acc2168_t *dev = (acc2168_t *) priv; return (addr == 0xf3) ? dev->regs[dev->reg_idx] : dev->reg_idx; } @@ -178,7 +182,7 @@ acc2168_close(void *priv) } static void * -acc2168_init(const device_t *info) +acc2168_init(UNUSED(const device_t *info)) { acc2168_t *dev = (acc2168_t *) malloc(sizeof(acc2168_t)); memset(dev, 0, sizeof(acc2168_t)); diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index e245603a9e..34c3e18c23 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -115,10 +115,12 @@ ali1429_log(const char *fmt, ...) # define ali1429_log(fmt, ...) #endif -typedef struct -{ - uint8_t is_g, index, cfg_locked, reg_57h, - regs[90]; +typedef struct ali_1429_t { + uint8_t is_g; + uint8_t index; + uint8_t cfg_locked; + uint8_t reg_57h; + uint8_t regs[90]; } ali1429_t; static void @@ -239,12 +241,16 @@ ali1429_write(uint16_t addr, uint8_t val, void *priv) case 6: cpu_set_isa_speed(cpu_busspeed / 12); break; + default: + break; } break; case 0x21 ... 0x27: dev->regs[dev->index] = val; break; + default: + break; } /* M1429G Only Registers */ @@ -260,18 +266,22 @@ ali1429_write(uint16_t addr, uint8_t val, void *priv) case 0x57: dev->reg_57h = val; break; + default: + break; } } } break; + default: + break; } } static uint8_t ali1429_read(uint16_t addr, void *priv) { - ali1429_t *dev = (ali1429_t *) priv; - uint8_t ret = 0xff; + const ali1429_t *dev = (ali1429_t *) priv; + uint8_t ret = 0xff; if ((addr == 0x23) && (dev->index >= 0x10) && (dev->index <= 0x4a)) ret = dev->regs[dev->index]; diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index c80611e1b0..9476d2b451 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -31,6 +31,7 @@ #include <86box/timer.h> #include <86box/pic.h> #include <86box/pit.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/hdc.h> @@ -42,13 +43,15 @@ #define MEM_STATE_SHADOW_W 0x02 #define MEM_STATE_SMRAM 0x04 -typedef struct -{ - uint8_t index, cfg_locked, - regs[16], pci_regs[256]; +typedef struct ali_1435_t { + uint8_t index; + uint8_t cfg_locked; + uint8_t pci_slot; + uint8_t pad; + uint8_t regs[16]; + uint8_t pci_regs[256]; } ali1435_t; -#define ENABLE_ALI1435_LOG 1 #ifdef ENABLE_ALI1435_LOG int ali1435_do_log = ENABLE_ALI1435_LOG; @@ -164,8 +167,8 @@ 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_t *dev = (ali1435_t *) priv; - uint8_t ret; + const ali1435_t *dev = (ali1435_t *) priv; + uint8_t ret; ret = 0xff; @@ -188,23 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv) break; case 0x23: - /* #ifdef ENABLE_ALI1435_LOG - if (dev->index != 0x03) - ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val); - #endif */ - if (dev->index == 0x03) dev->cfg_locked = (val != 0x69); +#ifdef ENABLE_ALI1435_LOG + else + ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val); +#endif if (!dev->cfg_locked) { - pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val); - switch (dev->index) { /* PCI Mechanism select? */ case 0x00: dev->regs[dev->index] = val; - pclog("PMC = %i\n", val != 0xc8); - pci_set_pmc(val != 0xc8); + ali1435_log("PMC = %i\n", val != 0xc8); + pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00); break; /* ???? */ @@ -216,17 +216,22 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv) case 0x07: dev->regs[dev->index] = val; break; + + default: + break; } } break; + default: + break; } } static uint8_t ali1435_read(uint16_t addr, void *priv) { - ali1435_t *dev = (ali1435_t *) priv; - uint8_t ret = 0xff; + const ali1435_t *dev = (ali1435_t *) priv; + uint8_t ret = 0xff; if ((addr == 0x23) && (dev->index < 0x10)) ret = dev->regs[dev->index]; @@ -245,8 +250,6 @@ ali1435_reset(void *priv) dev->regs[0x00] = 0xff; - pci_set_pmc(0); - dev->cfg_locked = 1; memset(dev->pci_regs, 0, 256); @@ -269,15 +272,15 @@ ali1435_reset(void *priv) } static void -ali1435_close(void *p) +ali1435_close(void *priv) { - ali1435_t *dev = (ali1435_t *) p; + ali1435_t *dev = (ali1435_t *) priv; free(dev); } static void * -ali1435_init(const device_t *info) +ali1435_init(UNUSED(const device_t *info)) { ali1435_t *dev = (ali1435_t *) malloc(sizeof(ali1435_t)); memset(dev, 0, sizeof(ali1435_t)); @@ -290,15 +293,10 @@ ali1435_init(const device_t *info) */ io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot); ali1435_reset(dev); - /* pci_set_irq_level(PCI_INTA, 0); - pci_set_irq_level(PCI_INTB, 0); - pci_set_irq_level(PCI_INTC, 0); - pci_set_irq_level(PCI_INTD, 0); */ - return dev; } diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index c7139612ad..3550f1da6d 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -35,12 +35,14 @@ #include <86box/nmi.h> #include <86box/pic.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/smram.h> #include <86box/chipset.h> -#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) +#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | \ + ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) #define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) #ifdef ENABLE_ALI1489_LOG @@ -61,28 +63,26 @@ ali1489_log(const char *fmt, ...) # define ali1489_log(fmt, ...) #endif -typedef struct -{ - uint8_t index, ide_index, ide_chip_id, pci_slot, - regs[256], pci_conf[256], ide_regs[256]; +typedef struct ali1489_t { + uint8_t index; + uint8_t pci_slot; + uint8_t regs[256]; + uint8_t pci_conf[256]; port_92_t *port_92; smram_t *smram; } ali1489_t; -static void ali1489_ide_handler(ali1489_t *dev); - static void ali1489_shadow_recalc(ali1489_t *dev) { - uint32_t i; - shadowbios = shadowbios_write = 0; - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (dev->regs[0x13] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xc0000 + (i << 14), 0xc3fff + (i << 14), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE); } else { ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14)); @@ -90,10 +90,11 @@ ali1489_shadow_recalc(ali1489_t *dev) } } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { if (dev->regs[0x14] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xe0000 + (i << 15), 0xe7fff + (i << 15), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE); shadowbios |= !!(dev->regs[0x14] & 0x10); shadowbios_write |= !!(dev->regs[0x14] & 0x20); @@ -126,6 +127,8 @@ ali1489_smram_recalc(ali1489_t *dev) else smram_enable(dev->smram, 0x38000, 0xa8000, 0x08000, (dev->regs[0x19] & 0x08), 1); break; + default: + break; } if ((dev->regs[0x19] & 0x31) == 0x11) { @@ -137,25 +140,9 @@ ali1489_smram_recalc(ali1489_t *dev) static void ali1489_defaults(ali1489_t *dev) { - memset(dev->ide_regs, 0x00, 256); memset(dev->pci_conf, 0x00, 256); memset(dev->regs, 0x00, 256); - ide_pri_disable(); - ide_sec_disable(); - - /* IDE registers */ - dev->ide_regs[0x00] = 0x57; - dev->ide_regs[0x01] = 0x02; - dev->ide_regs[0x08] = 0xff; - dev->ide_regs[0x09] = 0x41; - dev->ide_regs[0x0c] = 0x02; - dev->ide_regs[0x0e] = 0x02; - dev->ide_regs[0x10] = 0x02; - dev->ide_regs[0x12] = 0x02; - dev->ide_regs[0x34] = 0xff; - dev->ide_regs[0x35] = 0x01; - /* PCI registers */ dev->pci_conf[0x00] = 0xb9; dev->pci_conf[0x01] = 0x10; @@ -198,8 +185,6 @@ ali1489_defaults(ali1489_t *dev) pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - ali1489_ide_handler(dev); } static void @@ -208,7 +193,7 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) ali1489_t *dev = (ali1489_t *) priv; uint8_t old; uint8_t irq; - const uint8_t irq_array[16] = { 0, 3, 4, 7, 0, 0, 0, 0, 9, 10, 5, 6, 11, 12, 14, 15 }; + const uint8_t irq_array[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15 }; switch (addr) { case 0x22: @@ -320,6 +305,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) case 0x30: picint(1 << 10); break; + default: + break; } dev->regs[0x35] |= 0x0e; } else if (!(val & 0x10)) @@ -378,9 +365,12 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) break; case 0x44: /* PCI INTx Sensitivity Register */ - /* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */ + /* TODO: When doing the IRQ and PCI IRQ rewrite, + bits 0 to 3 toggle edge/level output. */ dev->regs[dev->index] = val; break; + default: + break; } if (dev->index != 0x03) { @@ -390,14 +380,17 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = val; break; + + default: + break; } } static uint8_t ali1489_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - ali1489_t *dev = (ali1489_t *) priv; + uint8_t ret = 0xff; + const ali1489_t *dev = (ali1489_t *) priv; switch (addr) { case 0x23: @@ -409,6 +402,8 @@ ali1489_read(uint16_t addr, void *priv) else ret = dev->regs[dev->index]; break; + default: + break; } ali1489_log("M1489: dev->regs[%02x] (%02x)\n", dev->index, ret); @@ -417,7 +412,7 @@ ali1489_read(uint16_t addr, void *priv) } static void -ali1489_pci_write(int func, int addr, uint8_t val, void *priv) +ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { ali1489_t *dev = (ali1489_t *) priv; @@ -433,123 +428,20 @@ ali1489_pci_write(int func, int addr, uint8_t val, void *priv) case 0x07: dev->pci_conf[0x07] &= ~(val & 0xb8); break; - } -} - -static uint8_t -ali1489_pci_read(int func, int addr, void *priv) -{ - ali1489_t *dev = (ali1489_t *) priv; - uint8_t ret = 0xff; - - ret = dev->pci_conf[addr]; - ali1489_log("M1489-PCI: dev->pci_conf[%02x] (%02x)\n", addr, ret); - return ret; -} - -static void -ali1489_ide_handler(ali1489_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->ide_regs[0x01] & 0x01) { - ide_pri_enable(); - if (!(dev->ide_regs[0x35] & 0x40)) - ide_sec_enable(); - } -} - -static void -ali1489_ide_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1489_t *dev = (ali1489_t *) priv; - - switch (addr) { - case 0xf4: /* Usually it writes 30h here */ - dev->ide_chip_id = val; - break; - case 0xf8: - dev->ide_index = val; - break; - - case 0xfc: - if (dev->ide_chip_id != 0x30) - break; - - switch (dev->ide_index) { - case 0x01: /* IDE Configuration Register */ - dev->ide_regs[dev->ide_index] = val & 0x8f; - ali1489_ide_handler(dev); - break; - case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ - case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ - case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ - case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ - case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ - case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ - case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ - case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ - case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ - case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ - case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ - case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ - case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ - case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ - case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ - case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ - case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ - case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ - case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ - case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x07: /* Buffer Mode Register 1 */ - dev->ide_regs[dev->ide_index] = val; - break; - case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0xc3; - break; - case 0x0a: /* Buffer Mode Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x4f; - break; - case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ - case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ - case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ - case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0x03; - break; - case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ - case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ - case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ - dev->ide_regs[dev->ide_index] = val; - ali1489_ide_handler(dev); - break; - } + default: break; } } static uint8_t -ali1489_ide_read(uint16_t addr, void *priv) +ali1489_pci_read(UNUSED(int func), int addr, void *priv) { - ali1489_t *dev = (ali1489_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0xf4: - ret = dev->ide_chip_id; - break; - case 0xfc: - ret = dev->ide_regs[dev->ide_index]; - ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret); - break; - } + const ali1489_t *dev = (ali1489_t *) priv; + uint8_t ret = 0xff; + ret = dev->pci_conf[addr]; + ali1489_log("M1489-PCI: dev->pci_conf[%02x] (%02x)\n", addr, ret); return ret; } @@ -576,7 +468,7 @@ ali1489_close(void *priv) } static void * -ali1489_init(const device_t *info) +ali1489_init(UNUSED(const device_t *info)) { ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t)); memset(dev, 0, sizeof(ali1489_t)); @@ -586,19 +478,10 @@ ali1489_init(const device_t *info) 23h Data Port */ io_sethandler(0x0022, 0x0002, ali1489_read, NULL, NULL, ali1489_write, NULL, NULL, dev); - /* M1489 IDE controller - F4h Chip ID we write always 30h onto it - F8h Index Port - FCh Data Port - */ - io_sethandler(0x0f4, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0f8, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - /* Dummy M1489 PCI device */ - dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot); - device_add(&ide_pci_2ch_device); + device_add(&ide_ali1489_device); dev->port_92 = device_add(&port_92_pci_device); dev->smram = smram_add(); diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 8d83587311..9eb75f7cda 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -28,12 +28,18 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/smram.h> #include <86box/spd.h> #include <86box/chipset.h> typedef struct ali1531_t { + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t pci_conf[256]; smram_t *smram; @@ -82,6 +88,9 @@ ali1531_smram_recalc(uint8_t val, ali1531_t *dev) if (val & 0x10) mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02); break; + + default: + break; } } @@ -89,7 +98,7 @@ ali1531_smram_recalc(uint8_t val, ali1531_t *dev) } static void -ali1531_shadow_recalc(int cur_reg, ali1531_t *dev) +ali1531_shadow_recalc(UNUSED(int cur_reg), ali1531_t *dev) { int bit; int r_reg; @@ -124,7 +133,7 @@ ali1531_shadow_recalc(int cur_reg, ali1531_t *dev) } static void -ali1531_write(int func, int addr, uint8_t val, void *priv) +ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) { ali1531_t *dev = (ali1531_t *) priv; @@ -228,8 +237,10 @@ ali1531_write(int func, int addr, uint8_t val, void *priv) case 0x57: /* H2PO */ dev->pci_conf[addr] = val & 0x60; /* Find where the Shut-down Special cycle is initiated. */ - // if (!(val & 0x20)) - // outb(0x92, 0x01); +#if 0 + if (!(val & 0x20)) + outb(0x92, 0x01); +#endif break; case 0x58: @@ -288,14 +299,17 @@ ali1531_write(int func, int addr, uint8_t val, void *priv) case 0x83: dev->pci_conf[addr] = val & 0x10; break; + + default: + break; } } static uint8_t -ali1531_read(int func, int addr, void *priv) +ali1531_read(UNUSED(int func), int addr, void *priv) { - ali1531_t *dev = (ali1531_t *) priv; - uint8_t ret = 0xff; + const ali1531_t *dev = (ali1531_t *) priv; + uint8_t ret = 0xff; ret = dev->pci_conf[addr]; @@ -306,7 +320,6 @@ static void ali1531_reset(void *priv) { ali1531_t *dev = (ali1531_t *) priv; - int i; /* Default Registers */ dev->pci_conf[0x00] = 0xb9; @@ -342,10 +355,10 @@ ali1531_reset(void *priv) ali1531_write(0, 0x47, 0x00, dev); ali1531_write(0, 0x48, 0x00, dev); - for (i = 0; i < 4; i++) + for (uint8_t i = 0; i < 4; i++) ali1531_write(0, 0x4c + i, 0x00, dev); - for (i = 0; i < 16; i += 2) { + for (uint8_t i = 0; i < 16; i += 2) { ali1531_write(0, 0x60 + i, 0x08, dev); ali1531_write(0, 0x61 + i, 0x40, dev); } @@ -361,12 +374,12 @@ ali1531_close(void *priv) } static void * -ali1531_init(const device_t *info) +ali1531_init(UNUSED(const device_t *info)) { ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t)); memset(dev, 0, sizeof(ali1531_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot); dev->smram = smram_add(); diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index 509bb95f2a..d57ef51e7b 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -28,12 +28,18 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/smram.h> #include <86box/spd.h> #include <86box/chipset.h> typedef struct ali1541_t { + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t pci_conf[256]; smram_t *smram; @@ -83,6 +89,8 @@ ali1541_smram_recalc(uint8_t val, ali1541_t *dev) if (val & 0x10) mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02); break; + default: + break; } } @@ -90,7 +98,7 @@ ali1541_smram_recalc(uint8_t val, ali1541_t *dev) } static void -ali1541_shadow_recalc(int cur_reg, ali1541_t *dev) +ali1541_shadow_recalc(UNUSED(int cur_reg), ali1541_t *dev) { int bit; int r_reg; @@ -131,8 +139,8 @@ ali1541_mask_bar(ali1541_t *dev) uint32_t mask; switch (dev->pci_conf[0xbc] & 0x0f) { - case 0x00: default: + case 0x00: mask = 0x00000000; break; case 0x01: @@ -170,7 +178,7 @@ ali1541_mask_bar(ali1541_t *dev) } static void -ali1541_write(int func, int addr, uint8_t val, void *priv) +ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv) { ali1541_t *dev = (ali1541_t *) priv; @@ -367,8 +375,10 @@ ali1541_write(int func, int addr, uint8_t val, void *priv) case 0x87: /* H2PO */ dev->pci_conf[addr] = val; /* Find where the Shut-down Special cycle is initiated. */ - // if (!(val & 0x20)) - // outb(0x92, 0x01); +#if 0 + if (!(val & 0x20)) + outb(0x92, 0x01); +#endif break; case 0x88: @@ -546,14 +556,17 @@ ali1541_write(int func, int addr, uint8_t val, void *priv) case 0xf7: dev->pci_conf[addr] = val & 0x43; break; + + default: + break; } } static uint8_t -ali1541_read(int func, int addr, void *priv) +ali1541_read(UNUSED(int func), int addr, void *priv) { - ali1541_t *dev = (ali1541_t *) priv; - uint8_t ret = 0xff; + const ali1541_t *dev = (ali1541_t *) priv; + uint8_t ret = 0xff; ret = dev->pci_conf[addr]; @@ -564,7 +577,6 @@ static void ali1541_reset(void *priv) { ali1541_t *dev = (ali1541_t *) priv; - int i; /* Default Registers */ dev->pci_conf[0x00] = 0xb9; @@ -607,12 +619,13 @@ ali1541_reset(void *priv) ali1541_write(0, 0x54, 0x00, dev); ali1541_write(0, 0x55, 0x00, dev); - for (i = 0; i < 4; i++) + for (uint8_t i = 0; i < 4; i++) ali1541_write(0, 0x56 + i, 0x00, dev); - ali1541_write(0, 0x60 + i, 0x07, dev); - ali1541_write(0, 0x61 + i, 0x40, dev); - for (i = 0; i < 14; i += 2) { + ali1541_write(0, 0x60, 0x07, dev); + ali1541_write(0, 0x61, 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); } @@ -628,12 +641,12 @@ ali1541_close(void *priv) } static void * -ali1541_init(const device_t *info) +ali1541_init(UNUSED(const device_t *info)) { ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t)); memset(dev, 0, sizeof(ali1541_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot); dev->smram = smram_add(); diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index fcad2486a5..fe3a0fda31 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -36,6 +36,7 @@ #include <86box/nvr.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/sio.h> #include <86box/smbus.h> @@ -46,10 +47,20 @@ #include <86box/chipset.h> typedef struct ali1543_t { - uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256], - pci_slot, ide_slot, usb_slot, pmu_slot, usb_dev_enable, ide_dev_enable, - pmu_dev_enable, type; - int offset; + uint8_t mirq_states[8]; + uint8_t pci_conf[256]; + uint8_t pmu_conf[256]; + uint8_t usb_conf[256]; + uint8_t ide_conf[256]; + uint8_t pci_slot; + uint8_t ide_slot; + uint8_t usb_slot; + uint8_t pmu_slot; + uint8_t usb_dev_enable; + uint8_t ide_dev_enable; + uint8_t pmu_dev_enable; + uint8_t type; + int offset; apm_t *apm; acpi_t *acpi; @@ -59,7 +70,6 @@ typedef struct ali1543_t { sff8038i_t *ide_controller[2]; smbus_ali7101_t *smbus; usb_t *usb; - usb_params_t usb_params; } ali1543_t; @@ -95,7 +105,7 @@ ali1543_log(const char *fmt, ...) #endif static void -ali1533_ddma_handler(ali1543_t *dev) +ali1533_ddma_handler(UNUSED(ali1543_t *dev)) { /* TODO: Find any documentation that actually explains the ALi southbridge DDMA mapping. */ } @@ -168,6 +178,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 6: cpu_set_isa_pci_div((val & 7) + 1); break; + default: + break; } break; @@ -185,8 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0xdf; soft_reset_pci = !!(val & 0x80); - sff_set_irq_level(dev->ide_controller[0], 0, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 0, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10)); ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ2, ali1533_irq_routing[val & 0x0f]); @@ -227,8 +238,10 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val; ali1543_log("SIRQI = IRQ %i; SIRQII = IRQ %i\n", ali1533_irq_routing[(val >> 4) & 0x0f], ali1533_irq_routing[val & 0x0f]); - // pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[(val >> 4) & 0x0f]); - // pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); +#if 0 + pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[(val >> 4) & 0x0f]); + pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); +#endif } break; @@ -293,6 +306,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x30: dev->ide_slot = 0x0d; /* A24 = slot 13 */ break; + default: + break; } pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_IDE, ((int) dev->ide_slot) + dev->offset); ali1543_log("IDE slot = %02X (A%0i)\n", ((int) dev->ide_slot) + dev->offset, dev->ide_slot + 11); @@ -364,6 +379,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x0c: dev->pmu_slot = 0x04; /* A15 = slot 04 */ break; + default: + break; } pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_PMU, ((int) dev->pmu_slot) + dev->offset); ali1543_log("PMU slot = %02X (A%0i)\n", ((int) dev->pmu_slot) + dev->offset, dev->pmu_slot + 11); @@ -380,6 +397,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x03: dev->usb_slot = 0x01; /* A12 = slot 01 */ break; + default: + break; } pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_USB, ((int) dev->usb_slot) + dev->offset); ali1543_log("USB slot = %02X (A%0i)\n", ((int) dev->usb_slot) + dev->offset, dev->usb_slot + 11); @@ -398,8 +417,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0x1f; - sff_set_irq_level(dev->ide_controller[0], 1, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 1, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10)); ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ3, ali1533_irq_routing[val & 0x0f]); @@ -437,6 +455,9 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->pmu_dev_enable = 0; } break; + + default: + break; } } @@ -468,46 +489,42 @@ static void ali5229_ide_irq_handler(ali1543_t *dev) { int ctl = 0; - int ch = 0; int bit = 0; if (dev->ide_conf[0x52] & 0x10) { ctl ^= 1; - ch ^= 1; bit ^= 5; } if (dev->ide_conf[0x09] & (1 ^ bit)) { /* Primary IDE is native. */ ali1543_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN); } else { /* Primary IDE is legacy. */ switch (dev->pci_conf[0x58] & 0x03) { case 0x00: /* SIRQI, SIRQII */ ali1543_log("Primary IDE IRQ mode: SIRQI, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0); break; case 0x01: /* IRQ14, IRQ15 */ ali1543_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY); break; case 0x02: /* IRQ14, SIRQII */ ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY); break; case 0x03: /* IRQ14, SIRQI */ ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQI\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY); + break; + + default: break; } } @@ -517,34 +534,32 @@ ali5229_ide_irq_handler(ali1543_t *dev) if (dev->ide_conf[0x09] & (4 ^ bit)) { /* Secondary IDE is native. */ ali1543_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN); } else { /* Secondary IDE is legacy. */ switch (dev->pci_conf[0x58] & 0x03) { case 0x00: /* SIRQI, SIRQII */ ali1543_log("Secondary IDE IRQ mode: SIRQI, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0); break; case 0x01: /* IRQ14, IRQ15 */ ali1543_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY); break; case 0x02: /* IRQ14, SIRQII */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY); break; case 0x03: /* IRQ14, SIRQI */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQI\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY); + break; + + default: break; } } @@ -607,7 +622,6 @@ ali5229_ide_handler(ali1543_t *dev) ali1543_log("ali5229_ide_handler(): Enabling primary IDE...\n"); ide_pri_enable(); - sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch)); ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); } @@ -621,13 +635,14 @@ ali5229_ide_handler(ali1543_t *dev) ali1543_log("ali5229_ide_handler(): Enabling secondary IDE...\n"); ide_sec_enable(); - sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch)); ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); } - } else { - sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); } + + sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, + ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch)); + sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, + ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch)); } static void @@ -693,8 +708,8 @@ ali5229_chip_reset(ali1543_t *dev) sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); - sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + sff_bus_master_reset(dev->ide_controller[0]); + sff_bus_master_reset(dev->ide_controller[1]); ali5229_ide_handler(dev); } @@ -815,8 +830,8 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) if (val & 0x80) ali5229_chip_reset(dev); else if (val & 0x40) { - sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + sff_bus_master_reset(dev->ide_controller[0]); + sff_bus_master_reset(dev->ide_controller[1]); } break; @@ -857,13 +872,16 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) case 0x5f: dev->ide_conf[addr] = val & 0x7f; break; + + default: + break; } } static uint8_t ali5229_read(int func, int addr, void *priv) { - ali1543_t *dev = (ali1543_t *) priv; + const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; if (dev->ide_dev_enable && (func == 0)) { @@ -942,13 +960,16 @@ ali5237_write(int func, int addr, uint8_t val, void *priv) if (!(dev->usb_conf[0x42] & 0x10)) dev->usb_conf[addr] = val; break; + + default: + break; } } static uint8_t ali5237_read(int func, int addr, void *priv) { - ali1543_t *dev = (ali1543_t *) priv; + const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; if (dev->usb_dev_enable && (func == 0)) @@ -961,7 +982,7 @@ static void ali7101_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; - ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); + ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val); if (func > 0) return; @@ -1033,7 +1054,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) case 0x40: dev->pmu_conf[addr] = val & 0x1f; - pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); + nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr); break; case 0x41: dev->pmu_conf[addr] = val & 0x10; @@ -1044,6 +1065,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) /* TODO: Is the status R/W or R/WC? */ case 0x42: dev->pmu_conf[addr] &= ~(val & 0x1f); + if (val & 0x08) + nvr_smi_status_clear(dev->nvr); break; case 0x43: dev->pmu_conf[addr] &= ~(val & 0x10); @@ -1181,8 +1204,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) case 0x77: /* TODO: If bit 1 is clear, then status bit is set even if SMI is disabled. */ dev->pmu_conf[addr] = val; - pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); ali1543_log("PMU77: %02X\n", val); + nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr); apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10)); break; @@ -1383,65 +1406,79 @@ ali7101_read(int func, int addr, void *priv) uint8_t ret = 0xff; if (dev->pmu_dev_enable && (func == 0)) { - if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9)) - return 0xff; - - /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ - if (addr == 0x43) - ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; - else if (addr == 0x7f) - ret = 0x80; - else if (addr == 0xbc) - ret = inb(0x70); - else - ret = dev->pmu_conf[addr]; - - if (dev->pmu_conf[0x77] & 0x10) { + if (!(dev->pmu_conf[0xc9] & 0x01) || (addr < 0x40) || (addr == 0xc9)) { + /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ switch (addr) { - case 0x42: - dev->pmu_conf[addr] &= 0xe0; + default: + ret = dev->pmu_conf[addr]; break; - case 0x43: - dev->pmu_conf[addr] &= 0xef; - acpi_ali_soft_smi_status_write(dev->acpi, 0); + case 0x10 ... 0x13: + if (dev->pmu_conf[0x5b] & 0x02) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; break; - - case 0x48: - dev->pmu_conf[addr] = 0x00; + case 0x14 ... 0x17: + if (dev->pmu_conf[0x5b] & 0x04) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; break; - case 0x49: - dev->pmu_conf[addr] &= 0x60; + case 0x42: + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); break; - case 0x4a: - dev->pmu_conf[addr] &= 0xc7; + case 0x43: + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; break; - - case 0x4e: - dev->pmu_conf[addr] &= 0xfa; + case 0x7f: + ret = 0x80; break; - case 0x4f: - dev->pmu_conf[addr] &= 0xfe; + case 0xbc: + ret = inb(0x70); break; + } - case 0x74: - dev->pmu_conf[addr] &= 0xcc; - break; + if (dev->pmu_conf[0x77] & 0x10) { + switch (addr) { + case 0x42: + dev->pmu_conf[addr] &= 0xe0; + break; + case 0x43: + dev->pmu_conf[addr] &= 0xef; + acpi_ali_soft_smi_status_write(dev->acpi, 0); + break; + + case 0x48: + dev->pmu_conf[addr] = 0x00; + break; + case 0x49: + dev->pmu_conf[addr] &= 0x60; + break; + case 0x4a: + dev->pmu_conf[addr] &= 0xc7; + break; + + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; + + case 0x74: + dev->pmu_conf[addr] &= 0xcc; + break; + + default: + break; + } } } } - return ret; -} - -static void -ali5237_usb_update_interrupt(usb_t* usb, void *priv) -{ - ali1543_t *dev = (ali1543_t *) priv; + ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret); - if (usb->irq_level) - pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10)); - else - pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10)); + return ret; } static void @@ -1557,16 +1594,16 @@ ali1543_init(const device_t *info) memset(dev, 0, sizeof(ali1543_t)); /* Device 02: M1533 Southbridge */ - dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot); /* Device 0B: M5229 IDE Controller*/ - dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev, &dev->ide_slot); /* Device 0C: M7101 Power Managment Controller */ - dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev, &dev->pmu_slot); /* Device 0F: M5237 USB */ - dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev, &dev->usb_slot); /* ACPI */ dev->acpi = device_add(&acpi_ali_device); @@ -1594,10 +1631,7 @@ ali1543_init(const device_t *info) dev->smbus = device_add(&ali7101_smbus_device); /* USB */ - dev->usb_params.parent_priv = dev; - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = ali5237_usb_update_interrupt; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); + dev->usb = device_add(&usb_device); dev->type = info->local & 0xff; dev->offset = (info->local >> 8) & 0x7f; diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index aba05e7764..6194dce195 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -28,12 +28,19 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/smram.h> #include <86box/spd.h> #include <86box/chipset.h> typedef struct ali1621_t { + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t pci_conf[256]; smram_t *smram[2]; @@ -107,10 +114,12 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal = ACCESS_SMRAM_RX; - /* FALLTHROUGH */ + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_R; break; + default: + break; } } @@ -118,10 +127,12 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal |= ACCESS_SMRAM_W; - /* FALLTHROUGH */ + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_W; break; + default: + break; } smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30)); @@ -137,7 +148,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) } static void -ali1621_shadow_recalc(int cur_reg, ali1621_t *dev) +ali1621_shadow_recalc(UNUSED(int cur_reg), ali1621_t *dev) { int r_bit; int w_bit; @@ -207,8 +218,8 @@ ali1621_mask_bar(ali1621_t *dev) uint32_t mask; switch (dev->pci_conf[0xbc] & 0x0f) { - case 0x00: default: + case 0x00: mask = 0x00000000; break; case 0x01: @@ -246,7 +257,7 @@ ali1621_mask_bar(ali1621_t *dev) } static void -ali1621_write(int func, int addr, uint8_t val, void *priv) +ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv) { ali1621_t *dev = (ali1621_t *) priv; @@ -565,14 +576,17 @@ ali1621_write(int func, int addr, uint8_t val, void *priv) case 0xf0 ... 0xff: dev->pci_conf[addr] = val; break; + + default: + break; } } static uint8_t -ali1621_read(int func, int addr, void *priv) +ali1621_read(UNUSED(int func), int addr, void *priv) { - ali1621_t *dev = (ali1621_t *) priv; - uint8_t ret = 0xff; + const ali1621_t *dev = (ali1621_t *) priv; + uint8_t ret = 0xff; ret = dev->pci_conf[addr]; @@ -653,12 +667,12 @@ ali1621_close(void *priv) } static void * -ali1621_init(const device_t *info) +ali1621_init(UNUSED(const device_t *info)) { ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t)); memset(dev, 0, sizeof(ali1621_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot); dev->smram[0] = smram_add(); dev->smram[1] = smram_add(); diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 3d86fbcd20..c7ada4bc60 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -33,12 +33,14 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/chipset.h> +#include <86box/plat_fallthrough.h> typedef struct ali6117_t { uint32_t local; /* Main registers (port 22h/23h) */ - uint8_t unlocked, mode; + uint8_t unlocked; + uint8_t mode; uint8_t reg_offset; uint8_t regs[256]; } ali6117_t; @@ -232,7 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x12: val &= 0xf7; - /* FALL-THROUGH */ + fallthrough; case 0x14: case 0x15: @@ -277,6 +279,9 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x7: cpu_set_isa_speed(cpu_busspeed / 6); break; + + default: + break; } break; @@ -372,6 +377,9 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x71: val &= 0x1f; break; + + default: + break; } dev->regs[dev->reg_offset] = val; @@ -381,7 +389,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) static uint8_t ali6117_reg_read(uint16_t addr, void *priv) { - ali6117_t *dev = (ali6117_t *) priv; + const ali6117_t *dev = (ali6117_t *) priv; uint8_t ret; if (addr == 0x22) diff --git a/src/chipset/compaq_386.c b/src/chipset/compaq_386.c new file mode 100644 index 0000000000..7d55bc5a5d --- /dev/null +++ b/src/chipset/compaq_386.c @@ -0,0 +1,761 @@ +/* + * 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. + * + * Emulation of the Compaq 386 memory controller. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/machine.h> +#include <86box/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> + +#define RAM_DIAG_L_BASE_MEM_640KB 0x00 +#define RAM_DIAG_L_BASE_MEM_INV 0x10 +#define RAM_DIAG_L_BASE_MEM_512KB 0x20 +#define RAM_DIAG_L_BASE_MEM_256KB 0x30 +#define RAM_DIAG_L_BASE_MEM_MASK 0x30 +#define RAM_DIAG_L_PERMA_BITS 0x80 + +#define RAM_DIAG_H_SYS_RAM_4MB 0x01 +#define RAM_DIAG_H_SYS_RAM_1MB 0x02 +#define RAM_DIAG_H_SYS_RAM_NONE 0x03 +#define RAM_DIAG_H_SYS_RAM_MASK 0x03 +#define RAM_DIAG_H_MOD_A_RAM_4MB 0x04 +#define RAM_DIAG_H_MOD_A_RAM_1MB 0x08 +#define RAM_DIAG_H_MOD_A_RAM_NONE 0x0c +#define RAM_DIAG_H_MOD_A_RAM_MASK 0x0c +#define RAM_DIAG_H_MOD_B_RAM_4MB 0x10 +#define RAM_DIAG_H_MOD_B_RAM_1MB 0x20 +#define RAM_DIAG_H_MOD_B_RAM_NONE 0x30 +#define RAM_DIAG_H_MOD_B_RAM_MASK 0x30 +#define RAM_DIAG_H_MOD_C_RAM_4MB 0x40 +#define RAM_DIAG_H_MOD_C_RAM_1MB 0x80 +#define RAM_DIAG_H_MOD_C_RAM_NONE 0xc0 +#define RAM_DIAG_H_MOD_C_RAM_MASK 0xc0 + +#define MEM_STATE_BUS 0x00 +#define MEM_STATE_SYS 0x01 +#define MEM_STATE_SYS_RELOC 0x02 +#define MEM_STATE_MOD_A 0x04 +#define MEM_STATE_MOD_B 0x08 +#define MEM_STATE_MOD_C 0x10 +#define MEM_STATE_MASK (MEM_STATE_SYS | MEM_STATE_MOD_A | MEM_STATE_MOD_B | MEM_STATE_MOD_C) +#define MEM_STATE_WP 0x20 + +typedef struct cpq_ram_t { + uint8_t wp; + + uint32_t phys_base; + uint32_t virt_base; + + mem_mapping_t mapping; +} cpq_ram_t; + +typedef struct cpq_386_t { + uint8_t regs[8]; + + uint8_t old_state[256]; + uint8_t mem_state[256]; + + uint32_t ram_bases[4]; + + uint32_t ram_sizes[4]; + uint32_t ram_map_sizes[4]; + + cpq_ram_t ram[4][64]; + cpq_ram_t high_ram[16]; + + mem_mapping_t regs_mapping; +} cpq_386_t; + +static uint8_t +cpq_read_ram(uint32_t addr, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_ram(addr, priv); + + return ret; +} + +static uint16_t +cpq_read_ramw(uint32_t addr, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + uint16_t ret = 0xffff; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_ramw(addr, priv); + + return ret; +} + +static uint32_t +cpq_read_raml(uint32_t addr, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + uint32_t ret = 0xffffffff; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_raml(addr, priv); + + return ret; +} + +static void +cpq_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_ram(addr, val, priv); +} + +static void +cpq_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_ramw(addr, val, priv); +} + +static void +cpq_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + const cpq_ram_t *dev = (cpq_ram_t *) priv; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_raml(addr, val, priv); +} + +static uint8_t +cpq_read_regs(uint32_t addr, void *priv) +{ + const cpq_386_t *dev = (cpq_386_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000001: + /* RAM Diagnostics (Read Only) */ + case 0x00000002: + case 0x00000003: + /* RAM Setup Port (Read/Write) */ + ret = dev->regs[addr]; + break; + + default: + break; + } + + return ret; +} + +static uint16_t +cpq_read_regsw(uint32_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + ret = cpq_read_regs(addr, priv); + ret |= (((uint16_t) cpq_read_regs(addr + 1, priv)) << 8); + + return ret; +} + +static uint32_t +cpq_read_regsl(uint32_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + ret = cpq_read_regsw(addr, priv); + ret |= (((uint32_t) cpq_read_regsw(addr + 2, priv)) << 16); + + return ret; +} + +static void +cpq_recalc_state(cpq_386_t *dev, uint8_t i) +{ + uint32_t addr; + + addr = ((uint32_t) i) << 16; + if (dev->mem_state[i] == 0x00) + mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else if (dev->mem_state[i] == MEM_STATE_WP) + mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_DISABLED); + else if (dev->mem_state[i] & MEM_STATE_WP) + mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + dev->old_state[i] = dev->mem_state[i]; +} + +static void +cpq_recalc_states(cpq_386_t *dev) +{ + /* Recalculate the entire 16 MB space. */ + for (uint16_t i = 0; i < 256; i++) { + if (dev->mem_state[i] != dev->old_state[i]) + cpq_recalc_state(dev, i); + } + + flushmmucache_nopc(); +} + +static void +cpq_recalc_cache(cpq_386_t *dev) +{ + cpu_cache_ext_enabled = (dev->regs[0x00000002] & 0x40); + cpu_update_waitstates(); +} + +static void +cpq_recalc_ram(cpq_386_t *dev) +{ + uint8_t sys_ram = (dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK) & 0x01; + uint8_t setup_port = dev->regs[0x00000002] & 0x0f; + uint8_t sys_min_high = sys_ram ? 0xfa : 0xf4; + uint8_t ram_states[4] = { MEM_STATE_SYS, MEM_STATE_MOD_A, + MEM_STATE_MOD_B, MEM_STATE_MOD_C }; + uint8_t ram_bases[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { { 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00 }, + { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x90, 0x00, 0x00, 0xc0, 0xc0, 0xc0 } } }; + uint8_t ram_sizes[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x30, 0x00, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 } }, + { { 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x10, 0x10, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, + 0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, + 0x00, 0x10, 0x10, 0x30, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x00, 0x00 }, + { 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x20, 0x30 } } }; + uint8_t size; + uint8_t start; + uint8_t end; + uint8_t k; + uint32_t virt_base; + cpq_ram_t *cram; + + for (uint16_t i = 0x10; i < sys_min_high; i++) + dev->mem_state[i] &= ~MEM_STATE_MASK; + + for (uint8_t i = 0; i < 4; i++) { + for (uint8_t j = 0; j <= 64; j++) { + if ((i >= 1) || (j >= 0x10)) + mem_mapping_disable(&dev->ram[i][j].mapping); + } + } + + for (uint8_t i = 0; i < 4; i++) { + size = ram_sizes[i][sys_ram][setup_port]; + if (size > 0x00) { + start = ram_bases[i][sys_ram][setup_port]; + end = start + (size - 1); + + virt_base = ((uint32_t) start) << 16; + + for (uint16_t j = start; j <= end; j++) { + k = j - start; + if (i == 0) + k += 0x10; + + cram = &(dev->ram[i][k]); + + dev->mem_state[j] |= ram_states[i]; + + cram->virt_base = ((uint32_t) j) << 16; + cram->phys_base = cram->virt_base - virt_base + dev->ram_bases[i]; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + } + } + } + + /* Recalculate the entire 16 MB space. */ + cpq_recalc_states(dev); +} + +static void +cpq_write_regs(uint32_t addr, uint8_t val, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000001: + /* RAM Relocation (Write Only) */ + dev->regs[addr + 4] = val; + if (addr == 0x00000000) { + dev->mem_state[0x0e] &= ~(MEM_STATE_SYS | MEM_STATE_WP); + dev->mem_state[0x0f] &= ~(MEM_STATE_SYS | MEM_STATE_WP); + dev->mem_state[0xfe] &= ~MEM_STATE_WP; + dev->mem_state[0xff] &= ~MEM_STATE_WP; + if (!(val & 0x01)) { + dev->mem_state[0x0e] |= MEM_STATE_SYS; + dev->mem_state[0x0f] |= MEM_STATE_SYS; + } + if (!(val & 0x02)) { + dev->mem_state[0x0e] |= MEM_STATE_WP; + dev->mem_state[0x0f] |= MEM_STATE_WP; + dev->mem_state[0xfe] |= MEM_STATE_WP; + dev->mem_state[0xff] |= MEM_STATE_WP; + } + cpq_recalc_state(dev, 0x0e); + cpq_recalc_state(dev, 0x0f); + cpq_recalc_state(dev, 0xfe); + cpq_recalc_state(dev, 0xff); + flushmmucache_nopc(); + } + break; + case 0x00000002: + case 0x00000003: + /* RAM Setup Port (Read/Write) */ + dev->regs[addr] = val; + if (addr == 0x00000002) { + cpq_recalc_ram(dev); + cpq_recalc_cache(dev); + } + break; + + default: + break; + } +} + +static void +cpq_write_regsw(uint32_t addr, uint16_t val, void *priv) +{ + cpq_write_regs(addr, val & 0xff, priv); + cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv); +} + +static void +cpq_write_regsl(uint32_t addr, uint32_t val, void *priv) +{ + cpq_write_regsw(addr, val & 0xff, priv); + cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv); +} + +static void +compaq_ram_init(cpq_ram_t *dev) +{ + mem_mapping_add(&dev->mapping, + 0x00000000, + 0x00010000, + cpq_read_ram, + cpq_read_ramw, + cpq_read_raml, + cpq_write_ram, + cpq_write_ramw, + cpq_write_raml, + NULL, + MEM_MAPPING_INTERNAL, + dev); + + mem_mapping_disable(&dev->mapping); +} + +static void +compaq_ram_diags_parse(cpq_386_t *dev) +{ + uint8_t val = dev->regs[0x00000001]; + uint32_t accum = 0x00100000; + + for (uint8_t i = 0; i < 4; i++) { + dev->ram_bases[i] = accum; + + switch (val & 0x03) { + case RAM_DIAG_H_SYS_RAM_1MB: + dev->ram_sizes[i] = 0x00100000; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + dev->ram_sizes[i] = 0x00400000; + break; + + default: + break; + } + if (i == 0) + dev->ram_sizes[i] -= 0x00100000; + + dev->ram_map_sizes[i] = dev->ram_sizes[i]; + accum += dev->ram_sizes[i]; + + if (accum >= (mem_size << 10)) { + dev->ram_sizes[i] = (mem_size << 10) - dev->ram_bases[i]; + break; + } + + val >>= 2; + } +} + +static void +compaq_recalc_base_ram(cpq_386_t *dev) +{ + uint8_t base_mem = dev->regs[0x00000000] & RAM_DIAG_L_BASE_MEM_MASK; + uint8_t sys_ram = dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK; + uint8_t low_start = 0x00; + uint8_t low_end = 0x00; + uint8_t high_start = 0x00; + uint8_t high_end = 0x00; + cpq_ram_t *cram; + + switch (base_mem) { + case RAM_DIAG_L_BASE_MEM_256KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x03; + high_start = 0xf4; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x03; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + case RAM_DIAG_L_BASE_MEM_512KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x07; + high_start = 0xf8; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x07; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + case RAM_DIAG_L_BASE_MEM_640KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x09; + high_start = 0xfa; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x09; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + if (mem_size < 1024) + dev->regs[0x00000002] = 0x01; + else if (mem_size == 8192) + dev->regs[0x00000002] = 0x09; + else if (mem_size >= 11264) + dev->regs[0x00000002] = 0x0d; + else + dev->regs[0x00000002] = (mem_size >> 10); + break; + case RAM_DIAG_H_SYS_RAM_4MB: + if (mem_size < 4096) + dev->regs[0x00000002] = 0x04; + else if (mem_size == 11264) + dev->regs[0x00000002] = 0x0c; + else if (mem_size >= 16384) + dev->regs[0x00000002] = 0x00; + else if (mem_size > 13312) + dev->regs[0x00000002] = 0x0d; + else + dev->regs[0x00000002] = (mem_size >> 10); + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X\n", sys_ram); + return; + } + + /* The base 640 kB. */ + for (uint8_t i = low_start; i <= low_end; i++) { + cram = &(dev->ram[0][i]); + + cram->phys_base = cram->virt_base = ((uint32_t) i) << 16; + dev->mem_state[i] |= MEM_STATE_SYS; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + + cpq_recalc_state(dev, i); + } + + /* The relocated 128 kB. */ + for (uint8_t i = 0x0e; i <= 0x0f; i++) { + cram = &(dev->ram[0][i]); + + cram->phys_base = cram->virt_base = ((uint32_t) i) << 16; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + } + + /* Blocks FA-FF. */ + for (uint16_t i = high_start; i <= high_end; i++) { + cram = &(dev->high_ram[i & 0x0f]); + + cram->phys_base = ((uint32_t) (i & 0x0f)) << 16; + cram->virt_base = ((uint32_t) i) << 16; + dev->mem_state[i] |= MEM_STATE_SYS; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + + cpq_recalc_state(dev, i); + } +} + +static void +compaq_386_close(void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + free(dev); +} + +static void * +compaq_386_init(UNUSED(const device_t *info)) +{ + cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t)); + + mem_mapping_add(&dev->regs_mapping, + 0x80c00000, + 0x00001000, + cpq_read_regs, + cpq_read_regsw, + cpq_read_regsl, + cpq_write_regs, + cpq_write_regsw, + cpq_write_regsl, + NULL, + MEM_MAPPING_INTERNAL, + dev); + + mem_set_mem_state(0x80c00000, 0x00001000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + dev->regs[0x00000000] = RAM_DIAG_L_PERMA_BITS; + if (mem_size >= 640) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_640KB; + else if (mem_size >= 512) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_512KB; + else if (mem_size >= 256) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_256KB; + else + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_INV; + /* Indicate no parity error. */ + dev->regs[0x00000000] |= 0x0f; + + if (mem_size >= 1024) { + switch (mem_size) { + case 1024: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 2048: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 3072: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 4096: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 5120: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 6144: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 7168: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 8192: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 9216: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 10240: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 11264: + case 12288: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 13312: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 14336: + case 15360: + case 16384: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB; + break; + + default: + break; + } + } else + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + + dev->regs[0x00000003] = 0xfc; + dev->regs[0x00000004] = dev->regs[0x00000005] = 0xff; + + compaq_ram_diags_parse(dev); + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + /* Should never be the case, but you never know what a user may set. */ + if (mem_size > 1048576) + mem_mapping_disable(&ram_2gb_mapping); +#endif + + /* Initialize in reverse order for memory mapping precedence + reasons. */ + for (int8_t i = 3; i >= 0; i--) { + for (uint8_t j = 0; j < 64; j++) + compaq_ram_init(&(dev->ram[i][j])); + } + + for (uint8_t i = 0; i < 16; i++) + compaq_ram_init(&(dev->high_ram[i])); + + /* First, set the entire 256 MB of space to invalid states. */ + for (uint16_t i = 0; i < 256; i++) + dev->old_state[i] = 0xff; + + /* Then, recalculate the base RAM mappings. */ + compaq_recalc_base_ram(dev); + + /* Enable the external cache. */ + dev->regs[0x00000002] |= 0x40; + cpq_recalc_cache(dev); + + /* Recalculate the rest of the RAM mapping. */ + cpq_recalc_ram(dev); + + return dev; +} + +const device_t compaq_386_device = { + .name = "Compaq 386 Memory Control", + .internal_name = "compaq_386", + .flags = 0, + .local = 0, + .init = compaq_386_init, + .close = compaq_386_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c index 720d7c81ed..5c29102270 100644 --- a/src/chipset/contaq_82c59x.c +++ b/src/chipset/contaq_82c59x.c @@ -48,16 +48,17 @@ contaq_82c59x_log(const char *fmt, ...) # define contaq_82c59x_log(fmt, ...) #endif -typedef struct -{ - uint32_t phys, virt; +typedef struct mem_remapping_t { + uint32_t phys; + uint32_t virt; } mem_remapping_t; -typedef struct -{ - uint8_t index, green, - smi_status_set, - regs[256], smi_status[2]; +typedef struct contaq_82c59x_t { + uint8_t index; + uint8_t green; + uint8_t smi_status_set; + uint8_t regs[256]; + uint8_t smi_status[2]; smram_t *smram[2]; } contaq_82c59x_t; @@ -82,6 +83,8 @@ contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev) case 0x03: cpu_set_isa_speed(cpu_busspeed / 5); break; + default: + break; } } } @@ -274,8 +277,14 @@ contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv) case 0x7c: dev->regs[dev->index] = val; break; + + default: + break; } break; + + default: + break; } } @@ -302,8 +311,10 @@ contaq_82c59x_close(void *priv) { contaq_82c59x_t *dev = (contaq_82c59x_t *) priv; - smram_del(dev->smram[1]); - smram_del(dev->smram[0]); + if (dev->green) { + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); + } free(dev); } diff --git a/src/chipset/cs4031.c b/src/chipset/cs4031.c index a2cef50b93..fb439ec3a6 100644 --- a/src/chipset/cs4031.c +++ b/src/chipset/cs4031.c @@ -27,13 +27,13 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t index, - regs[256]; +typedef struct cs4031_t { + uint8_t index; + uint8_t regs[256]; port_92_t *port_92; } cs4031_t; @@ -134,15 +134,21 @@ cs4031_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = val & 0xb3; port_92_set_features(dev->port_92, val & 0x10, val & 0x20); break; + + default: + break; } break; + + default: + break; } } static uint8_t cs4031_read(uint16_t addr, void *priv) { - cs4031_t *dev = (cs4031_t *) priv; + const cs4031_t *dev = (cs4031_t *) priv; return (addr == 0x23) ? dev->regs[dev->index] : 0xff; } @@ -156,7 +162,7 @@ cs4031_close(void *priv) } static void * -cs4031_init(const device_t *info) +cs4031_init(UNUSED(const device_t *info)) { cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t)); memset(dev, 0, sizeof(cs4031_t)); diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index edf4ac8c23..93a7f1bbad 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -25,12 +25,12 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/chipset.h> -typedef struct -{ +typedef struct cs8230_t { int idx; uint8_t regs[256]; } cs8230_t; @@ -51,6 +51,8 @@ shadow_control(uint32_t addr, uint32_t size, int state) case 0x11: mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); break; + default: + break; } flushmmucache_nopc(); @@ -59,9 +61,7 @@ shadow_control(uint32_t addr, uint32_t size, int state) static void rethink_shadow_mappings(cs8230_t *cs8230) { - int c; - - for (c = 0; c < 32; c++) { + for (uint8_t c = 0; c < 32; c++) { /* Addresses 40000-bffff in 16k blocks */ if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7))) mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */ @@ -69,7 +69,7 @@ rethink_shadow_mappings(cs8230_t *cs8230) mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */ } - for (c = 0; c < 16; c++) { + for (uint8_t c = 0; c < 16; c++) { /* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */ if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7))) mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */ @@ -79,10 +79,10 @@ rethink_shadow_mappings(cs8230_t *cs8230) } static uint8_t -cs8230_read(uint16_t port, void *p) +cs8230_read(uint16_t port, void *priv) { - cs8230_t *cs8230 = (cs8230_t *) p; - uint8_t ret = 0xff; + const cs8230_t *cs8230 = (cs8230_t *) priv; + uint8_t ret = 0xff; if (port & 1) { switch (cs8230->idx) { @@ -112,6 +112,9 @@ cs8230_read(uint16_t port, void *p) case 0x2a: ret = cs8230->regs[cs8230->idx]; break; + + default: + break; } } @@ -119,9 +122,9 @@ cs8230_read(uint16_t port, void *p) } static void -cs8230_write(uint16_t port, uint8_t val, void *p) +cs8230_write(uint16_t port, uint8_t val, void *priv) { - cs8230_t *cs8230 = (cs8230_t *) p; + cs8230_t *cs8230 = (cs8230_t *) priv; if (!(port & 1)) cs8230->idx = val; @@ -137,6 +140,8 @@ cs8230_write(uint16_t port, uint8_t val, void *p) case 0x0f: /* Address maps */ rethink_shadow_mappings(cs8230); break; + default: + break; } } } @@ -149,9 +154,8 @@ cs8230_close(void *priv) free(cs8230); } -static void - * - cs8230_init(const device_t *info) +static void * +cs8230_init(UNUSED(const device_t *info)) { cs8230_t *cs8230 = (cs8230_t *) malloc(sizeof(cs8230_t)); memset(cs8230, 0, sizeof(cs8230_t)); diff --git a/src/chipset/et6000.c b/src/chipset/et6000.c index ca011e33c8..f2cffd7f7e 100644 --- a/src/chipset/et6000.c +++ b/src/chipset/et6000.c @@ -28,14 +28,15 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/pit.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> #define INDEX (dev->index - 0x10) -typedef struct -{ - uint8_t index, regs[256]; +typedef struct et6000_t { + uint8_t index; + uint8_t regs[256]; } et6000_t; #ifdef ENABLE_ET6000_LOG @@ -105,16 +106,22 @@ et6000_write(uint16_t addr, uint8_t val, void *priv) et6000_shadow_control(0xe0000, 0x10000, val & 0x20, (val & 0x20) && (val & 0x10)); et6000_shadow_control(0xf0000, 0x10000, val & 0x40, !(val & 0x40)); break; + + default: + break; } et6000_log("ET6000: dev->regs[%02x] = %02x\n", dev->index, dev->regs[dev->index]); break; + + default: + break; } } static uint8_t et6000_read(uint16_t addr, void *priv) { - et6000_t *dev = (et6000_t *) priv; + const et6000_t *dev = (et6000_t *) priv; return ((addr == 0x23) && (INDEX >= 0) && (INDEX <= 5)) ? dev->regs[INDEX] : 0xff; } @@ -128,7 +135,7 @@ et6000_close(void *priv) } static void * -et6000_init(const device_t *info) +et6000_init(UNUSED(const device_t *info)) { et6000_t *dev = (et6000_t *) malloc(sizeof(et6000_t)); memset(dev, 0, sizeof(et6000_t)); diff --git a/src/chipset/gc100.c b/src/chipset/gc100.c index 0df25b1d67..0b47179035 100644 --- a/src/chipset/gc100.c +++ b/src/chipset/gc100.c @@ -44,8 +44,7 @@ #include <86box/io.h> #include <86box/video.h> -typedef struct -{ +typedef struct gc100_t { uint8_t reg[0x10]; } gc100_t; @@ -70,7 +69,7 @@ gc100_log(const char *fmt, ...) static uint8_t get_fdd_switch_settings(void) { - int fdd_count = 0; + uint8_t fdd_count = 0; for (uint8_t i = 0; i < FDD_NUM; i++) { if (fdd_get_flags(i)) @@ -135,6 +134,9 @@ gc100_write(uint16_t port, uint8_t val, void *priv) /* addr 0x6 */ /* addr 0x7 */ + + default: + break; } gc100_log("GC100: Write %02x at %02x\n", val, port); @@ -143,9 +145,9 @@ gc100_write(uint16_t port, uint8_t val, void *priv) static uint8_t gc100_read(uint16_t port, void *priv) { - gc100_t *dev = (gc100_t *) priv; - uint8_t ret = 0xff; - uint16_t addr = port & 0xf; + const gc100_t *dev = (gc100_t *) priv; + uint8_t ret = 0xff; + uint16_t addr = port & 0xf; ret = dev->reg[addr]; @@ -187,6 +189,9 @@ gc100_read(uint16_t port, void *priv) /* addr 0x6 */ /* addr 0x7 */ + + default: + break; } return ret; diff --git a/src/chipset/headland.c b/src/chipset/headland.c index 31cb752537..db5922470a 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -34,6 +34,7 @@ #include <86box/device.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -52,8 +53,9 @@ enum { #define HEADLAND_HAS_CRI 0x10 #define HEADLAND_HAS_SLEEP 0x20 -typedef struct { - uint8_t valid, enabled; +typedef struct headland_mr_t { + uint8_t valid; + uint8_t enabled; uint16_t mr; uint32_t virt_base; @@ -62,7 +64,8 @@ typedef struct { typedef struct headland_t { uint8_t revision; - uint8_t has_cri, has_sleep; + uint8_t has_cri; + uint8_t has_sleep; uint8_t cri; uint8_t cr[7]; @@ -72,8 +75,8 @@ typedef struct headland_t { uint8_t ems_mar; - headland_mr_t null_mr, - ems_mr[64]; + headland_mr_t null_mr; + headland_mr_t ems_mr[64]; mem_mapping_t low_mapping; mem_mapping_t ems_mapping[64]; @@ -162,7 +165,7 @@ get_addr(headland_t *dev, uint32_t addr, headland_mr_t *mr) static void hl_ems_disable(headland_t *dev, uint8_t mar, uint32_t base_addr, uint8_t indx) { - if (base_addr < ((uint32_t) mem_size << 10)) + if (base_addr < (mem_size << 10)) mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + base_addr); else mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], NULL); @@ -194,7 +197,7 @@ hl_ems_update(headland_t *dev, uint8_t mar) dev->ems_mr[mar & 0x3f].virt_base = virt_addr; if (indx < 24) mem_mapping_disable(&dev->upper_mapping[indx]); - if (virt_addr < ((uint32_t) mem_size << 10)) + if (virt_addr < (mem_size << 10)) mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + virt_addr); else mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], NULL); @@ -205,7 +208,7 @@ hl_ems_update(headland_t *dev, uint8_t mar) } static void -set_global_EMS_state(headland_t *dev, int state) +set_global_EMS_state(headland_t *dev, UNUSED(int state)) { for (uint8_t i = 0; i < 32; i++) { hl_ems_update(dev, i | (((dev->cr[0] & 0x01) << 5) ^ 0x20)); @@ -241,7 +244,7 @@ memmap_state_update(headland_t *dev) for (uint8_t i = 0; i < 24; i++) { addr = get_addr(dev, 0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&dev->upper_mapping[i], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL); + mem_mapping_set_exec(&dev->upper_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); } memmap_state_default(dev, ht_romcs); @@ -510,7 +513,7 @@ mem_read_b(uint32_t addr, void *priv) uint8_t ret = 0xff; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ret = ram[addr]; return ret; @@ -524,7 +527,7 @@ mem_read_w(uint32_t addr, void *priv) uint16_t ret = 0xffff; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ret = *(uint16_t *) &ram[addr]; return ret; @@ -538,7 +541,7 @@ mem_read_l(uint32_t addr, void *priv) uint32_t ret = 0xffffffff; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ret = *(uint32_t *) &ram[addr]; return ret; @@ -551,7 +554,7 @@ mem_write_b(uint32_t addr, uint8_t val, void *priv) headland_t *dev = mr->headland; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) ram[addr] = val; } @@ -562,7 +565,7 @@ mem_write_w(uint32_t addr, uint16_t val, void *priv) headland_t *dev = mr->headland; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) *(uint16_t *) &ram[addr] = val; } @@ -573,7 +576,7 @@ mem_write_l(uint32_t addr, uint32_t val, void *priv) headland_t *dev = mr->headland; addr = get_addr(dev, addr, mr); - if (addr < ((uint32_t) mem_size << 10)) + if (addr < (mem_size << 10)) *(uint32_t *) &ram[addr] = val; } @@ -590,7 +593,6 @@ headland_init(const device_t *info) { headland_t *dev; int ht386 = 0; - uint32_t i; dev = (headland_t *) malloc(sizeof(headland_t)); memset(dev, 0x00, sizeof(headland_t)); @@ -615,7 +617,7 @@ headland_init(const device_t *info) dev->null_mr.mr = 0xff; dev->null_mr.headland = dev; - for (i = 0; i < 64; i++) { + for (uint8_t i = 0; i < 64; i++) { dev->ems_mr[i].valid = 1; dev->ems_mr[i].mr = 0x00; dev->ems_mr[i].headland = dev; @@ -647,7 +649,7 @@ headland_init(const device_t *info) mem_mapping_enable(&dev->high_mapping); } - for (i = 0; i < 24; i++) { + for (uint8_t i = 0; i < 24; i++) { mem_mapping_add(&dev->upper_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_b, mem_read_w, mem_read_l, @@ -673,7 +675,7 @@ headland_init(const device_t *info) MEM_MAPPING_INTERNAL, &dev->null_mr); mem_mapping_disable(&dev->shadow_mapping[1]); - for (i = 0; i < 64; i++) { + for (uint8_t i = 0; i < 64; i++) { dev->ems_mr[i].mr = 0x00; mem_mapping_add(&dev->ems_mapping[i], ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000, diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 34a09ae35b..3e86a44e17 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -31,6 +31,7 @@ #include <86box/smram.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -118,10 +119,14 @@ Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable) */ -typedef struct -{ - uint8_t idx, access_data, - regs[256], pci_conf[256]; +typedef struct ims8848_t { + uint8_t idx; + uint8_t access_data; + uint8_t pci_slot; + uint8_t pad; + + uint8_t regs[256]; + uint8_t pci_conf[256]; smram_t *smram; } ims8848_t; @@ -148,7 +153,6 @@ ims8848_log(const char *fmt, ...) static void ims8848_recalc(ims8848_t *dev) { - int i; int state_on; uint32_t base; ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n", @@ -157,7 +161,7 @@ ims8848_recalc(ims8848_t *dev) state_on = MEM_READ_INTERNAL; state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { base = 0xe0000 + (i << 16); if (dev->regs[0x00] & (1 << (i + 2))) mem_set_mem_state_both(base, 0x10000, state_on); @@ -165,7 +169,7 @@ ims8848_recalc(ims8848_t *dev) mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xc0000 + (i << 14); if (dev->regs[0x1c] & (1 << i)) mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); @@ -244,10 +248,16 @@ ims8848_write(uint16_t addr, uint8_t val, void *priv) /* Base Memory */ ims8848_base_memory(dev); break; + + default: + break; } dev->access_data = 0; } break; + + default: + break; } } @@ -276,6 +286,8 @@ ims8848_read(uint16_t addr, void *priv) } ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret); break; + default: + break; } return ret; @@ -309,14 +321,17 @@ ims8849_pci_write(int func, int addr, uint8_t val, void *priv) case 0x52 ... 0x55: dev->pci_conf[addr] = val; break; + + default: + break; } } static uint8_t ims8849_pci_read(int func, int addr, void *priv) { - ims8848_t *dev = (ims8848_t *) priv; - uint8_t ret = 0xff; + const ims8848_t *dev = (ims8848_t *) priv; + uint8_t ret = 0xff; if (func == 0) ret = dev->pci_conf[addr]; @@ -364,7 +379,7 @@ ims8848_close(void *priv) } static void * -ims8848_init(const device_t *info) +ims8848_init(UNUSED(const device_t *info)) { ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t)); memset(dev, 0, sizeof(ims8848_t)); @@ -380,7 +395,7 @@ ims8848_init(const device_t *info) PCI Device 0: IMS 8849 Dummy for compatibility reasons */ io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev); - pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev, &dev->pci_slot); dev->smram = smram_add(); smram_set_separate_smram(1); diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index b2a0e082b9..34335d53c6 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -15,6 +15,7 @@ * * Copyright 2020 Miran Grca. */ +#define USE_DRB_HACK #include #include #include @@ -34,30 +35,38 @@ #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/hdc.h> #include <86box/machine.h> #include <86box/chipset.h> #include <86box/spd.h> +#ifndef USE_DRB_HACK +#include <86box/row.h> +#endif #define MEM_STATE_SHADOW_R 0x01 #define MEM_STATE_SHADOW_W 0x02 #define MEM_STATE_SMRAM 0x04 -typedef struct -{ - uint8_t has_ide, smram_locked, - regs[256]; +typedef struct i420ex_t { + uint8_t has_ide; + uint8_t smram_locked; + uint8_t pci_slot; + uint8_t pad; - uint16_t timer_base, - timer_latch; + uint8_t regs[256]; + + uint16_t timer_base; + uint16_t timer_latch; smram_t *smram; double fast_off_period; - pc_timer_t timer, fast_off_timer; + pc_timer_t timer; + pc_timer_t fast_off_timer; apm_t *apm; port_92_t *port_92; @@ -97,6 +106,8 @@ i420ex_map(uint32_t addr, uint32_t size, int state) case 3: mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; + default: + break; } flushmmucache_nopc(); } @@ -111,16 +122,16 @@ i420ex_smram_handler_phase0(void) static void i420ex_smram_handler_phase1(i420ex_t *dev) { - uint8_t *regs = (uint8_t *) dev->regs; + const uint8_t *regs = (uint8_t *) dev->regs; uint32_t host_base = 0x000a0000; uint32_t ram_base = 0x000a0000; uint32_t size = 0x00010000; switch (regs[0x70] & 0x07) { + default: case 0: case 1: - default: host_base = ram_base = 0x00000000; size = 0x00000000; break; @@ -154,6 +165,25 @@ i420ex_smram_handler_phase1(i420ex_t *dev) (regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20)); } +#ifndef USE_DRB_HACK +static void +i420ex_drb_recalc(i420ex_t *dev) +{ + uint32_t boundary; + + for (int8_t i = 4; i >= 0; i--) + row_disable(i); + + for (uint8_t i = 0; i <= 4; i++) { + boundary = ((uint32_t) dev->regs[0x60 + i]) & 0xff; + row_set_boundary(i, boundary); + } + + flushmmucache(); +} +#endif + + static void i420ex_write(int func, int addr, uint8_t val, void *priv) { @@ -195,6 +225,8 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) ide_set_side(0, 0x0376); ide_pri_enable(); break; + default: + break; } } break; @@ -283,7 +315,12 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) case 0x62: case 0x63: case 0x64: +#ifdef USE_DRB_HACK spd_write_drbs(dev->regs, 0x60, 0x64, 1); +#else + dev->regs[addr] = val; + i420ex_drb_recalc(dev); +#endif break; case 0x66: case 0x67: @@ -356,14 +393,16 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) cpu_fast_off_count = val + 1; cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period); break; + default: + break; } } static uint8_t i420ex_read(int func, int addr, void *priv) { - i420ex_t *dev = (i420ex_t *) priv; - uint8_t ret; + const i420ex_t *dev = (i420ex_t *) priv; + uint8_t ret; ret = 0xff; @@ -411,9 +450,9 @@ i420ex_reset_hard(void *priv) } static void -i420ex_apm_out(uint16_t port, uint8_t val, void *p) +i420ex_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv) { - i420ex_t *dev = (i420ex_t *) p; + i420ex_t *dev = (i420ex_t *) priv; if (dev->apm->do_smi) dev->regs[0xaa] |= 0x80; @@ -431,42 +470,41 @@ i420ex_fast_off_count(void *priv) } static void -i420ex_reset(void *p) +i420ex_reset(void *priv) { - i420ex_t *dev = (i420ex_t *) p; - int i; + i420ex_t *dev = (i420ex_t *) priv; - i420ex_write(0, 0x48, 0x00, p); + i420ex_write(0, 0x48, 0x00, priv); /* Disable the PIC mouse latch. */ - i420ex_write(0, 0x4e, 0x03, p); + i420ex_write(0, 0x4e, 0x03, priv); - for (i = 0; i < 7; i++) - i420ex_write(0, 0x59 + i, 0x00, p); + for (uint8_t i = 0; i < 7; i++) + i420ex_write(0, 0x59 + i, 0x00, priv); - for (i = 0; i <= 4; i++) - i420ex_write(0, 0x60 + i, 0x01, p); + 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, p); + i420ex_write(0, 0x70, 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, p); - i420ex_write(0, 0xa2, 0x00, p); - i420ex_write(0, 0xa4, 0x00, p); - i420ex_write(0, 0xa5, 0x00, p); - i420ex_write(0, 0xa6, 0x00, p); - i420ex_write(0, 0xa7, 0x00, p); - i420ex_write(0, 0xa8, 0x0f, p); + 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); } static void -i420ex_close(void *p) +i420ex_close(void *priv) { - i420ex_t *dev = (i420ex_t *) p; + i420ex_t *dev = (i420ex_t *) priv; smram_del(dev->smram); @@ -485,7 +523,7 @@ i420ex_speed_changed(void *priv) if (te) timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); - te = timer_is_enabled(&dev->fast_off_timer); + te = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); if (te) @@ -500,7 +538,7 @@ i420ex_init(const device_t *info) dev->smram = smram_add(); - pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev, &dev->pci_slot); dev->has_ide = info->local; @@ -523,6 +561,11 @@ i420ex_init(const device_t *info) device_add(&ide_pci_2ch_device); +#ifndef USE_DRB_HACK + row_device.local = 4 | (1 << 8) | (0x01 << 16) | (8 << 24); + device_add((const device_t *) &row_device); +#endif + i420ex_reset_hard(dev); return dev; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index bebfa6aded..a1f923e492 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -28,6 +28,7 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> #include <86box/spd.h> #include <86box/machine.h> @@ -50,17 +51,23 @@ enum { INTEL_440ZX }; -typedef struct -{ - uint8_t pm2_cntrl, - smram_locked, max_drb, - drb_unit, drb_default; - uint8_t regs[256], regs_locked[256]; +typedef struct i4x0_t { + uint8_t pm2_cntrl; + uint8_t smram_locked; + uint8_t max_drb; + uint8_t drb_unit; + uint8_t drb_default; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t regs[256]; + uint8_t regs_locked[256]; uint8_t mem_state[256]; int type; - smram_t *smram_low, *smram_high; + smram_t *smram_low; + smram_t *smram_high; agpgart_t *agpgart; - void (*write_drbs)(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); + void (*write_drbs)(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); } i4x0_t; #ifdef ENABLE_I4X0_LOG @@ -114,10 +121,10 @@ static void i4x0_smram_handler_phase1(i4x0_t *dev) { - uint8_t *regs = (uint8_t *) dev->regs; - uint32_t tom = (mem_size << 10); - uint8_t *reg = (dev->type >= INTEL_430LX) ? &(regs[0x72]) : &(regs[0x57]); - uint8_t *ext_reg = (dev->type >= INTEL_440BX) ? &(regs[0x73]) : &(regs[0x71]); + const uint8_t *regs = (uint8_t *) dev->regs; + uint32_t tom = (mem_size << 10); + const uint8_t *reg = (dev->type >= INTEL_430LX) ? &(regs[0x72]) : &(regs[0x57]); + const uint8_t *ext_reg = (dev->type >= INTEL_440BX) ? &(regs[0x73]) : &(regs[0x71]); uint32_t s; uint32_t base[2] = { 0x000a0000, 0x00000000 }; @@ -165,8 +172,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev) } else { size[0] = 0x00010000; switch (*reg & 0x03) { - case 0: default: + case 0: base[0] = (mem_size << 10) - size[0]; s = 1; break; @@ -222,17 +229,17 @@ i4x0_mask_bar(uint8_t *regs, void *agpgart) } static uint8_t -pm2_cntrl_read(uint16_t addr, void *p) +pm2_cntrl_read(UNUSED(uint16_t addr), void *priv) { - i4x0_t *dev = (i4x0_t *) p; + const i4x0_t *dev = (i4x0_t *) priv; return dev->pm2_cntrl & 0x01; } static void -pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) +pm2_cntrl_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { - i4x0_t *dev = (i4x0_t *) p; + i4x0_t *dev = (i4x0_t *) priv; dev->pm2_cntrl = val & 0x01; } @@ -251,6 +258,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: /*Command register*/ switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: @@ -258,7 +266,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: - default: regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); break; case INTEL_430FX: @@ -291,16 +298,18 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[0x05] = val & 0x01; break; + default: + break; } break; case 0x07: switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: - default: regs[0x07] &= ~(val & 0x70); break; case INTEL_430FX: @@ -343,6 +352,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[0x0f] = (val & 0x40); break; + default: + break; } break; case 0x12: @@ -355,6 +366,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x12] = (val & 0xc0); i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; case 0x13: @@ -367,6 +380,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x13] = val; i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; case 0x2c: @@ -382,6 +397,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs_l[addr] = 1; } break; + default: + break; } break; @@ -396,14 +413,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[0x4f] = (val & 0x80); break; + default: + break; } break; case 0x50: switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: - default: regs[0x50] = (val & 0xe5); break; case INTEL_430NX: @@ -467,17 +486,19 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x51] = (regs[0x51] & 0xb0) | (val & 0x4f); i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; case 0x52: /* Cache Control Register */ switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - default: regs[0x52] = (val & 0xfb); break; case INTEL_430NX: @@ -515,6 +536,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) /* Not applicable to 440ZX as that does not support ECC. */ regs[0x53] = val; break; + default: + break; } break; case 0x54: @@ -534,6 +557,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440FX: regs[0x54] = val & 0x82; break; + default: + break; } break; case 0x55: @@ -553,6 +578,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[0x55] = val; break; + default: + break; } break; case 0x56: @@ -577,6 +604,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[0x56] = val; break; + default: + break; } break; case 0x57: @@ -628,10 +657,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x58: switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: - default: regs[0x58] = val & 0x01; break; case INTEL_430NX: @@ -720,6 +749,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; } switch (dev->type) { + default: case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: @@ -731,7 +761,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: case INTEL_440GX: - default: regs[addr] = val; break; case INTEL_430FX: @@ -768,6 +797,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[addr] = val & 0x7f; break; + default: + break; } break; case 0x66: @@ -786,6 +817,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[addr] = val; break; + default: + break; } break; case 0x67: @@ -810,6 +843,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: regs[addr] = val & 0xb7; break; + default: + break; } break; case 0x68: @@ -838,6 +873,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0); break; + default: + break; } break; case 0x69: @@ -856,6 +893,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[0x69] = val & 0x3f; break; + default: + break; } break; case 0x6a: @@ -880,6 +919,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) else regs[addr] = val & 0x33; break; + default: + break; } break; case 0x6c: @@ -899,6 +940,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) else if (addr == 0x6d) regs[addr] = val & 0xcf; break; + default: + break; } break; case 0x6f: @@ -909,6 +952,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[addr] = val & 0xcf; break; + default: + break; } break; case 0x70: @@ -930,6 +975,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[addr] = val & 0xf8; break; + default: + break; } break; case 0x71: @@ -953,6 +1000,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: regs[addr] = val & 0x1f; break; + default: + break; } break; case 0x72: /* SMRAM */ @@ -998,6 +1047,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) i4x0_smram_handler_phase1(dev); } break; + default: + break; } break; case 0x74: @@ -1008,6 +1059,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x74] = val; break; + default: + break; } break; case 0x75: @@ -1018,6 +1071,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: case INTEL_440GX: regs[addr] = val; + break; + + default: + break; } break; case 0x77: @@ -1025,6 +1082,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0x77] = val & 0x03; + break; + + default: + break; } break; case 0x78: @@ -1039,6 +1100,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x78] = val & 0x1f; break; + default: + break; } break; case 0x79: @@ -1054,6 +1117,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x79] = val; break; + default: + break; } break; case 0x7a: @@ -1066,6 +1131,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (val & 0x40) io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); break; + default: + break; } break; case 0x7c: @@ -1081,6 +1148,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[0x7c] = val & 0x1f; break; + default: + break; } break; case 0x7d: @@ -1091,6 +1160,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: regs[0x7d] = val & 0x32; break; + default: + break; } break; case 0x7e: @@ -1102,6 +1173,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: regs[addr] = val; break; + default: + break; } break; case 0x80: @@ -1111,6 +1184,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x80] &= ~(val & 0x03); break; + default: + break; } break; case 0x90: @@ -1132,6 +1207,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x90] = val; break; + default: + break; } break; case 0x91: @@ -1144,6 +1221,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) /* Not applicable on 82443EX and 82443ZX. */ regs[0x91] &= ~(val & 0x11); break; + default: + break; } break; case 0x92: @@ -1157,18 +1236,22 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0x92] &= ~(val & 0x1f); break; + default: + break; } break; case 0x93: switch (dev->type) { case INTEL_440FX: regs[0x93] = (val & 0x0f); - trc_write(0x0093, val & 0x06, NULL); + pci_write(0x0cf9, val & 0x06, NULL); break; case INTEL_440LX: case INTEL_440EX: regs[0x93] = (val & 0x0e); - trc_write(0x0093, val & 0x06, NULL); + pci_write(0x0cf9, val & 0x06, NULL); + break; + default: break; } break; @@ -1178,6 +1261,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[0xa7] = val & 0x1f; break; + default: + break; } break; case 0xa8: @@ -1190,6 +1275,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[addr] = (val & 0x03); break; + default: + break; } break; case 0xb0: @@ -1201,6 +1288,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0xb0] = (val & 0x80); break; + default: + break; } break; case 0xb1: @@ -1214,6 +1303,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0xb1] = (val & 0xa0); break; + default: + break; } break; case 0xb4: @@ -1226,6 +1317,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0xb4] = (val & 0x3f); i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; case 0xb9: @@ -1238,6 +1331,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0xb9] = (val & 0xf0); i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; @@ -1252,6 +1347,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[addr] = val; i4x0_mask_bar(regs, dev->agpgart); break; + default: + break; } break; @@ -1261,6 +1358,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[addr] = (val & 0xf8); break; + default: + break; } break; @@ -1270,6 +1369,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440EX: regs[addr] = (val & 0xf8); break; + default: + break; } break; @@ -1287,6 +1388,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[addr] = val; break; + default: + break; } break; case 0xca: @@ -1298,6 +1401,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[addr] = val & 0xe7; break; + default: + break; } break; case 0xcb: @@ -1309,6 +1414,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[addr] = val & 0xa7; break; + default: + break; } break; case 0xcc: @@ -1320,6 +1427,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440ZX: regs[0xcc] = (val & 0x58); break; + default: + break; } break; case 0xe0: @@ -1339,6 +1448,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (!regs_l[addr]) regs[addr] = val; break; + default: + break; } break; case 0xe5: @@ -1350,6 +1461,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (!regs_l[addr]) regs[addr] = (val & 0x3f); break; + default: + break; } break; case 0xe7: @@ -1364,6 +1477,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0xe7] |= (val & 0x7f); } break; + default: + break; } break; case 0xf0: @@ -1373,6 +1488,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0xf0] = (val & 0xc0); break; + default: + break; } break; case 0xf1: @@ -1382,24 +1499,31 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440GX: regs[0xf1] = (val & 0x03); break; + default: + break; } break; + + default: + break; } } static uint8_t i4x0_read(int func, int addr, void *priv) { - i4x0_t *dev = (i4x0_t *) priv; - uint8_t ret = 0xff; - uint8_t *regs = (uint8_t *) dev->regs; + i4x0_t *dev = (i4x0_t *) priv; + uint8_t ret = 0xff; + const uint8_t *regs = (uint8_t *) dev->regs; if (func == 0) { ret = regs[addr]; /* Special behavior for 440FX register 0x93 which is basically TRC in PCI space with the addition of bits 3 and 0. */ if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX))) - ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06); + ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06); + else if ((func == 0) && (addr == 0x52) && (dev->type == INTEL_430TX) && !strcmp(machine_get_internal_name(), "tomahawk")) + ret = 0xb2; } return ret; @@ -1409,7 +1533,6 @@ static void i4x0_reset(void *priv) { i4x0_t *dev = (i4x0_t *) priv; - int i; if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t)); @@ -1419,11 +1542,16 @@ i4x0_reset(void *priv) else i4x0_write(0, 0x59, 0x0f, priv); - for (i = 0; i < 6; i++) + for (uint8_t i = 0; i < 6; i++) i4x0_write(0, 0x5a + i, 0x00, priv); - for (i = 0; i <= dev->max_drb; i++) - i4x0_write(0, 0x60 + i, dev->drb_default, priv); + for (uint8_t i = 0; i <= dev->max_drb; i++) + dev->regs[0x60 + i] = dev->drb_default; + + if (dev->type >= INTEL_430NX) { + for (uint8_t i = 0; i < 4; i++) + dev->regs[0x68 + i] = 0x00; + } if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ @@ -1443,9 +1571,9 @@ i4x0_reset(void *priv) } static void -i4x0_close(void *p) +i4x0_close(void *priv) { - i4x0_t *dev = (i4x0_t *) p; + i4x0_t *dev = (i4x0_t *) priv; smram_del(dev->smram_high); smram_del(dev->smram_low); @@ -1453,9 +1581,8 @@ i4x0_close(void *p) free(dev); } -static void - * - i4x0_init(const device_t *info) +static void * +i4x0_init(const device_t *info) { i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t)); uint8_t *regs; @@ -1508,7 +1635,7 @@ static void regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02; dev->max_drb = 3; - dev->drb_unit = 4; + dev->drb_unit = 1; dev->drb_default = 0x02; break; case INTEL_430LX: @@ -1547,11 +1674,12 @@ static void regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ regs[0x57] = 0x31; regs[0x59] = 0x0f; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 1; - dev->drb_default = 0x02; - dev->write_drbs = spd_write_drbs_with_ext; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 1; + dev->drb_default = 0x02; + dev->write_drbs = spd_write_drbs_with_ext; break; case INTEL_430FX: regs[0x02] = 0x2d; @@ -1580,11 +1708,12 @@ static void regs[0x57] |= 0x02; else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) regs[0x57] |= 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 4; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 4; + dev->drb_default = 0x02; break; case INTEL_430VX: regs[0x02] = 0x30; @@ -1639,12 +1768,13 @@ static void regs[0x53] = 0x80; regs[0x57] = 0x01; regs[0x58] = 0x10; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x71] = 0x10; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x71] = 0x10; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x02; break; case INTEL_440LX: regs[0x02] = 0x80; @@ -1659,7 +1789,8 @@ static void regs[0x51] |= 0x00; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1681,7 +1812,8 @@ static void regs[0x51] = 0x80; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1709,19 +1841,20 @@ static void regs[0x51] |= 0x00; regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; break; case INTEL_440GX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1732,19 +1865,22 @@ static void regs[0x10] = 0x08; regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; regs[0x57] = 0x28; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; + break; + default: break; } @@ -1786,12 +1922,12 @@ static void (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); } - pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot); if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) { device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device); dev->agpgart = device_add(&agpgart_device); - } else if (dev->type >= INTEL_440LX) { + } else if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) { device_add(&i440lx_agp_device); dev->agpgart = device_add(&agpgart_device); } @@ -1982,7 +2118,7 @@ const device_t i440bx_device = { }; const device_t i440bx_no_agp_device = { - .name = "Intel 82443BX", + .name = "Intel 82443BX (No AGP)", .internal_name = "i440bx_no_agp", .flags = DEVICE_PCI, .local = 0x8200 | INTEL_440BX, diff --git a/src/chipset/intel_82335.c b/src/chipset/intel_82335.c index 678c868f31..da0cc30f60 100644 --- a/src/chipset/intel_82335.c +++ b/src/chipset/intel_82335.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> /* Shadow capabilities */ #define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) @@ -56,12 +57,10 @@ #define DEFINE_RC1_REMAP_SIZE ((dev->regs[0x24] & 0x02) ? 128 : 256) #define DEFINE_RC2_REMAP_SIZE ((dev->regs[0x26] & 0x02) ? 128 : 256) -typedef struct -{ - - uint16_t regs[256], +typedef struct intel_82335_t { + uint16_t regs[256]; - cfg_locked; + uint16_t cfg_locked; } intel_82335_t; @@ -109,7 +108,9 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv) shadowbios_write = !!(dev->regs[0x22] & 0x01); /* Base System 512/640KB set */ - // mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB); +#if 0 + mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB); +#endif /* Video RAM shadow*/ mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW); @@ -137,8 +138,11 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv) shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize); mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC); } - break; } + break; + + default: + break; } } @@ -149,7 +153,7 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv) static uint16_t intel_82335_read(uint16_t addr, void *priv) { - intel_82335_t *dev = (intel_82335_t *) priv; + const intel_82335_t *dev = (intel_82335_t *) priv; intel_82335_log("Register %02x: Read %04x\n", addr, dev->regs[addr]); @@ -165,7 +169,7 @@ intel_82335_close(void *priv) } static void * -intel_82335_init(const device_t *info) +intel_82335_init(UNUSED(const device_t *info)) { intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t)); memset(dev, 0, sizeof(intel_82335_t)); diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index de6d25422e..2f65473092 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -8,19 +8,14 @@ * * Implementation of the Intel 450KX Mars Chipset. * + * i450GX is way more popular of an option but needs more stuff. * + * Authors: Miran Grca, + * Tiseno100, * - * Authors: Tiseno100 - * + * Copyright 2021-2024 Miran Grca. * Copyright 2021 Tiseno100. */ - -/* -Note: i450KX PB manages PCI memory access with MC manages DRAM memory access. -Due to 86Box limitations we can't manage them seperately thus it is dev branch till then. - -i450GX is way more popular of an option but needs more stuff. -*/ #include #include #include @@ -35,6 +30,7 @@ i450GX is way more popular of an option but needs more stuff. #include <86box/device.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/smram.h> #include <86box/spd.h> #include <86box/chipset.h> @@ -61,10 +57,15 @@ i450kx_log(const char *fmt, ...) typedef struct i450kx_t { smram_t *smram[2]; - uint8_t pb_pci_conf[256], mc_pci_conf[256]; - uint8_t mem_state[2][256]; - uint8_t bus_index; + uint8_t pb_slot; + uint8_t mc_slot; + uint8_t pad; + + uint8_t pb_pci_conf[256]; + uint8_t mc_pci_conf[256]; + + uint8_t mem_state[2][256]; } i450kx_t; static void @@ -88,20 +89,21 @@ i450kx_map(i450kx_t *dev, int bus, uint32_t addr, uint32_t size, int state) static void i450kx_smram_recalc(i450kx_t *dev, int bus) { - uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; - uint32_t addr; - uint32_t size; + const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + uint32_t addr; + uint32_t size; + int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08); smram_disable(dev->smram[bus]); addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; - if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if ((addr != 0x00000000) && enable) { if (bus) - smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable); else - smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0); } flushmmucache(); @@ -110,10 +112,10 @@ i450kx_smram_recalc(i450kx_t *dev, int bus) static void i450kx_vid_buf_recalc(i450kx_t *dev, int bus) { - uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; - // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); - int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); if (bus) mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); @@ -128,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x04: dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); @@ -167,8 +169,10 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0x4a: case 0x4b: dev->pb_pci_conf[addr] = val; - // if (addr == 0x4a) - // pci_remap_bus(dev->bus_index, val); +#if 0 + if (addr == 0x4a) + pci_remap_bus(dev->bus_index, val); +#endif break; case 0x4c: @@ -320,13 +324,6 @@ pb_write(int func, int addr, uint8_t val, void *priv) dev->pb_pci_conf[addr] = val & /*0x1a*/ 0x1f; break; - case 0xb4: - dev->pb_pci_conf[addr] = val & 0xe0; - break; - case 0xb5: - dev->pb_pci_conf[addr] = val & 0x1f; - break; - case 0xb8: case 0xb9: dev->pb_pci_conf[addr] = val; @@ -366,19 +363,25 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0xcb: dev->pb_pci_conf[addr] = val; break; + + default: + break; } + } } static uint8_t pb_read(int func, int addr, void *priv) { - i450kx_t *dev = (i450kx_t *) priv; + const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->pb_pci_conf[addr]; - // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -401,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; - // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + if (func == 0) { + i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, val); - if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; @@ -590,19 +593,25 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0xcb: dev->mc_pci_conf[addr] = val; break; + + default: + break; } + } } static uint8_t mc_read(int func, int addr, void *priv) { - i450kx_t *dev = (i450kx_t *) priv; + const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; - if (func == 0) + if (func == 0) { ret = dev->mc_pci_conf[addr]; - // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc, + addr, ret); + } return ret; } @@ -613,8 +622,6 @@ i450kx_reset(void *priv) i450kx_t *dev = (i450kx_t *) priv; uint32_t i; - // pclog("i450KX: i450kx_reset()\n"); - /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; @@ -671,9 +678,11 @@ i450kx_reset(void *priv) dev->pb_pci_conf[0xa6] = 0xfe; dev->pb_pci_conf[0xa7] = 0x00; /* Note: Do NOT reset these two registers on programmed (TRC) hard reset! */ - // dev->pb_pci_conf[0xb0] = 0x00; - // dev->pb_pci_conf[0xb1] = 0x00; - dev->pb_pci_conf[0xb4] = 0x00; +#if 0 + dev->pb_pci_conf[0xb0] = 0x00; + dev->pb_pci_conf[0xb1] = 0x00; +#endif + dev->pb_pci_conf[0xb4] = 0xff; dev->pb_pci_conf[0xb5] = 0x00; dev->pb_pci_conf[0xb8] = 0x05; dev->pb_pci_conf[0xb9] = 0x00; @@ -693,7 +702,9 @@ i450kx_reset(void *priv) dev->pb_pci_conf[0xca] = 0x00; dev->pb_pci_conf[0xcb] = 0x00; - // pci_remap_bus(dev->bus_index, 0x00); +#if 0 + pci_remap_bus(dev->bus_index, 0x00); +#endif i450kx_smram_recalc(dev, 1); i450kx_vid_buf_recalc(dev, 1); pb_write(0, 0x59, 0x30, dev); @@ -786,12 +797,12 @@ i450kx_close(void *priv) } static void * -i450kx_init(const device_t *info) +i450kx_init(UNUSED(const device_t *info)) { i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t)); memset(dev, 0, sizeof(i450kx_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */ - pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */ + pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */ + pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */ dev->smram[0] = smram_add(); dev->smram[1] = smram_add(); diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 3a65d5de3a..1f95c28b35 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -40,6 +40,7 @@ #include <86box/pci.h> #include <86box/pic.h> #include <86box/pit.h> +#include <86box/plat.h> #include <86box/port_92.h> #include <86box/scsi_device.h> #include <86box/hdc.h> @@ -50,7 +51,7 @@ #include <86box/smbus.h> #include <86box/chipset.h> -typedef struct { +typedef struct piix_io_trap_t { struct _piix_ *dev; void *trap; uint8_t dev_id; @@ -58,14 +59,18 @@ typedef struct { } piix_io_trap_t; typedef struct _piix_ { - uint8_t cur_readout_reg, rev, - type, func_shift, - max_func, pci_slot, - no_mirq0, pad, - regs[4][256], - readout_regs[256], board_config[2]; - uint16_t func0_id, nvr_io_base, - acpi_io_base; + uint8_t cur_readout_reg; + uint8_t rev; + uint8_t type; + uint8_t func_shift; + uint8_t max_func; + uint8_t pci_slot; + uint8_t no_mirq0; + uint8_t regs[4][256]; + uint8_t readout_regs[256]; + uint16_t func0_id; + uint16_t nvr_io_base; + uint16_t acpi_io_base; double fast_off_period; sff8038i_t *bm[2]; smbus_piix4_t *smbus; @@ -77,7 +82,6 @@ typedef struct _piix_ { piix_io_trap_t io_traps[26]; port_92_t *port_92; pc_timer_t fast_off_timer; - usb_params_t usb_params; } piix_t; #ifdef ENABLE_PIIX_LOG @@ -102,13 +106,13 @@ static void smsc_ide_irqs(piix_t *dev) { int irq_line = 3; - uint8_t irq_mode[2] = { 0, 0 }; + uint8_t irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; if (dev->regs[1][0x09] & 0x01) - irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; + irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN; if (dev->regs[1][0x09] & 0x04) - irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; + irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN; switch ((dev->regs[0][0xe1] >> 1) & 0x07) { case 0x00: @@ -135,15 +139,15 @@ smsc_ide_irqs(piix_t *dev) case 0x07: irq_line = 15; break; + default: + break; } sff_set_irq_line(dev->bm[0], irq_line); - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); sff_set_irq_line(dev->bm[1], irq_line); - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); } static void @@ -203,7 +207,7 @@ piix_ide_bm_handlers(piix_t *dev) } static uint8_t -kbc_alias_reg_read(uint16_t addr, void *p) +kbc_alias_reg_read(UNUSED(uint16_t addr), UNUSED(void *priv)) { uint8_t ret = inb(0x61); @@ -211,7 +215,7 @@ kbc_alias_reg_read(uint16_t addr, void *p) } static void -kbc_alias_reg_write(uint16_t addr, uint8_t val, void *p) +kbc_alias_reg_write(UNUSED(uint16_t addr), uint8_t val, UNUSED(void *priv)) { outb(0x61, val); } @@ -267,7 +271,7 @@ nvr_update_io_mapping(piix_t *dev) } static void -piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +piix_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv) { piix_io_trap_t *trap = (piix_io_trap_t *) priv; @@ -280,7 +284,7 @@ piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) static void piix_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) { - piix_io_trap_t *trap = (piix_io_trap_t *) priv; + const piix_io_trap_t *trap = (piix_io_trap_t *) priv; /* IDE traps are per drive, not per channel. */ if (ide_drives[trap->dev_id]->selected) @@ -318,10 +322,10 @@ piix_trap_update_devctl(piix_t *dev, uint8_t trap_id, uint8_t dev_id, static void piix_trap_update(void *priv) { - piix_t *dev = (piix_t *) priv; - uint8_t trap_id = 0; - uint8_t *fregs = dev->regs[3]; - uint16_t temp; + piix_t *dev = (piix_t *) priv; + uint8_t trap_id = 0; + const uint8_t *fregs = dev->regs[3]; + uint16_t temp; piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x1f0, 8); piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x3f6, 1); @@ -555,8 +559,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x6a: switch (dev->type) { - case 1: default: + case 1: fregs[0x6a] = (fregs[0x6a] & 0xfb) | (val & 0x04); fregs[0x0e] = (val & 0x04) ? 0x80 : 0x00; piix_log("PIIX: Write %02X\n", val); @@ -593,6 +597,12 @@ piix_write(int func, int addr, uint8_t val, void *priv) pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); else pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + if (dev->type == 3) { + if (val & 0x20) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled"); } break; @@ -791,6 +801,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) } } break; + default: + break; } else if (func == 1) switch (addr) { /* IDE */ @@ -1000,11 +1012,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0xc0: if (dev->type <= 4) - fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20); + fregs[0xc0] = (fregs[0xc0] & 0x40) | (val & 0xbf); break; case 0xc1: if (dev->type <= 4) - fregs[0xc1] &= ~val; + fregs[0xc1] = (fregs[0xc0] & ~(val & 0x8f)) | (val & 0x20); break; case 0xff: if (dev->type == 4) { @@ -1012,6 +1024,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) nvr_read_addr_set(!!(val & 0x10), dev->nvr); } break; + default: + break; } else if (func == 3) switch (addr) { /* Power Management */ @@ -1145,15 +1159,17 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[0x91] = val; smbus_update_io_mapping(dev); break; + default: + break; } } static uint8_t piix_read(int func, int addr, void *priv) { - piix_t *dev = (piix_t *) priv; - uint8_t ret = 0xff; - uint8_t *fregs; + piix_t *dev = (piix_t *) priv; + uint8_t ret = 0xff; + const uint8_t *fregs; if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40)) ret = 0x00; @@ -1162,8 +1178,6 @@ piix_read(int func, int addr, void *priv) if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; - if ((func == 2) && (addr == 0xff)) - ret |= 0xef; piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr); } @@ -1176,9 +1190,7 @@ board_write(uint16_t port, uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; - if (port == 0x0078) - dev->board_config[0] = val; - else if (port == 0x00e0) + if (port == 0x00e0) dev->cur_readout_reg = val; else if (port == 0x00e1) dev->readout_regs[dev->cur_readout_reg] = val; @@ -1187,14 +1199,10 @@ board_write(uint16_t port, uint8_t val, void *priv) static uint8_t board_read(uint16_t port, void *priv) { - piix_t *dev = (piix_t *) priv; - uint8_t ret = 0x64; + const piix_t *dev = (piix_t *) priv; + uint8_t ret = 0x64; - if (port == 0x0078) - ret = dev->board_config[0]; - else if (port == 0x0079) - ret = dev->board_config[1]; - else if (port == 0x00e0) + if (port == 0x00e0) ret = dev->cur_readout_reg; else if (port == 0x00e1) ret = dev->readout_regs[dev->cur_readout_reg]; @@ -1207,23 +1215,19 @@ piix_reset_hard(piix_t *dev) { uint8_t *fregs; - uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); - - sff_bus_master_reset(dev->bm[0], old_base); - sff_bus_master_reset(dev->bm[1], old_base + 8); + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); if (dev->type >= 4) { sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_irq_pin(dev->bm[0], PCI_INTA); sff_set_irq_line(dev->bm[0], 14); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); sff_set_slot(dev->bm[1], dev->pci_slot); sff_set_irq_pin(dev->bm[1], PCI_INTA); sff_set_irq_line(dev->bm[1], 14); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); } #ifdef ENABLE_PIIX_LOG @@ -1409,9 +1413,9 @@ piix_reset_hard(piix_t *dev) } static void -piix_apm_out(uint16_t port, uint8_t val, void *p) +piix_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv) { - piix_t *dev = (piix_t *) p; + piix_t *dev = (piix_t *) priv; if (dev->apm->do_smi) { if (dev->type < 4) @@ -1429,96 +1433,81 @@ piix_fast_off_count(void *priv) } static void -piix_usb_update_interrupt(usb_t* usb, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if (usb->irq_level) - pci_set_irq(dev->pci_slot, PCI_INTD); - else - pci_clear_irq(dev->pci_slot, PCI_INTD); -} - -static void -piix_reset(void *p) +piix_reset(void *priv) { - piix_t *dev = (piix_t *) p; + const piix_t *dev = (piix_t *) priv; if (dev->type > 3) { - piix_write(3, 0x04, 0x00, p); - piix_write(3, 0x5b, 0x00, p); + piix_write(3, 0x04, 0x00, priv); + piix_write(3, 0x5b, 0x00, priv); } else { - piix_write(0, 0xa0, 0x08, p); - piix_write(0, 0xa2, 0x00, p); - piix_write(0, 0xa4, 0x00, p); - piix_write(0, 0xa5, 0x00, p); - piix_write(0, 0xa6, 0x00, p); - piix_write(0, 0xa7, 0x00, p); - piix_write(0, 0xa8, 0x0f, p); + 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); } /* Disable the PIC mouse latch. */ - piix_write(0, 0x4e, 0x03, p); + piix_write(0, 0x4e, 0x03, priv); if (dev->type == 5) - piix_write(0, 0xe1, 0x40, p); - piix_write(1, 0x04, 0x00, p); + piix_write(0, 0xe1, 0x40, priv); + piix_write(1, 0x04, 0x00, priv); if (dev->type == 5) { - piix_write(1, 0x09, 0x8a, p); - piix_write(1, 0x10, 0xf1, p); - piix_write(1, 0x11, 0x01, p); - piix_write(1, 0x14, 0xf5, p); - piix_write(1, 0x15, 0x03, p); - piix_write(1, 0x18, 0x71, p); - piix_write(1, 0x19, 0x01, p); - piix_write(1, 0x1c, 0x75, p); - piix_write(1, 0x1d, 0x03, p); + 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); } else - piix_write(1, 0x09, 0x80, p); - piix_write(1, 0x20, 0x01, p); - piix_write(1, 0x21, 0x00, p); - piix_write(1, 0x41, 0x00, p); - piix_write(1, 0x43, 0x00, p); + 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); ide_pri_disable(); ide_sec_disable(); if (dev->type >= 3) { - piix_write(2, 0x04, 0x00, p); + piix_write(2, 0x04, 0x00, priv); if (dev->type == 5) { - piix_write(2, 0x10, 0x00, p); - piix_write(2, 0x11, 0x00, p); - piix_write(2, 0x12, 0x00, p); - piix_write(2, 0x13, 0x00, p); + piix_write(2, 0x10, 0x00, priv); + piix_write(2, 0x11, 0x00, priv); + piix_write(2, 0x12, 0x00, priv); + piix_write(2, 0x13, 0x00, priv); } else { - piix_write(2, 0x20, 0x01, p); - piix_write(2, 0x21, 0x00, p); - piix_write(2, 0x22, 0x00, p); - piix_write(2, 0x23, 0x00, p); + piix_write(2, 0x20, 0x01, priv); + piix_write(2, 0x21, 0x00, priv); + piix_write(2, 0x22, 0x00, priv); + piix_write(2, 0x23, 0x00, priv); } } if (dev->type >= 4) { - piix_write(0, 0xb0, is_pentium ? 0x00 : 0x04, p); - piix_write(3, 0x40, 0x01, p); - piix_write(3, 0x41, 0x00, p); - piix_write(3, 0x5b, 0x00, p); - piix_write(3, 0x80, 0x00, p); - piix_write(3, 0x90, 0x01, p); - piix_write(3, 0x91, 0x00, p); - piix_write(3, 0xd2, 0x00, p); + 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); } - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (dev->no_mirq0 || (dev->type >= 4)) { - sff_set_irq_mode(dev->bm[0], 1, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } else { - sff_set_irq_mode(dev->bm[0], 1, 2); - sff_set_irq_mode(dev->bm[1], 1, 2); - } + if (dev->no_mirq0 || (dev->type >= 4)) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); } static void @@ -1539,10 +1528,10 @@ piix_speed_changed(void *priv) if (!dev) return; - int te = timer_is_enabled(&dev->fast_off_timer); + int to = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); - if (te) + if (to) timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period); } @@ -1559,7 +1548,7 @@ piix_init(const device_t *info) dev->no_mirq0 = (info->local >> 12) & 0x0f; dev->func0_id = info->local >> 16; - dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev); + 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); piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); @@ -1572,23 +1561,15 @@ piix_init(const device_t *info) ide_board_set_force_ata3(1, 1); } - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (dev->no_mirq0 || (dev->type >= 4)) { - sff_set_irq_mode(dev->bm[0], 1, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } else { - sff_set_irq_mode(dev->bm[0], 1, 2); - sff_set_irq_mode(dev->bm[1], 1, 2); - } + if (dev->no_mirq0 || (dev->type >= 4)) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); - if (dev->type >= 3) { - dev->usb_params.parent_priv = dev; - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = piix_usb_update_interrupt; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); - } + if (dev->type >= 3) + dev->usb = device_add(&usb_device); if (dev->type > 3) { dev->nvr = device_add(&piix4_nvr_device); @@ -1597,7 +1578,16 @@ piix_init(const device_t *info) dev->acpi = device_add(&acpi_intel_device); acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); - acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); + /* + TriGem Richmond: + - Bit 5: Manufacturing jumper, must be set; + - Bit 4: CMOS clear jumper, must be clear; + - Bit 0: Password switch, must be clear. + */ + if (!strcmp(machine_get_internal_name(), "richmond")) + acpi_set_gpireg2_default(dev->acpi, 0xee); + else + acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); acpi_set_trap_update(dev->acpi, piix_trap_update, dev); dev->ddma = device_add(&ddma_device); @@ -1623,7 +1613,10 @@ piix_init(const device_t *info) dev->port_92 = device_add(&port_92_pci_device); - cpu_set_isa_pci_div(4); + if (cpu_busspeed > 50000000) + cpu_set_isa_pci_div(4); + else + cpu_set_isa_pci_div(3); dma_alias_set(); @@ -1664,38 +1657,11 @@ piix_init(const device_t *info) else if (cpu_dmulti > 2.5) dev->readout_regs[1] |= 0x80; - io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); - dev->board_config[0] = 0xff; - /* Register 0x0079: */ - /* Bit 7: 0 = Clear password, 1 = Keep password. */ - /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ - /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ - /* Bit 4: External CPU clock (Switch 8). */ - /* Bit 3: External CPU clock (Switch 7). */ - /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ - /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ - /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ - /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ - /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ - /* Bit 0: 0 = 1.5x multiplier, 1 = 2x multiplier (Switch 6). */ - /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ - dev->board_config[1] = 0xe0; - - if (cpu_busspeed <= 50000000) - dev->board_config[1] |= 0x10; - else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) - dev->board_config[1] |= 0x18; - else if (cpu_busspeed > 60000000) - dev->board_config[1] |= 0x00; - - if (cpu_dmulti <= 1.5) - dev->board_config[1] |= 0x01; - else - dev->board_config[1] |= 0x00; - - // device_add(&i8254_sec_device); +#if 0 + device_add(&i8254_sec_device); +#endif return dev; } diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 26f3cb422b..03a292da8f 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -33,18 +33,23 @@ #include <86box/port_92.h> #include <86box/machine.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> -typedef struct -{ - uint8_t id, - regs[256]; +typedef struct sio_t { + uint8_t id; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + + uint8_t regs[256]; - uint16_t timer_base, - timer_latch; + uint16_t timer_base; + uint16_t timer_latch; double fast_off_period; - pc_timer_t timer, fast_off_timer; + pc_timer_t timer; + pc_timer_t fast_off_timer; apm_t *apm; port_92_t *port_92; @@ -315,14 +320,16 @@ sio_write(int func, int addr, uint8_t val, void *priv) cpu_fast_off_count = val + 1; cpu_fast_off_period_set(cpu_fast_off_val, dev->fast_off_period); break; + default: + break; } } static uint8_t sio_read(int func, int addr, void *priv) { - sio_t *dev = (sio_t *) priv; - uint8_t ret; + const sio_t *dev = (sio_t *) priv; + uint8_t ret; ret = 0xff; @@ -333,12 +340,13 @@ sio_read(int func, int addr, void *priv) } static void -sio_config_write(uint16_t addr, uint8_t val, void *priv) +sio_config_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), UNUSED(void *priv)) { + // } static uint8_t -sio_config_read(uint16_t port, void *priv) +sio_config_read(uint16_t port, UNUSED(void *priv)) { uint8_t ret = 0x00; @@ -365,6 +373,9 @@ sio_config_read(uint16_t port, void *priv) break; } break; + + default: + break; } return ret; @@ -425,9 +436,9 @@ sio_reset_hard(void *priv) } static void -sio_apm_out(uint16_t port, uint8_t val, void *p) +sio_apm_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv) { - sio_t *dev = (sio_t *) p; + sio_t *dev = (sio_t *) priv; if (dev->apm->do_smi) dev->regs[0xaa] |= 0x80; @@ -443,32 +454,32 @@ sio_fast_off_count(void *priv) } static void -sio_reset(void *p) +sio_reset(void *priv) { - sio_t *dev = (sio_t *) p; + const sio_t *dev = (sio_t *) priv; /* Disable the PIC mouse latch. */ - sio_write(0, 0x4d, 0x40, p); + sio_write(0, 0x4d, 0x40, priv); - sio_write(0, 0x57, 0x04, p); + sio_write(0, 0x57, 0x04, priv); dma_set_params(1, 0xffffffff); if (dev->id == 0x03) { - sio_write(0, 0xa0, 0x08, p); - sio_write(0, 0xa2, 0x00, p); - sio_write(0, 0xa4, 0x00, p); - sio_write(0, 0xa5, 0x00, p); - sio_write(0, 0xa6, 0x00, p); - sio_write(0, 0xa7, 0x00, p); - sio_write(0, 0xa8, 0x0f, p); + 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); } } static void -sio_close(void *p) +sio_close(void *priv) { - sio_t *dev = (sio_t *) p; + sio_t *dev = (sio_t *) priv; free(dev); } @@ -486,7 +497,7 @@ sio_speed_changed(void *priv) timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); if (dev->id == 0x03) { - te = timer_is_enabled(&dev->fast_off_timer); + te = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); if (te) @@ -500,7 +511,7 @@ sio_init(const device_t *info) sio_t *dev = (sio_t *) malloc(sizeof(sio_t)); memset(dev, 0, sizeof(sio_t)); - pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot); dev->id = info->local; @@ -542,7 +553,9 @@ sio_init(const device_t *info) timer_add(&dev->timer, NULL, NULL, 0); - // device_add(&i8254_sec_device); +#if 0 + device_add(&i8254_sec_device); +#endif return dev; } diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 2613b8de9f..3b00b4ffde 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -30,6 +30,7 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> #define NEAT_DEBUG 0 @@ -200,7 +201,7 @@ #define RB11_EMSLEN 0xe0 /* EMS memory chunk size */ #define RB11_EMSLEN_SH 5 -typedef struct { +typedef struct emspage_t { int8_t enabled; /* 1=ENABLED */ char pad; uint16_t page; /* selected page in EMS block */ @@ -209,18 +210,18 @@ typedef struct { mem_mapping_t mapping; /* mapping entry for page */ } emspage_t; -typedef struct { +typedef struct neat_t { uint8_t regs[128]; /* all the CS8221 registers */ uint8_t indx; /* programmed index into registers */ char pad; - uint16_t ems_base, /* configured base address */ - ems_oldbase; - uint32_t ems_frame, /* configured frame address */ - ems_oldframe; - uint16_t ems_size, /* EMS size in KB */ - ems_pages; /* EMS size in pages */ + uint16_t ems_base; /* configured base address */ + uint16_t ems_oldbase; + uint32_t ems_frame; /* configured frame address */ + uint32_t ems_oldframe; + uint16_t ems_size; /* EMS size in KB */ + uint16_t ems_pages; /* EMS size in pages */ emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */ } neat_t; @@ -340,15 +341,17 @@ ems_write(uint16_t port, uint8_t val, void *priv) ems->page |= (val & 0x7f); /* add new bits */ ems_recalc(dev, ems); break; + default: + break; } } static uint8_t ems_read(uint16_t port, void *priv) { - neat_t *dev = (neat_t *) priv; - uint8_t ret = 0xff; - int vpage; + const neat_t *dev = (neat_t *) priv; + uint8_t ret = 0xff; + int vpage; /* Get the viewport page number. */ vpage = (port / EMS_PGSIZE); @@ -359,6 +362,8 @@ ems_read(uint16_t port, void *priv) if (dev->ems[vpage].enabled) ret |= 0x80; break; + default: + break; } #if NEAT_DEBUG > 1 @@ -372,12 +377,12 @@ ems_read(uint16_t port, void *priv) static void ems_init(neat_t *dev, int en) { - int i; + uint8_t j; /* Remove if needed. */ if (!en) { if (dev->ems_base > 0) - for (i = 0; i < EMS_MAXPAGE; i++) { + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { /* Disable for now. */ mem_mapping_disable(&dev->ems[i].mapping); @@ -394,19 +399,19 @@ ems_init(neat_t *dev, int en) } /* Get configured I/O address. */ - i = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH; - dev->ems_base = 0x0208 + (0x10 * i); + j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH; + dev->ems_base = 0x0208 + (0x10 * j); /* Get configured frame address. */ - i = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH; - dev->ems_frame = 0xC0000 + (EMS_PGSIZE * i); + j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH; + dev->ems_frame = 0xC0000 + (EMS_PGSIZE * j); /* * For each supported page (we can have a maximum of 4), * create, initialize and disable the mappings, and set * up the I/O control handler. */ - for (i = 0; i < EMS_MAXPAGE; i++) { + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { /* Create and initialize a page mapping. */ mem_mapping_add(&dev->ems[i].mapping, dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE, @@ -608,6 +613,8 @@ neat_write(uint16_t port, uint8_t val, void *priv) case 7: /* 7 MB */ dev->ems_size = i << 10; break; + default: + break; } dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE; if (dev->regs[REG_RB7] & RB7_EMSEN) { @@ -622,14 +629,16 @@ neat_write(uint16_t port, uint8_t val, void *priv) break; } break; + default: + break; } } static uint8_t neat_read(uint16_t port, void *priv) { - neat_t *dev = (neat_t *) priv; - uint8_t ret = 0xff; + const neat_t *dev = (neat_t *) priv; + uint8_t ret = 0xff; switch (port) { case 0x22: @@ -660,10 +669,11 @@ neat_close(void *priv) } static void * -neat_init(const device_t *info) +neat_init(UNUSED(const device_t *info)) { neat_t *dev; - int i; + uint8_t dram_mode = 0; + uint8_t i; /* Create an instance. */ dev = (neat_t *) malloc(sizeof(neat_t)); @@ -682,7 +692,6 @@ neat_init(const device_t *info) * TODO: We might also want to set 'valid' waitstate * bits, based on our cpu speed. */ - i = 0; switch (mem_size) { case 512: /* 512KB */ /* 256K, 0, 0, 0 */ @@ -690,7 +699,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */ - i = 2; + dram_mode = 2; break; case 640: /* 640KB */ @@ -699,7 +708,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */ - i = 4; + dram_mode = 4; break; case 1024: /* 1MB */ @@ -708,7 +717,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */ - i = 5; + dram_mode = 5; break; case 1536: /* 1.5MB */ @@ -717,7 +726,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */ - i = 7; + dram_mode = 7; break; case 1664: /* 1.64MB */ @@ -726,7 +735,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */ dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */ dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */ - i = 10; + dram_mode = 10; break; case 2048: /* 2MB */ @@ -737,14 +746,14 @@ neat_init(const device_t *info) dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */ dev->regs[REG_RB8] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */ - i = 11; + dram_mode = 11; #else /* 1M, 0, 0, 0 */ dev->regs[REG_RB6] &= ~RB6_BANKS; /* one bank */ dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */ - i = 3; + dram_mode = 3; #endif break; @@ -754,7 +763,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */ - i = 8; + dram_mode = 8; break; case 4096: /* 4MB */ @@ -763,7 +772,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_NONE << RTYPE_SH); /* NONE */ - i = 6; + dram_mode = 6; break; case 4224: /* 4.64MB */ @@ -772,7 +781,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_MIXED << RTYPE_SH); /* mixed */ dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */ dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */ - i = 12; + dram_mode = 12; break; case 5120: /* 5MB */ @@ -781,7 +790,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_256K << RTYPE_SH); /* 256K */ dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */ dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */ - i = 13; + dram_mode = 13; break; case 6144: /* 6MB */ @@ -790,7 +799,7 @@ neat_init(const device_t *info) dev->regs[REG_RB6] |= (RTYPE_1M << RTYPE_SH); /* 1M */ dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */ dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */ - i = 9; + dram_mode = 9; break; case 8192: /* 8MB */ @@ -800,13 +809,13 @@ neat_init(const device_t *info) dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */ dev->regs[REG_RB8] |= (RTYPE_1M << RTYPE_SH); /* 1M */ dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */ - i = 14; + dram_mode = 14; break; default: neat_log("NEAT: **INVALID DRAM SIZE %iKB !**\n", mem_size); } - if (i > 0) { + if (dram_mode > 0) { neat_log("NEAT: using DRAM mode #%i (mem=%iKB)\n", i, mem_size); } diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index ce9ba9a1fb..1f5eacc6cb 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -32,9 +32,9 @@ #include <86box/chipset.h> #include <86box/video.h> #include <86box/mem.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct olivetti_eva_t { uint8_t reg_065; uint8_t reg_067; uint8_t reg_069; @@ -77,20 +77,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv) * Unfortunately, if triggered, the BIOS remapping function fails causing * a fatal error. Therefore, this code section is currently commented. */ - // if (val & 1){ - // /* - // * Set the register to 7 or above for the BIOS to trigger the - // * memory remapping function if shadowing is active. - // */ - // dev->reg_069 = 0x7; - // } - // if (val & 8) { - // /* - // * Activate shadowing for region e0000-fffff - // */ - // mem_remap_top(256); - // mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - // } +#if 0 + if (val & 1) { + /* + * Set the register to 7 or above for the BIOS to trigger the + * memory remapping function if shadowing is active. + */ + dev->reg_069 = 0x7; + } + if (val & 8) { + /* + * Activate shadowing for region e0000-fffff + */ + mem_remap_top(256); + mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } +#endif + break; + default: break; } } @@ -98,8 +102,9 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv) static uint8_t olivetti_eva_read(uint16_t addr, void *priv) { - olivetti_eva_t *dev = (olivetti_eva_t *) priv; + const olivetti_eva_t *dev = (olivetti_eva_t *) priv; uint8_t ret = 0xff; + switch (addr) { case 0x065: ret = dev->reg_065; @@ -111,6 +116,8 @@ olivetti_eva_read(uint16_t addr, void *priv) case 0x069: ret = dev->reg_069; break; + default: + break; } olivetti_eva_log("Olivetti EVA Gate Array: Read %02x at %02x\n", ret, addr); return ret; @@ -125,7 +132,7 @@ olivetti_eva_close(void *priv) } static void * -olivetti_eva_init(const device_t *info) +olivetti_eva_init(UNUSED(const device_t *info)) { olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t)); memset(dev, 0, sizeof(olivetti_eva_t)); diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 8989139e4e..1fa59f2f05 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -29,6 +29,8 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> #ifdef ENABLE_OPTI283_LOG @@ -49,15 +51,15 @@ opti283_log(const char *fmt, ...) # define opti283_log(fmt, ...) #endif -typedef struct -{ - uint32_t phys, virt; +typedef struct mem_remapping_t { + uint32_t phys; + uint32_t virt; } mem_remapping_t; -typedef struct -{ - uint8_t index, shadow_high, - regs[256]; +typedef struct opti283_t { + uint8_t index; + uint8_t shadow_high; + uint8_t regs[256]; mem_remapping_t mem_remappings[2]; mem_mapping_t mem_mappings[2]; } opti283_t; @@ -65,7 +67,7 @@ typedef struct static uint8_t opti283_read_remapped_ram(uint32_t addr, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; return mem_read_ram((addr - dev->virt) + dev->phys, priv); } @@ -73,7 +75,7 @@ opti283_read_remapped_ram(uint32_t addr, void *priv) static uint16_t opti283_read_remapped_ramw(uint32_t addr, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; return mem_read_ramw((addr - dev->virt) + dev->phys, priv); } @@ -81,7 +83,7 @@ opti283_read_remapped_ramw(uint32_t addr, void *priv) static uint32_t opti283_read_remapped_raml(uint32_t addr, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; return mem_read_raml((addr - dev->virt) + dev->phys, priv); } @@ -89,7 +91,7 @@ opti283_read_remapped_raml(uint32_t addr, void *priv) static void opti283_write_remapped_ram(uint32_t addr, uint8_t val, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; mem_write_ram((addr - dev->virt) + dev->phys, val, priv); } @@ -97,7 +99,7 @@ opti283_write_remapped_ram(uint32_t addr, uint8_t val, void *priv) static void opti283_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; mem_write_ramw((addr - dev->virt) + dev->phys, val, priv); } @@ -105,7 +107,7 @@ opti283_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv) static void opti283_write_remapped_raml(uint32_t addr, uint32_t val, void *priv) { - mem_remapping_t *dev = (mem_remapping_t *) priv; + const mem_remapping_t *dev = (mem_remapping_t *) priv; mem_write_raml((addr - dev->virt) + dev->phys, val, priv); } @@ -227,23 +229,29 @@ opti283_write(uint16_t addr, uint8_t val, void *priv) case 0x14: reset_on_hlt = !!(val & 0x40); - /* FALLTHROUGH */ + fallthrough; case 0x11: case 0x12: case 0x13: dev->regs[dev->index] = val; opti283_shadow_recalc(dev); break; + + default: + break; } break; + + default: + break; } } static uint8_t opti283_read(uint16_t addr, void *priv) { - opti283_t *dev = (opti283_t *) priv; - uint8_t ret = 0xff; + const opti283_t *dev = (opti283_t *) priv; + uint8_t ret = 0xff; if (addr == 0x24) ret = dev->regs[dev->index]; @@ -260,7 +268,7 @@ opti283_close(void *priv) } static void * -opti283_init(const device_t *info) +opti283_init(UNUSED(const device_t *info)) { opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t)); memset(dev, 0x00, sizeof(opti283_t)); diff --git a/src/chipset/opti291.c b/src/chipset/opti291.c index b15b712609..6d22569744 100644 --- a/src/chipset/opti291.c +++ b/src/chipset/opti291.c @@ -28,6 +28,7 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -49,9 +50,9 @@ opti291_log(const char *fmt, ...) # define opti291_log(fmt, ...) #endif -typedef struct -{ - uint8_t index, regs[256]; +typedef struct opti291_t { + uint8_t index; + uint8_t regs[256]; port_92_t *port_92; } opti291_t; @@ -107,15 +108,21 @@ opti291_write(uint16_t addr, uint8_t val, void *priv) case 0x2c: dev->regs[dev->index] = val; break; + + default: + break; } break; + + default: + break; } } static uint8_t opti291_read(uint16_t addr, void *priv) { - opti291_t *dev = (opti291_t *) priv; + const opti291_t *dev = (opti291_t *) priv; return (addr == 0x24) ? dev->regs[dev->index] : 0xff; } @@ -129,7 +136,7 @@ opti291_close(void *priv) } static void * -opti291_init(const device_t *info) +opti291_init(UNUSED(const device_t *info)) { opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t)); memset(dev, 0, sizeof(opti291_t)); diff --git a/src/chipset/opti391.c b/src/chipset/opti391.c index 1aad0a8cc7..03cbb2ea7a 100644 --- a/src/chipset/opti391.c +++ b/src/chipset/opti391.c @@ -27,6 +27,7 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> #ifdef ENABLE_OPTI391_LOG @@ -47,20 +48,19 @@ opti391_log(const char *fmt, ...) # define opti391_log(fmt, ...) #endif -typedef struct -{ - uint32_t phys, virt; +typedef struct mem_remapping_t { + uint32_t phys; + uint32_t virt; } mem_remapping_t; -typedef struct -{ - uint8_t index, regs[256]; +typedef struct opti391_t { + uint8_t index; + uint8_t regs[256]; } opti391_t; static void opti391_shadow_recalc(opti391_t *dev) { - uint32_t i; uint32_t base; uint8_t sh_enable; uint8_t sh_master; @@ -78,7 +78,7 @@ opti391_shadow_recalc(opti391_t *dev) sh_write_internal = (dev->regs[0x26] & 0x40); /* D0000-EFFFF */ - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); if (base >= 0xe0000) { sh_master = (dev->regs[0x22] & 0x40); @@ -108,7 +108,7 @@ opti391_shadow_recalc(opti391_t *dev) /* C0000-CFFFF */ sh_master = !(dev->regs[0x26] & 0x10); sh_wp = (dev->regs[0x26] & 0x20); - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xc0000 + (i << 14); sh_enable = dev->regs[0x26] & (1 << i); @@ -164,16 +164,22 @@ opti391_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = val; opti391_shadow_recalc(dev); break; + + default: + break; } break; + + default: + break; } } static uint8_t opti391_read(uint16_t addr, void *priv) { - opti391_t *dev = (opti391_t *) priv; - uint8_t ret = 0xff; + const opti391_t *dev = (opti391_t *) priv; + uint8_t ret = 0xff; if (addr == 0x24) ret = dev->regs[dev->index]; @@ -190,7 +196,7 @@ opti391_close(void *priv) } static void * -opti391_init(const device_t *info) +opti391_init(UNUSED(const device_t *info)) { opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t)); memset(dev, 0x00, sizeof(opti391_t)); diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index c02f19e10d..13bc2a1245 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -31,11 +31,10 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t idx, - regs[256], - scratch[2]; +typedef struct opti495_t { + uint8_t idx; + uint8_t regs[256]; + uint8_t scratch[2]; } opti495_t; #ifdef ENABLE_OPTI495_LOG @@ -60,7 +59,6 @@ static void opti495_recalc(opti495_t *dev) { uint32_t base; - uint32_t i; uint32_t shflags = 0; shadowbios = 0; @@ -78,7 +76,7 @@ opti495_recalc(opti495_t *dev) mem_set_mem_state_both(0xf0000, 0x10000, shflags); - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) { @@ -95,7 +93,7 @@ opti495_recalc(opti495_t *dev) mem_set_mem_state_both(base, 0x4000, shflags); } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xc0000 + (i << 14); if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) { @@ -141,6 +139,8 @@ opti495_write(uint16_t addr, uint8_t val, void *priv) case 0x26: opti495_recalc(dev); break; + default: + break; } } break; @@ -149,14 +149,16 @@ opti495_write(uint16_t addr, uint8_t val, void *priv) case 0xe2: dev->scratch[~addr & 0x01] = val; break; + default: + break; } } static uint8_t opti495_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - opti495_t *dev = (opti495_t *) priv; + uint8_t ret = 0xff; + const opti495_t *dev = (opti495_t *) priv; switch (addr) { case 0x22: @@ -172,6 +174,8 @@ opti495_read(uint16_t addr, void *priv) case 0xe2: ret = dev->scratch[~addr & 0x01]; break; + default: + break; } return ret; diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index b6219b1a4f..f8b8785590 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -29,12 +29,13 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/port_92.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t idx, - regs[256], scratch[2]; +typedef struct opti499_t { + uint8_t idx; + uint8_t regs[256]; + uint8_t scratch[2]; } opti499_t; #ifdef ENABLE_OPTI499_LOG @@ -59,7 +60,6 @@ static void opti499_recalc(opti499_t *dev) { uint32_t base; - uint32_t i; uint32_t shflags = 0; shadowbios = 0; @@ -77,7 +77,7 @@ opti499_recalc(opti499_t *dev) mem_set_mem_state_both(0xf0000, 0x10000, shflags); - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) { @@ -93,7 +93,7 @@ opti499_recalc(opti499_t *dev) mem_set_mem_state_both(base, 0x4000, shflags); } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xc0000 + (i << 14); if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) { @@ -154,6 +154,9 @@ opti499_write(uint16_t addr, uint8_t val, void *priv) case 0x2d: opti499_recalc(dev); break; + + default: + break; } } break; @@ -162,6 +165,9 @@ opti499_write(uint16_t addr, uint8_t val, void *priv) case 0xe2: dev->scratch[~addr & 0x01] = val; break; + + default: + break; } } @@ -188,6 +194,9 @@ opti499_read(uint16_t addr, void *priv) case 0xe2: ret = dev->scratch[~addr & 0x01]; break; + + default: + break; } return ret; @@ -230,7 +239,7 @@ opti499_close(void *priv) } static void * -opti499_init(const device_t *info) +opti499_init(UNUSED(const device_t *info)) { opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t)); memset(dev, 0, sizeof(opti499_t)); diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index fdcb4fc3ee..64adacde46 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -32,10 +32,10 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t idx, is_pci, - regs[16]; +typedef struct opti5x7_t { + uint8_t idx; + uint8_t is_pci; + uint8_t regs[16]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG @@ -84,7 +84,7 @@ opti5x7_shadow_map(int cur_reg, opti5x7_t *dev) mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); } } else { - for (int i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { if (dev->is_pci) mem_set_mem_state_cpu_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); else @@ -143,16 +143,20 @@ opti5x7_write(uint16_t addr, uint8_t val, void *priv) case 0x11: /* Master Cycle Control Register */ dev->regs[dev->idx] = val; break; + default: + break; } opti5x7_log("OPTi 5x7: dev->regs[%02x] = %02x\n", dev->idx, dev->regs[dev->idx]); break; + default: + break; } } static uint8_t opti5x7_read(uint16_t addr, void *priv) { - opti5x7_t *dev = (opti5x7_t *) priv; + const opti5x7_t *dev = (opti5x7_t *) priv; return (addr == 0x24) ? dev->regs[dev->idx] : 0xff; } diff --git a/src/chipset/opti602.c b/src/chipset/opti602.c new file mode 100644 index 0000000000..3b5614ff41 --- /dev/null +++ b/src/chipset/opti602.c @@ -0,0 +1,239 @@ +/* + * 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. + * + * Implementation of the OPTi 82C601/82C602 Buffer Devices. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/smram.h> +#include <86box/port_92.h> +#include <86box/chipset.h> +#include <86box/plat_unused.h> + +typedef struct opti602_t { + uint8_t idx; + + uint8_t regs[256]; + uint8_t gpio[32]; + + uint16_t gpio_base; + + uint16_t gpio_mask; + uint16_t gpio_size; + + nvr_t *nvr; +} opti602_t; + +#ifdef ENABLE_OPTI602_LOG +int opti602_do_log = ENABLE_OPTI602_LOG; + +static void +opti602_log(const char *fmt, ...) +{ + va_list ap; + + if (opti602_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define opti602_log(fmt, ...) +#endif + +static void +opti602_gpio_write(uint16_t addr, uint8_t val, void *priv) +{ + opti602_t *dev = (opti602_t *) priv; + + dev->gpio[addr - dev->gpio_base] = val; +} + +static uint8_t +opti602_gpio_read(uint16_t addr, void *priv) +{ + const opti602_t *dev = (opti602_t *) priv; + uint8_t ret = 0xff; + + ret = dev->gpio[addr - dev->gpio_base]; + + return ret; +} + +static void +opti602_gpio_recalc(opti602_t *dev) +{ + if (dev->gpio_base != 0x0000) + io_removehandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev); + + dev->gpio_base = dev->regs[0xf8]; + dev->gpio_base |= (((uint16_t) dev->regs[0xf7]) << 8); + + dev->gpio_size = 1 << ((dev->regs[0xf9] >> 2) & 0x07); + + dev->gpio_mask = ~(dev->gpio_size - 1); + dev->gpio_base &= dev->gpio_mask; + + dev->gpio_mask = ~dev->gpio_mask; + + if (dev->gpio_base != 0x0000) + io_sethandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev); +} + +static void +opti602_write(uint16_t addr, uint8_t val, void *priv) +{ + opti602_t *dev = (opti602_t *) priv; + + switch (addr) { + case 0x22: + dev->idx = val; + break; + case 0x24: + if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) { + dev->regs[dev->idx] = val; + opti602_log("dev->regs[%04x] = %08x\n", dev->idx, val); + + /* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */ + switch (dev->idx) { + case 0xea: + /* GREEN Power Port */ + break; + + case 0xf7: + case 0xf8: + /* General Purpose Chip Select Registers */ + opti602_gpio_recalc(dev); + break; + + case 0xf9: + /* General Purpose Chip Select Register */ + nvr_bank_set(0, !!(val & 0x20), dev->nvr); + opti602_gpio_recalc(dev); + break; + + case 0xfa: + /* GPM Port */ + break; + + default: + break; + } + } + break; + + default: + break; + } +} + +static uint8_t +opti602_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + const opti602_t *dev = (opti602_t *) priv; + + switch (addr) { + case 0x24: + if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) { + ret = dev->regs[dev->idx]; + if ((dev->idx == 0xfa) && (dev->regs[0xf9] & 0x40)) + ret |= dev->regs[0xea]; + } + break; + + default: + break; + } + + return ret; +} + +static void +opti602_reset(void *priv) +{ + opti602_t *dev = (opti602_t *) priv; + + memset(dev->regs, 0x00, 256 * sizeof(uint8_t)); + memset(dev->gpio, 0x00, 32 * sizeof(uint8_t)); + + dev->regs[0xfa] = 0x07; + + dev->gpio[0x01] |= 0xfe; + + nvr_bank_set(0, 0, dev->nvr); + opti602_gpio_recalc(dev); +} + +static void +opti602_close(void *priv) +{ + opti602_t *dev = (opti602_t *) priv; + + free(dev); +} + +static void * +opti602_init(UNUSED(const device_t *info)) +{ + opti602_t *dev = (opti602_t *) calloc(1, sizeof(opti602_t)); + + io_sethandler(0x0022, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev); + + dev->nvr = device_add(&at_mb_nvr_device); + + opti602_reset(dev); + + return dev; +} + +const device_t opti601_device = { + .name = "OPTi 82C601", + .internal_name = "opti601", + .flags = 0, + .local = 0, + .init = opti602_init, + .close = opti602_close, + .reset = opti602_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t opti602_device = { + .name = "OPTi 82C602", + .internal_name = "opti602", + .flags = 0, + .local = 0, + .init = opti602_init, + .close = opti602_close, + .reset = opti602_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index f9b0bf8a7a..3e9316f2bf 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -33,6 +33,7 @@ #include <86box/timer.h> #include <86box/pic.h> #include <86box/pit.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/hdc.h> @@ -40,10 +41,13 @@ #include <86box/chipset.h> #include <86box/spd.h> -typedef struct -{ - uint8_t irq_convert, - pci_regs[256]; +typedef struct opti822_t { + uint8_t irq_convert; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + + uint8_t pci_regs[256]; } opti822_t; // #define ENABLE_OPTI822_LOG 1 @@ -107,7 +111,9 @@ opti822_update_irqs(opti822_t *dev, int set) int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; pic_t *temp_pic; - // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); +#if 0 + dev->irq_convert = (dev->pci_regs[0x53] & 0x08); +#endif dev->irq_convert = 1; for (uint8_t i = 0; i < 16; i++) { @@ -325,14 +331,17 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) } opti822_update_irqs(dev, 1); break; + + default: + break; } } static uint8_t opti822_pci_read(int func, int addr, void *priv) { - opti822_t *dev = (opti822_t *) priv; - uint8_t ret; + const opti822_t *dev = (opti822_t *) priv; + uint8_t ret; ret = 0xff; @@ -375,20 +384,20 @@ opti822_reset(void *priv) } static void -opti822_close(void *p) +opti822_close(void *priv) { - opti822_t *dev = (opti822_t *) p; + opti822_t *dev = (opti822_t *) priv; free(dev); } static void * -opti822_init(const device_t *info) +opti822_init(UNUSED(const device_t *info)) { opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t)); memset(dev, 0, sizeof(opti822_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot); opti822_reset(dev); diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 18f1791e85..77297ae950 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -32,12 +32,12 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t idx, forced_green, - is_pci, - regs[256], - scratch[2]; +typedef struct opti895_t { + uint8_t idx; + uint8_t forced_green; + uint8_t is_pci; + uint8_t regs[256]; + uint8_t scratch[2]; smram_t *smram; } opti895_t; @@ -64,7 +64,6 @@ static void opti895_recalc(opti895_t *dev) { uint32_t base; - uint32_t i; uint32_t shflags = 0; shadowbios = 0; @@ -85,7 +84,7 @@ opti895_recalc(opti895_t *dev) else mem_set_mem_state_both(0xf0000, 0x10000, shflags); - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { base = 0xd0000 + (i << 14); if (dev->regs[0x23] & (1 << i)) { @@ -109,7 +108,7 @@ opti895_recalc(opti895_t *dev) mem_set_mem_state_both(base, 0x4000, shflags); } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xc0000 + (i << 14); if (dev->regs[0x26] & (1 << i)) { @@ -141,6 +140,8 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) { opti895_t *dev = (opti895_t *) priv; + opti895_log("opti895_write(%04X, %08X)\n", addr, val); + switch (addr) { case 0x22: dev->idx = val; @@ -156,6 +157,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->idx] = val; opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); + /* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */ switch (dev->idx) { case 0x21: cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); @@ -185,6 +187,9 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) break; } break; + + default: + break; } } break; @@ -193,14 +198,17 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) case 0xe2: dev->scratch[addr - 0xe1] = val; break; + + default: + break; } } static uint8_t opti895_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - opti895_t *dev = (opti895_t *) priv; + uint8_t ret = 0xff; + const opti895_t *dev = (opti895_t *) priv; switch (addr) { case 0x23: @@ -208,18 +216,25 @@ opti895_read(uint16_t addr, void *priv) ret = dev->regs[dev->idx]; break; case 0x24: + /* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */ if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) { ret = dev->regs[dev->idx]; if (dev->idx == 0xe0) ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green; } break; + case 0xe1: case 0xe2: ret = dev->scratch[addr - 0xe1]; break; + + default: + break; } + opti895_log("opti895_read(%04X) = %02X\n", addr, ret); + return ret; } diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 1ab5749f74..122318862a 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -31,6 +31,7 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/nmi.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -66,20 +67,21 @@ enum { BANK_4M_INTERLEAVED }; -typedef struct { +typedef struct ram_struct_t { void *parent; int bank; } ram_struct_t; -typedef struct { +typedef struct ems_struct_t { void *parent; int segment; } ems_struct_t; -typedef struct { +typedef struct scamp_t { int cfg_index; uint8_t cfg_regs[256]; - int cfg_enable, ram_config; + int cfg_enable; + int ram_config; int ems_index; int ems_autoinc; @@ -91,21 +93,23 @@ typedef struct { ram_struct_t ram_struct[2]; ems_struct_t ems_struct[20]; - uint32_t ram_virt_base[2], ram_phys_base[2]; + uint32_t ram_virt_base[2]; + uint32_t ram_phys_base[2]; uint32_t ram_mask[2]; - int row_virt_shift[2], row_phys_shift[2]; - int ram_interleaved[2], ibank_shift[2]; + int row_virt_shift[2]; + int row_phys_shift[2]; + int ram_interleaved[2]; + int ibank_shift[2]; port_92_t *port_92; } scamp_t; -static const struct -{ +static const struct { int size_kb; int rammap; int bank[2]; } ram_configs[] = { - {512, 0x0, { BANK_256K, BANK_NONE } }, + { 512, 0x0, { BANK_256K, BANK_NONE } }, { 1024, 0x1, { BANK_256K_INTERLEAVED, BANK_NONE } }, { 1536, 0x2, { BANK_256K_INTERLEAVED, BANK_256K } }, { 2048, 0x3, { BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED }}, @@ -118,12 +122,11 @@ static const struct { 16384, 0x9, { BANK_4M_INTERLEAVED, BANK_NONE } }, }; -static const struct -{ +static const struct { int bank[2]; int remapped; } rammap[16] = { - {{ BANK_256K, BANK_NONE }, 0}, + { { BANK_256K, BANK_NONE }, 0}, { { BANK_256K_INTERLEAVED, BANK_NONE }, 0}, { { BANK_256K_INTERLEAVED, BANK_256K }, 0}, { { BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED }, 0}, @@ -149,12 +152,12 @@ static const struct static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -180,12 +183,12 @@ ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -213,12 +216,12 @@ ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -244,12 +247,12 @@ ram_mirrored_interleaved_read(uint32_t addr, void *priv) static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -275,12 +278,12 @@ ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -294,12 +297,12 @@ ram_mirrored_read(uint32_t addr, void *priv) static void ram_mirrored_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int byte; - int row; - int column; + const ram_struct_t *rs = (ram_struct_t *) priv; + const scamp_t *dev = rs->parent; + int bank = rs->bank; + int byte; + int row; + int column; addr -= dev->ram_virt_base[bank]; byte = addr & 1; @@ -424,6 +427,9 @@ recalc_mappings(void *priv) virt_base += (1 << 24); dev->row_virt_shift[bank_nr] = 12; break; + + default: + break; } } else { switch (rammap[cur_rammap].bank[bank_nr]) { @@ -489,6 +495,9 @@ recalc_mappings(void *priv) virt_base += (1 << 24); dev->row_virt_shift[bank_nr] = 12; break; + + default: + break; } } switch (rammap[cur_rammap].bank[bank_nr]) { @@ -534,6 +543,9 @@ recalc_mappings(void *priv) ram_mirrored_interleaved_write, NULL, NULL); } break; + + default: + break; } } } @@ -562,9 +574,9 @@ recalc_sltptr(scamp_t *dev) static uint8_t scamp_ems_read(uint32_t addr, void *priv) { - ems_struct_t *ems = (ems_struct_t *) priv; - scamp_t *dev = ems->parent; - int segment = ems->segment; + const ems_struct_t *ems = (ems_struct_t *) priv; + const scamp_t *dev = ems->parent; + int segment = ems->segment; addr = (addr & 0x3fff) | dev->mappings[segment]; return ram[addr]; @@ -573,9 +585,9 @@ scamp_ems_read(uint32_t addr, void *priv) static void scamp_ems_write(uint32_t addr, uint8_t val, void *priv) { - ems_struct_t *ems = (ems_struct_t *) priv; - scamp_t *dev = ems->parent; - int segment = ems->segment; + const ems_struct_t *ems = (ems_struct_t *) priv; + const scamp_t *dev = ems->parent; + int segment = ems->segment; addr = (addr & 0x3fff) | dev->mappings[segment]; ram[addr] = val; @@ -584,7 +596,6 @@ scamp_ems_write(uint32_t addr, uint8_t val, void *priv) static void recalc_ems(scamp_t *dev) { - int segment; const uint32_t ems_base[12] = { 0xc0000, 0xc4000, 0xc8000, 0xcc000, 0xd0000, 0xd4000, 0xd8000, 0xdc000, @@ -593,7 +604,7 @@ recalc_ems(scamp_t *dev) uint32_t new_mappings[20]; uint16_t ems_enable; - for (segment = 0; segment < 20; segment++) + for (int segment = 0; segment < 20; segment++) new_mappings[segment] = 0xa0000 + segment * 0x4000; if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) @@ -601,7 +612,7 @@ recalc_ems(scamp_t *dev) else ems_enable = 0; - for (segment = 0; segment < 12; segment++) { + for (int segment = 0; segment < 12; segment++) { if (ems_enable & (1 << segment)) { uint32_t phys_addr = dev->ems[segment] << 14; @@ -613,7 +624,7 @@ recalc_ems(scamp_t *dev) } } - for (segment = 0; segment < 20; segment++) { + for (int segment = 0; segment < 20; segment++) { if (new_mappings[segment] != dev->mappings[segment]) { dev->mappings[segment] = new_mappings[segment]; if (new_mappings[segment] < (mem_size * 1024)) { @@ -644,6 +655,8 @@ shadow_control(uint32_t addr, uint32_t size, int state, int ems_enable) case 3: mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; + default: + break; } flushmmucache_nopc(); @@ -756,6 +769,8 @@ scamp_write(uint16_t addr, uint8_t val, void *priv) case CFG_FEAXS: shadow_recalc(dev); break; + default: + break; } } break; @@ -767,6 +782,9 @@ scamp_write(uint16_t addr, uint8_t val, void *priv) mem_a20_recalc(); } break; + + default: + break; } } @@ -809,6 +827,9 @@ scamp_read(uint16_t addr, void *priv) softresetx86(); cpu_set_edx(); break; + + default: + break; } return ret; @@ -823,10 +844,9 @@ scamp_close(void *priv) } static void * -scamp_init(const device_t *info) +scamp_init(UNUSED(const device_t *info)) { uint32_t addr; - int c; scamp_t *dev = (scamp_t *) malloc(sizeof(scamp_t)); memset(dev, 0x00, sizeof(scamp_t)); @@ -847,7 +867,7 @@ scamp_init(const device_t *info) dev->ram_config = 0; /* Find best fit configuration for the requested memory size */ - for (c = 0; c < NR_ELEMS(ram_configs); c++) { + for (uint8_t c = 0; c < NR_ELEMS(ram_configs); c++) { if (mem_size < ram_configs[c].size_kb) break; @@ -863,7 +883,7 @@ scamp_init(const device_t *info) mem_mapping_set_exec(&ram_mid_mapping, ram + 0xf0000); addr = 0; - for (c = 0; c < 2; c++) { + for (uint8_t c = 0; c < 2; c++) { dev->ram_struct[c].parent = dev; dev->ram_struct[c].bank = c; mem_mapping_add(&dev->ram_mapping[c], 0, 0, @@ -924,12 +944,15 @@ scamp_init(const device_t *info) dev->ibank_shift[c] = 23; dev->ram_interleaved[c] = 1; break; + + default: + break; } } mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - for (c = 0; c < 20; c++) { + for (uint8_t c = 0; c < 20; c++) { dev->ems_struct[c].parent = dev; dev->ems_struct[c].segment = c; mem_mapping_add(&dev->ems_mappings[c], diff --git a/src/chipset/scat.c b/src/chipset/scat.c index e2c1bf103c..aa0c5511a3 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -55,8 +55,9 @@ #define SCATSX_HIGH_PERFORMANCE_REFRESH 0x63 #define SCATSX_CAS_TIMING_FOR_DMA 0x64 -typedef struct { - uint8_t valid, pad; +typedef struct ems_page_t { + uint8_t valid; + uint8_t pad; uint8_t regs_2x8; uint8_t regs_2x9; @@ -75,7 +76,8 @@ typedef struct scat_t { int external_is_RAS; - ems_page_t null_page, page[32]; + ems_page_t null_page; + ems_page_t page[32]; mem_mapping_t low_mapping[32]; mem_mapping_t remap_mapping[6]; @@ -931,9 +933,8 @@ static void memmap_state_update(scat_t *dev) { uint32_t addr; - int i; - for (i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) { + for (uint8_t i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) { addr = get_addr(dev, 0x40000 + (i << 14), &dev->null_page); mem_mapping_set_exec(&dev->efff_mapping[i], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL); @@ -947,37 +948,40 @@ memmap_state_update(scat_t *dev) mem_mapping_set_exec(&dev->low_mapping[1], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL); - for (i = 2; i < 32; i++) { + for (uint8_t i = 2; i < 32; i++) { addr = get_addr(dev, i << 19, &dev->null_page); mem_mapping_set_exec(&dev->low_mapping[i], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL); } if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - for (i = 0; i < max_map[(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)]; i++) - mem_mapping_enable(&dev->low_mapping[i]); + uint8_t j = 0; - for (; i < 32; i++) - mem_mapping_disable(&dev->low_mapping[i]); + for (j = 0; j < max_map[(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)]; j++) + mem_mapping_enable(&dev->low_mapping[j]); - for (i = 24; i < 36; i++) { + for (; j < 32; j++) + mem_mapping_disable(&dev->low_mapping[j]); + + for (j = 24; j < 36; j++) { if (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4) - mem_mapping_disable(&dev->efff_mapping[i]); + mem_mapping_disable(&dev->efff_mapping[j]); else - mem_mapping_enable(&dev->efff_mapping[i]); + mem_mapping_enable(&dev->efff_mapping[j]); } } else { - for (i = 0; i < max_map_sx[dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f]; i++) - mem_mapping_enable(&dev->low_mapping[i]); + uint8_t j = 0; + for (j = 0; j < max_map_sx[dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f]; j++) + mem_mapping_enable(&dev->low_mapping[j]); - for (; i < 32; i++) - mem_mapping_disable(&dev->low_mapping[i]); + for (; j < 32; j++) + mem_mapping_disable(&dev->low_mapping[j]); - for (i = 24; i < 36; i++) { + for (j = 24; j < 36; j++) { if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 2 || (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3) - mem_mapping_disable(&dev->efff_mapping[i]); + mem_mapping_disable(&dev->efff_mapping[j]); else - mem_mapping_enable(&dev->efff_mapping[i]); + mem_mapping_enable(&dev->efff_mapping[j]); } } @@ -985,21 +989,21 @@ memmap_state_update(scat_t *dev) if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) == 3) || (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3)) { mem_mapping_disable(&dev->low_mapping[2]); - for (i = 0; i < 6; i++) { + for (uint8_t i = 0; i < 6; i++) { addr = get_addr(dev, 0x100000 + (i << 16), &dev->null_page); mem_mapping_set_exec(&dev->remap_mapping[i], addr < ((uint32_t) mem_size << 10) ? ram + addr : NULL); mem_mapping_enable(&dev->remap_mapping[i]); } } else { - for (i = 0; i < 6; i++) + for (uint8_t i = 0; i < 6; i++) mem_mapping_disable(&dev->remap_mapping[i]); if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) > 4) || (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) > 3)) mem_mapping_enable(&dev->low_mapping[2]); } } else { - for (i = 0; i < 6; i++) + for (uint8_t i = 0; i < 6; i++) mem_mapping_disable(&dev->remap_mapping[i]); mem_mapping_enable(&dev->low_mapping[2]); @@ -1191,15 +1195,18 @@ scat_out(uint16_t port, uint8_t val, void *priv) if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) dev->reg_2xA = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? val : val & 0xc3; break; + + default: + break; } } static uint8_t scat_in(uint16_t port, void *priv) { - scat_t *dev = (scat_t *) priv; - uint8_t ret = 0xff; - uint8_t indx; + const scat_t *dev = (scat_t *) priv; + uint8_t ret = 0xff; + uint8_t indx; switch (port) { case 0x23: @@ -1258,6 +1265,8 @@ scat_in(uint16_t port, void *priv) if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) ret = dev->reg_2xA; break; + default: + break; } return ret; @@ -1374,7 +1383,7 @@ static void * scat_init(const device_t *info) { scat_t *dev; - uint32_t i; + uint32_t j; uint32_t k; int sx; @@ -1384,7 +1393,7 @@ scat_init(const device_t *info) sx = (dev->type == 32) ? 1 : 0; - for (i = 0; i < sizeof(dev->regs); i++) + for (uint32_t i = 0; i < sizeof(dev->regs); i++) dev->regs[i] = 0xff; if (sx) { @@ -1445,7 +1454,7 @@ scat_init(const device_t *info) mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xf0000, MEM_MAPPING_INTERNAL, &dev->null_page); - for (i = 2; i < 32; i++) { + for (uint8_t i = 2; i < 32; i++) { mem_mapping_add(&dev->low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, @@ -1453,27 +1462,27 @@ scat_init(const device_t *info) } if (sx) { - i = 16; + j = 16; k = 0x40000; } else { - i = 0; + j = 0; k = (dev->regs[SCAT_VERSION] < 4) ? 0x40000 : 0x60000; } mem_mapping_set_addr(&dev->low_mapping[31], 0xf80000, k); - for (; i < 44; i++) { - mem_mapping_add(&dev->efff_mapping[i], 0x40000 + (i << 14), 0x4000, + for (; j < 44; j++) { + mem_mapping_add(&dev->efff_mapping[j], 0x40000 + (j << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, - mem_size > (256 + (i << 4)) ? ram + 0x40000 + (i << 14) : NULL, + mem_size > (256 + (j << 4)) ? ram + 0x40000 + (j << 14) : NULL, MEM_MAPPING_INTERNAL, &dev->null_page); if (sx) - mem_mapping_enable(&dev->efff_mapping[i]); + mem_mapping_enable(&dev->efff_mapping[j]); } if (sx) { - for (i = 24; i < 32; i++) { + for (uint8_t i = 24; i < 32; i++) { dev->page[i].valid = 1; dev->page[i].regs_2x8 = 0xff; dev->page[i].regs_2x9 = 0x03; @@ -1485,7 +1494,7 @@ scat_init(const device_t *info) mem_mapping_disable(&dev->ems_mapping[i]); } } else { - for (i = 0; i < 32; i++) { + for (uint8_t i = 0; i < 32; i++) { dev->page[i].valid = 1; dev->page[i].regs_2x8 = 0xff; dev->page[i].regs_2x9 = 0x03; @@ -1498,7 +1507,7 @@ scat_init(const device_t *info) } } - for (i = 0; i < 6; i++) { + for (uint8_t i = 0; i < 6; i++) { mem_mapping_add(&dev->remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 462db88ea2..aa841ed9c1 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -8,11 +8,11 @@ * * Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2021-2023 Miran Grca. + * Copyright 2021-2023 Tiseno100. */ #include #include @@ -25,27 +25,26 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/smram.h> - +#include <86box/spd.h> +#include <86box/sis_55xx.h> #include <86box/chipset.h> -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - #ifdef ENABLE_SIS_5511_LOG int sis_5511_do_log = ENABLE_SIS_5511_LOG; @@ -65,629 +64,69 @@ sis_5511_log(const char *fmt, ...) #endif typedef struct sis_5511_t { - uint8_t pci_conf[256], pci_conf_sb[2][256], - index, regs[16]; + uint8_t nb_slot; + uint8_t sb_slot; - int nb_pci_slot, sb_pci_slot; + void *h2p; - sff8038i_t *ide_drive[2]; - smram_t *smram; - port_92_t *port_92; + void *p2i; + void *ide; + sis_55xx_common_t *sis; } sis_5511_t; -static void -sis_5511_shadow_recalc(sis_5511_t *dev) -{ - int state; - uint32_t base; - - for (uint8_t i = 0x80; i <= 0x86; i++) { - if (i == 0x86) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - pclog("000F0000-000FFFFF\n"); - } else { - base = ((i & 0x07) << 15) + 0xc0000; - - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - pclog("%08X-%08X\n", base, base + 0x3fff); - - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff); - } - } - - flushmmucache_nopc(); -} - -static void -sis_5511_smram_recalc(sis_5511_t *dev) -{ - smram_disable_all(); - - switch (dev->pci_conf[0x65] >> 6) { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - } - - flushmmucache(); -} - -void -sis_5513_ide_handler(sis_5511_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) { - if (dev->pci_conf_sb[1][0x4a] & 4) { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void -sis_5513_bm_handler(sis_5511_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); -} - static void sis_5511_write(int func, int addr, uint8_t val, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; - - switch (addr) { - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= 0xb0; - break; - - case 0x50: - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x51: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x52: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x53: - case 0x54: - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x56 ... 0x59: - dev->pci_conf[addr] = val; - break; - - case 0x5a: - /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. - The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. - The latter (bit 6) means the chipset intercepts all odd FXh to 64h. - Bit 5 sets fast reset latency. This should be fixed on the other SiS - chipsets as well. */ - dev->pci_conf[addr] = val; - break; - - case 0x5b: - dev->pci_conf[addr] = val & 0xf7; - break; - - case 0x5c: - dev->pci_conf[addr] = val & 0xcf; - break; - - case 0x5d: - dev->pci_conf[addr] = val; - break; - - case 0x5e: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x5f: - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x60: - dev->pci_conf[addr] = val & 0x3e; - if ((dev->pci_conf[0x68] & 1) && (val & 2)) { - smi_raise(); - dev->pci_conf[0x69] |= 1; - } - break; - - case 0x61 ... 0x64: - dev->pci_conf[addr] = val; - break; - - case 0x65: - dev->pci_conf[addr] = val & 0xd0; - sis_5511_smram_recalc(dev); - break; - - case 0x66: - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x67: - case 0x68: - dev->pci_conf[addr] = val; - break; - - case 0x69: - dev->pci_conf[addr] &= val; - break; - - case 0x6a ... 0x6e: - dev->pci_conf[addr] = val; - break; - - case 0x6f: - dev->pci_conf[addr] = val & 0x3f; - break; - - case 0x70: /* DRAM Bank Register 0-0 */ - case 0x71: /* DRAM Bank Register 0-0 */ - case 0x72: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x73: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x74: /* DRAM Bank Register 1-0 */ - dev->pci_conf[addr] = val; - break; - - case 0x75: /* DRAM Bank Register 1-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x76: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x77: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x78: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val; - break; - - case 0x79: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; + const sis_5511_t *dev = (sis_5511_t *) priv; - case 0x7a: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val; - break; + sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - case 0x7b: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x7c: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val; - break; - - case 0x7d: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x7e: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x7f: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee); - sis_5511_shadow_recalc(dev); - break; - - case 0x90: /* 5512 General Purpose Register Index */ - case 0x91: /* 5512 General Purpose Register Index */ - case 0x92: /* 5512 General Purpose Register Index */ - case 0x93: /* 5512 General Purpose Register Index */ - dev->pci_conf[addr] = val; - break; - } - sis_5511_log("SiS 5511: dev->pci_conf[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); + if (func == 0x00) + sis_5511_host_to_pci_write(addr, val, dev->h2p); } static uint8_t sis_5511_read(int func, int addr, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; - sis_5511_log("SiS 5511: dev->pci_conf[%02x] (%02x) POST %02x\n", addr, dev->pci_conf[addr], inb(0x80)); - return dev->pci_conf[addr]; -} - -void -sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) -{ - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] = val & 7; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= val & 0x36; - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x80) : PCI_IRQ_DISABLED); - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->pci_conf_sb[0][addr] = val; - break; + const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - case 0x60: /* MIRQ0 Remapping Control Register */ - case 0x61: /* MIRQ1 Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xcf; - pci_set_mirq_routing(addr & 1, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; + if (func == 0x00) + ret = sis_5511_host_to_pci_read(addr, dev->h2p); - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; + sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); - case 0x63: /* IDEIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) { - sff_set_irq_line(dev->ide_drive[0], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - sff_set_irq_line(dev->ide_drive[1], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - } - break; - - case 0x64: /* GPIO0 Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x80; - break; - - case 0x66: /* GPIO0 Output Mode Control Register */ - case 0x67: /* GPIO0 Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: /* GPIO Status Register */ - dev->pci_conf_sb[0][addr] &= val & 0x15; - break; - } -} - -void -sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) -{ - switch (addr) { - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 5; - sis_5513_ide_handler(dev); - sis_5513_bm_handler(dev); - break; - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] &= val & 0x3f; - break; - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x10: /* Primary Channel Base Address Register */ - case 0x11: /* Primary Channel Base Address Register */ - case 0x12: /* Primary Channel Base Address Register */ - case 0x13: /* Primary Channel Base Address Register */ - case 0x14: /* Primary Channel Base Address Register */ - case 0x15: /* Primary Channel Base Address Register */ - case 0x16: /* Primary Channel Base Address Register */ - case 0x17: /* Primary Channel Base Address Register */ - case 0x18: /* Secondary Channel Base Address Register */ - case 0x19: /* Secondary Channel Base Address Register */ - case 0x1a: /* Secondary Channel Base Address Register */ - case 0x1b: /* Secondary Channel Base Address Register */ - case 0x1c: /* Secondary Channel Base Address Register */ - case 0x1d: /* Secondary Channel Base Address Register */ - case 0x1e: /* Secondary Channel Base Address Register */ - case 0x1f: /* Secondary Channel Base Address Register */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; - - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_bm_handler(dev); - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0x9f; - sis_5513_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control Register 1 */ - dev->pci_conf_sb[1][addr] = val & 0xef; - break; - - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - } + return ret; } static void sis_5513_write(int func, int addr, uint8_t val, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; - switch (func) { - case 0: - sis_5513_pci_to_isa_write(addr, val, dev); - break; - case 1: - sis_5513_ide_write(addr, val, dev); - break; - } - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); -} - -static uint8_t -sis_5513_read(int func, int addr, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; + const sis_5511_t *dev = (sis_5511_t *) priv; - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); - if ((func >= 0) && (func <= 1)) - return dev->pci_conf_sb[func][addr]; - else - return 0xff; -} - -static void -sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; + sis_5511_log("SiS 5513: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - switch (addr) { - case 0x22: - dev->index = val - 0x50; - break; - case 0x23: - switch (dev->index) { - case 0x00: - dev->regs[dev->index] = val & 0xed; - switch (val >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - } - break; - case 0x01: - dev->regs[dev->index] = val & 0xf4; - break; - case 0x03: - dev->regs[dev->index] = val & 3; - break; - case 0x04: /* BIOS Register */ - dev->regs[dev->index] = val; - break; - case 0x05: - dev->regs[dev->index] = inb(0x70); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - dev->regs[dev->index] = val; - break; - } - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] = %02x POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); - break; - } + if (func == 0x00) + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); } static uint8_t -sis_5513_isa_read(uint16_t addr, void *priv) -{ - sis_5511_t *dev = (sis_5511_t *) priv; - - if (addr == 0x23) { - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] (%02x) POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); - return dev->regs[dev->index]; - } else - return 0xff; -} - -static void -sis_5511_reset(void *priv) +sis_5513_read(int func, int addr, void *priv) { - sis_5511_t *dev = (sis_5511_t *) priv; - - /* SiS 5511 */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x11; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0x07; - dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; - dev->pci_conf[0x07] = 0x02; - dev->pci_conf[0x08] = 0x00; - dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; - dev->pci_conf[0x52] = 0x20; - dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; - dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; - dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; - dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; - dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; - dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; - dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; - dev->pci_conf[0x63] = 0xff; - dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; - dev->pci_conf[0x66] = 0x00; - dev->pci_conf[0x67] = 0xff; - dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; - dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; - dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - cpu_cache_ext_enabled = 0; - cpu_update_waitstates(); + if (func == 0x00) + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); - dev->pci_conf[0x6b] = 0xff; - dev->pci_conf[0x6c] = 0xff; - dev->pci_conf[0x70] = 4; - dev->pci_conf[0x72] = 4; - dev->pci_conf[0x73] = 0x80; - dev->pci_conf[0x74] = 4; - dev->pci_conf[0x76] = 4; - dev->pci_conf[0x77] = 0x80; - dev->pci_conf[0x78] = 4; - dev->pci_conf[0x7a] = 4; - dev->pci_conf[0x7b] = 0x80; - dev->pci_conf[0x7c] = 4; - dev->pci_conf[0x7e] = 4; - dev->pci_conf[0x7f] = 0x80; - dev->pci_conf[0x80] = 0x00; - dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = 0x00; - dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = 0x00; - dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; - sis_5511_smram_recalc(dev); - sis_5511_shadow_recalc(dev); + sis_5511_log("SiS 5513: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); - /* SiS 5513 */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 8; - dev->pci_conf_sb[0][0x04] = 7; - dev->pci_conf_sb[0][0x0a] = 1; - dev->pci_conf_sb[0][0x0b] = 6; - dev->pci_conf_sb[0][0x0e] = 0x80; - - /* SiS 5513 IDE Controller */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x0a] = 1; - dev->pci_conf_sb[1][0x0b] = 1; - dev->pci_conf_sb[1][0x0e] = 0x80; - sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot); - sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); + return ret; } static void @@ -695,35 +134,25 @@ sis_5511_close(void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; - smram_del(dev->smram); free(dev); } static void * -sis_5511_init(const device_t *info) +sis_5511_init(UNUSED(const device_t *info)) { - sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t)); - memset(dev, 0, sizeof(sis_5511_t)); - - dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev); /* Device 0: SiS 5511 */ - dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev); /* Device 1: SiS 5513 */ - io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */ - - /* MIRQ */ - pci_enable_mirq(0); - pci_enable_mirq(1); + sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); - /* Port 92h */ - dev->port_92 = device_add(&port_92_device); + /* Device 0: SiS 5511 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); + /* Device 1: SiS 5513 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); - /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + dev->sis = device_add(&sis_55xx_common_device); - /* SMRAM */ - dev->smram = smram_add(); + dev->h2p = device_add_linked(&sis_5511_h2p_device, dev->sis); - sis_5511_reset(dev); + dev->p2i = device_add_linked(&sis_5513_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5513_ide_device, dev->sis); return dev; } @@ -735,7 +164,7 @@ const device_t sis_5511_device = { .local = 0, .init = sis_5511_init, .close = sis_5511_close, - .reset = sis_5511_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c new file mode 100644 index 0000000000..7916d6ae29 --- /dev/null +++ b/src/chipset/sis_5511_h2p.c @@ -0,0 +1,461 @@ +/* + * 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. + * + * Implementation of the SiS 5511 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5511_HOST_TO_PCI_LOG +int sis_5511_host_to_pci_do_log = ENABLE_SIS_5511_HOST_TO_PCI_LOG; + +static void +sis_5511_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5511_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5511_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5511_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + uint8_t slic_regs[4096]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + mem_mapping_t slic_mapping; +} sis_5511_host_to_pci_t; + +static void +sis_5511_shadow_recalc(sis_5511_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x80; i <= 0x86; i++) { + if (i == 0x86) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5511_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5511_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5511_smram_recalc(sis_5511_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x65] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= 0xb0; + break; + + case 0x50: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x51: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x52: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x53: + case 0x54: + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x56 ... 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x5a: + /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. + The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. + The latter (bit 6) means the chipset intercepts all odd FXh to 64h. + Bit 5 sets fast reset latency. This should be fixed on the other SiS + chipsets as well. */ + dev->pci_conf[addr] = val; + break; + + case 0x5b: + dev->pci_conf[addr] = val & 0xf7; + break; + + case 0x5c: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0x5d: + dev->pci_conf[addr] = val; + break; + + case 0x5e: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x5f: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x60: + dev->pci_conf[addr] = val & 0x3e; + if ((dev->pci_conf[0x68] & 1) && (val & 2)) { + smi_raise(); + dev->pci_conf[0x69] |= 1; + } + break; + + case 0x61 ... 0x64: + dev->pci_conf[addr] = val; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0xd0; + sis_5511_smram_recalc(dev); + break; + + case 0x66: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x67: + case 0x68: + dev->pci_conf[addr] = val; + break; + + case 0x69: + dev->pci_conf[addr] &= val; + break; + + case 0x6a ... 0x6e: + dev->pci_conf[addr] = val; + break; + + case 0x6f: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x70: /* DRAM Bank Register 0-0 */ + case 0x72: /* DRAM Bank Register 0-1 */ + case 0x74: /* DRAM Bank Register 1-0 */ + case 0x76: /* DRAM Bank Register 1-1 */ + case 0x78: /* DRAM Bank Register 2-0 */ + case 0x7a: /* DRAM Bank Register 2-1 */ + case 0x7c: /* DRAM Bank Register 3-0 */ + case 0x7e: /* DRAM Bank Register 3-1 */ + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82); + break; + + case 0x71: /* DRAM Bank Register 0-0 */ + dev->pci_conf[addr] = val; + break; + + case 0x75: /* DRAM Bank Register 1-0 */ + case 0x79: /* DRAM Bank Register 2-0 */ + case 0x7d: /* DRAM Bank Register 3-0 */ + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x73: /* DRAM Bank Register 0-1 */ + case 0x77: /* DRAM Bank Register 1-1 */ + case 0x7b: /* DRAM Bank Register 2-1 */ + case 0x7f: /* DRAM Bank Register 3-1 */ + dev->pci_conf[addr] = val & 0x83; + break; + + case 0x80 ... 0x85: + dev->pci_conf[addr] = val & 0xee; + sis_5511_shadow_recalc(dev); + break; + case 0x86: + dev->pci_conf[addr] = val & 0xe8; + sis_5511_shadow_recalc(dev); + break; + + case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5511_host_to_pci_read(int addr, void *priv) +{ + const sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5511_host_to_pci_log("SiS 5511 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + dev->slic_regs[addr] = val; + break; + case 0x00000010: + case 0x00000018: + case 0x00000028: + case 0x00000038: + dev->slic_regs[addr] = val & 0x01; + break; + case 0x00000030: + dev->slic_regs[addr] = val & 0x0f; + mem_mapping_set_addr(&dev->slic_mapping, + (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); + break; + } +} + +static uint8_t +sis_5511_slic_read(uint32_t addr, void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + ret = dev->slic_regs[addr]; + break; + } + + return ret; +} + +static void +sis_5511_host_to_pci_reset(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x11; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x20; + dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = 0xff; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; + dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; + dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; + dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; + dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; + dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5511_smram_recalc(dev); + sis_5511_shadow_recalc(dev); + + flushmmucache(); + + memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); + dev->slic_regs[0x18] = 0x0f; + + mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); +} + +static void +sis_5511_host_to_pci_close(void *priv) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5511_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) calloc(1, sizeof(sis_5511_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SLiC Memory Mapped Registers */ + mem_mapping_add(&dev->slic_mapping, + 0xffc00000, 0x00001000, + sis_5511_slic_read, + NULL, + NULL, + sis_5511_slic_write, + NULL, + NULL, + NULL, MEM_MAPPING_EXTERNAL, + dev); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5511_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5511_h2p_device = { + .name = "SiS 5511 Host to PCI bridge", + .internal_name = "sis_5511_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5511_host_to_pci_init, + .close = sis_5511_host_to_pci_close, + .reset = sis_5511_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c new file mode 100644 index 0000000000..130f2abd5a --- /dev/null +++ b/src/chipset/sis_5513_ide.c @@ -0,0 +1,501 @@ +/* + * 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. + * + * Implementation of the SiS 5513 IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_IDE_LOG +int sis_5513_ide_do_log = ENABLE_SIS_5513_IDE_LOG; + +static void +sis_5513_ide_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_ide_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_ide_log(fmt, ...) +#endif + +typedef struct sis_5513_ide_t { + uint8_t rev; + + uint8_t pci_conf[256]; + + sis_55xx_common_t *sis; +} sis_5513_ide_t; + +static void +sis_5513_ide_irq_handler(sis_5513_ide_t *dev) +{ + if (dev->pci_conf[0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5513_ide_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5513_ide_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf[0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5513_ide_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5513_ide_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5513_ide_handler(sis_5513_ide_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf[0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf[0x11] | dev->pci_conf[0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf[0x15] | dev->pci_conf[0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf[0x19] | dev->pci_conf[0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf[0x1c] | dev->pci_conf[0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf[0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf[0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf[0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf[0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5513_ide_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5513_ide_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x02) { + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5513_ide_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf[0x4a] & 0x04) { + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5513_ide_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5513_ide_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->sis->bm[0], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 0); + sff_bus_master_handler(dev->sis->bm[1], ide_io_on, + ((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 8); +} + +void +sis_5513_ide_write(int addr, uint8_t val, void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + sis_5513_ide_log("SiS 5513 IDE: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf[addr] = val & 0x05; + sis_5513_ide_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf[addr] = val & 0x20; + break; + case 0x07: /* Status high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x38); + break; + case 0x09: /* Programming Interface Byte */ + switch (dev->rev) { + case 0xd0: + if (dev->sis->ide_bits_1_3_writable) + val |= 0x0a; + fallthrough; + case 0x00: + case 0xd1: + val &= 0xbf; + fallthrough; + case 0xc0: + switch (val & 0x0a) { + case 0x00: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x85) | (val & 0x4a); + break; + case 0x02: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x84) | (val & 0x4b); + break; + case 0x08: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x81) | (val & 0x4e); + break; + case 0x0a: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x80) | (val & 0x4f); + break; + } + break; + } + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + break; + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + /* Primary Base Address */ + case 0x10 ... 0x11: + case 0x14 ... 0x15: + fallthrough; + + /* Secondary Base Address */ + case 0x18 ... 0x19: + case 0x1c ... 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20 ... 0x21: + if (addr == 0x20) + dev->pci_conf[addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf[addr] = val; + sis_5513_ide_handler(dev); + break; + + case 0x2c ... 0x2f: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x30 ... 0x33: /* Expansion ROM Base Address */ +#ifdef DATASHEET + dev->pci_conf[addr] = val; +#else + if (dev->rev == 0x00) + dev->pci_conf[addr] = val; +#endif + break; + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xcf; + else + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0xe7; + else + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x4a: /* IDE General Control Register 0 */ + switch (dev->rev) { + case 0x00: + dev->pci_conf[addr] = val & 0x9e; + break; + case 0xc0: + dev->pci_conf[addr] = val & 0xaf; + break; + case 0xd0: + dev->pci_conf[addr] = val; + break; + } + sis_5513_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control Register 1 */ + if (dev->rev >= 0xc0) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf[addr] = val; + break; + + case 0x50: + case 0x51: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val; + break; + + case 0x52: + if (dev->rev >= 0xd0) + dev->pci_conf[addr] = val & 0x0f; + break; + + default: + break; + } +} + +uint8_t +sis_5513_ide_read(int addr, void *priv) +{ + const sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x09: + ret = dev->pci_conf[addr]; + if (dev->rev >= 0xc0) { + if (dev->pci_conf[0x09] & 0x40) + ret |= ((dev->pci_conf[0x4a] & 0x06) << 3); + if ((dev->rev == 0xd0) && dev->sis->ide_bits_1_3_writable) + ret |= 0x0a; + } + break; + case 0x3d: + if (dev->rev >= 0xc0) + ret = (dev->pci_conf[0x09] & 0x05) ? PCI_INTA : 0x00; + else + ret = (((dev->pci_conf[0x4b] & 0xc0) == 0xc0) || + (dev->pci_conf[0x09] & 0x05)) ? PCI_INTA : 0x00; + break; + } + + sis_5513_ide_log("SiS 5513 IDE: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_ide_reset(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x13; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = dev->pci_conf[0x07] = 0x00; + dev->pci_conf[0x08] = (dev->rev == 0xd1) ? 0xd0 : dev->rev; + dev->pci_conf[0x09] = 0x8a; + dev->pci_conf[0x0a] = dev->pci_conf[0x0b] = 0x01; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0xf1; + dev->pci_conf[0x11] = 0x01; + dev->pci_conf[0x14] = 0xf5; + dev->pci_conf[0x15] = 0x03; + dev->pci_conf[0x18] = 0x71; + dev->pci_conf[0x19] = 0x01; + dev->pci_conf[0x1c] = 0x75; + dev->pci_conf[0x1d] = 0x03; + dev->pci_conf[0x20] = 0x01; + dev->pci_conf[0x21] = 0xf0; + dev->pci_conf[0x22] = dev->pci_conf[0x23] = 0x00; + dev->pci_conf[0x24] = dev->pci_conf[0x25] = 0x00; + dev->pci_conf[0x26] = dev->pci_conf[0x27] = 0x00; + dev->pci_conf[0x28] = dev->pci_conf[0x29] = 0x00; + dev->pci_conf[0x2a] = dev->pci_conf[0x2b] = 0x00; + switch (dev->rev) { + case 0x00: + case 0xd0: + case 0xd1: + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; + break; + case 0xc0: +#ifdef DATASHEET + dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00; +#else + /* The only Linux lspci listing I could find of this chipset, + shows a subsystem of 0058:0000. */ + dev->pci_conf[0x2c] = 0x58; + dev->pci_conf[0x2d] = 0x00; +#endif + break; + } + dev->pci_conf[0x2e] = dev->pci_conf[0x2f] = 0x00; + dev->pci_conf[0x30] = dev->pci_conf[0x31] = 0x00; + dev->pci_conf[0x32] = dev->pci_conf[0x33] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = 0x06; + dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + + sff_bus_master_reset(dev->sis->bm[0]); + sff_bus_master_reset(dev->sis->bm[1]); +} + +static void +sis_5513_ide_close(void *priv) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) priv; + + free(dev); +} + +static void * +sis_5513_ide_init(UNUSED(const device_t *info)) +{ + sis_5513_ide_t *dev = (sis_5513_ide_t *) calloc(1, sizeof(sis_5513_ide_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* SFF IDE */ + dev->sis->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->sis->bm[1] = device_add_inst(&sff8038i_device, 2); + + sis_5513_ide_reset(dev); + + return dev; +} + +const device_t sis_5513_ide_device = { + .name = "SiS 5513 IDE controller", + .internal_name = "sis_5513_ide", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_ide_device = { + .name = "SiS 5572 IDE controller", + .internal_name = "sis_5572_ide", + .flags = DEVICE_PCI, + .local = 0xc0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_ide_device = { + .name = "SiS 5582 IDE controller", + .internal_name = "sis_5582_ide", + .flags = DEVICE_PCI, + .local = 0xd0, + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_5600_ide_device = { + .name = "SiS 5591/(5)600 IDE controller", + .internal_name = "sis_5591_5600_ide", + .flags = DEVICE_PCI, + .local = 0xd1, /* D0, but we need to distinguish them. */ + .init = sis_5513_ide_init, + .close = sis_5513_ide_close, + .reset = sis_5513_ide_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c new file mode 100644 index 0000000000..df18cc4b39 --- /dev/null +++ b/src/chipset/sis_5513_p2i.c @@ -0,0 +1,1354 @@ +/* + * 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. + * + * Implementation of the SiS 5513 PCI to ISA bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5513_PCI_TO_ISA_LOG +int sis_5513_pci_to_isa_do_log = ENABLE_SIS_5513_PCI_TO_ISA_LOG; + +static void +sis_5513_pci_to_isa_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5513_pci_to_isa_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5513_pci_to_isa_log(fmt, ...) +#endif + +typedef struct sis_5513_pci_to_isa_t { + uint8_t rev; + uint8_t index; + uint8_t dam_index; + uint8_t irq_state; + uint8_t dam_enable; + uint8_t dam_irq_enable; + uint8_t ddma_enable; + uint8_t pci_conf[256]; + uint8_t regs[16]; + uint8_t dam_regs[256]; + uint8_t apc_regs[256]; + + uint16_t dam_base; + uint16_t ddma_base; + uint16_t acpi_io_base; + + sis_55xx_common_t *sis; + port_92_t *port_92; + void *pit; + nvr_t *nvr; + ddma_t *ddma; + acpi_t *acpi; + void *smbus; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); +} sis_5513_pci_to_isa_t; + +static void +sis_5595_acpi_recalc(sis_5513_pci_to_isa_t *dev) +{ + dev->acpi_io_base = (dev->pci_conf[0x91] << 8) | (dev->pci_conf[0x90] & 0xc0); + acpi_update_io_mapping(dev->sis->acpi, dev->acpi_io_base, (dev->pci_conf[0x40] & 0x80)); +} + +static void +sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) +{ + memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); + + if (dev->rev == 0b0) { + dev->apc_regs[0x03] = 0x80; + dev->apc_regs[0x04] = 0x38; + dev->apc_regs[0x07] = 0x01; + } else + dev->apc_regs[0x04] = 0x08; +} + +static void +sis_5513_apc_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + + sis_5513_pci_to_isa_log("SiS 5595 APC: [W] %04X = %02X\n", addr, val); + + switch (nvr_index) { + case 0x02 ... 0x04: + dev->apc_regs[nvr_index] = val; + break; + case 0x05: + case 0x07 ... 0x08: + if (dev->rev == 0xb0) + dev->apc_regs[nvr_index] = val; + break; + } +} + +static uint8_t +sis_5513_apc_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t nvr_index = nvr_get_index(dev->nvr, 0); + uint8_t ret = 0xff; + + ret = dev->apc_regs[nvr_index]; + + if (nvr_index == 0x06) + dev->apc_regs[nvr_index] = 0x00; + + sis_5513_pci_to_isa_log("SiS 5595 APC: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +void +sis_5513_apc_recalc(sis_5513_pci_to_isa_t *dev, uint8_t apc_on) +{ + nvr_at_data_port(!apc_on, dev->nvr); + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); + + if (apc_on) + io_removehandler(0x0071, 0x0001, + sis_5513_apc_read, NULL, NULL, sis_5513_apc_write, NULL, NULL, dev); +} + +static void +sis_5595_do_nmi(sis_5513_pci_to_isa_t *dev, int set) +{ + if (set) + nmi_raise(); + + dev->irq_state = set; +} + +static void +sis_5595_dam_reset(sis_5513_pci_to_isa_t *dev) +{ + if (dev->irq_state) { + if (dev->dam_regs[0x40] & 0x20) + sis_5595_do_nmi(dev, 0); + else if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + } + + memset(dev->dam_regs, 0x00, sizeof(dev->dam_regs)); + + dev->dam_regs[0x40] = 0x08; + dev->dam_regs[0x47] = 0x50; +} + +static void +sis_5595_dam_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t old; + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [W] %04X = %02X\n", addr, val); + + switch (reg) { + case 0x05: + dev->dam_index = (dev->index & 0x80) | (val & 0x7f); + break; + case 0x06: + switch (dev->dam_index) { + case 0x40: + old = dev->dam_regs[0x40]; + dev->dam_regs[0x40] = val & 0xef; + if (val & 0x80) { + sis_5595_dam_reset(dev); + return; + } + if (dev->irq_state) { + if (!(old & 0x20) && (val & 0x20)) { + if (dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + sis_5595_do_nmi(dev, 1); + } else if ((old & 0x20) && !(val & 0x20)) { + sis_5595_do_nmi(dev, 0); + if (dev->dam_irq_enable) + pci_set_mirq(6, 1, &dev->irq_state); + } + } + if ((val & 0x08) && dev->dam_irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + break; + case 0x43 ... 0x47: + dev->dam_regs[dev->dam_index] = val; + break; + case 0x2b ... 0x34: + case 0x6b ... 0x74: + case 0x3b ... 0x3c: + case 0x7b ... 0x7c: + dev->dam_regs[dev->dam_index & 0x3f] = val; + break; + } + break; + } +} + +static uint8_t +sis_5595_dam_read(uint16_t addr, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint16_t reg = addr - dev->dam_base; + uint8_t ret = 0xff; + + switch (reg) { + case 0x05: + ret = dev->dam_index; + break; + case 0x06: + switch (dev->dam_index) { + default: + ret = dev->dam_regs[dev->dam_index]; + break; + case 0x20 ... 0x29: + case 0x2b ... 0x3f: + ret = dev->dam_regs[dev->dam_index & 0x3f]; + break; + case 0x2a: + case 0x6a: + ret = dev->pci_conf[0x78]; + break; + } + break; + } + + sis_5513_pci_to_isa_log("SiS 5595 DAM: [R] %04X = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_dam_recalc(sis_5513_pci_to_isa_t *dev) +{ + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_removehandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); + + dev->dam_base = dev->pci_conf[0x68] | (dev->pci_conf[0x69] << 16); + dev->dam_enable = !!(dev->pci_conf[0x7b] & 0x80); + + if (dev->dam_enable && (dev->dam_base != 0x0000)) + io_sethandler(dev->dam_base, 0x0008, + sis_5595_dam_read, NULL, NULL, sis_5595_dam_write, NULL, NULL, dev); +} + +static void +sis_5595_ddma_recalc(sis_5513_pci_to_isa_t *dev) +{ + uint16_t ch_base; + + dev->ddma_base = (dev->pci_conf[0x80] & 0xf0) | (dev->pci_conf[0x81] << 16); + dev->ddma_enable = !!(dev->pci_conf[0x80] & 0x01); + + for (uint8_t i = 0; i < 8; i++) { + ch_base = dev->ddma_base + (i << 4); + ddma_update_io_mapping(dev->ddma, i, ch_base & 0xff, (ch_base >> 8), + dev->ddma_enable && (dev->pci_conf[0x84] & (1 << i)) && + (dev->ddma_base != 0x0000)); + } +} + +static void +sis_5513_00_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + switch (addr) { + case 0x60: /* MIRQ0 Remapping Control Register */ + case 0x61: /* MIRQ1 Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO0 Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x80; + break; + + case 0x66: /* GPIO0 Output Mode Control Register */ + case 0x67: /* GPIO0 Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x6a: /* GPIO Status Register */ + dev->pci_conf[addr] |= (val & 0x10); + dev->pci_conf[addr] &= ~(val & 0x01); + break; + + default: + break; + } +} + +static void +sis_5513_01_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ + case 0x61: /* MIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf[addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x69: + dev->pci_conf[addr] = val; + break; + + case 0x6a: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x6c: + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x02) | (val & 0xdc); + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, + System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf[addr] = val; + break; + + default: + break; + } +} + +static void +sis_5513_11_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xcf; + dev->sis->ide_bits_1_3_writable = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* GPCS0 Control Register */ + case 0x64: /* GPCS1 Control Register */ + case 0x65: /* GPCS0 Output Mode Control Register */ + case 0x66: /* GPCS0 Output Mode Control Register */ + case 0x67: /* GPCS1 Output Mode Control Register */ + case 0x68: /* GPCS1 Output Mode Control Register */ + case 0x6b: + case 0x6c: + dev->pci_conf[addr] = val; + break; + + case 0x69: /* GPCS0/1 De-Bounce Control Register */ + dev->pci_conf[addr] = val & 0xdf; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x10)) { + plat_power_off(); + return; + } + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x71: /* Type F DMA Control Register */ + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ Control */ + dev->pci_conf[addr] = val & 0xfa; + break; + case 0x73: /* SMI Triggered By IRQ Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x77: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit */ + case 0x76: /* Monoitor Standby Timer Reload And Monoitor Standby State Exit Control */ + dev->pci_conf[addr] = val & 0xfb; + break; + dev->pci_conf[addr] = val; + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + dev->pci_conf[addr] = val; + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +static void +sis_5513_b0_pci_to_isa_write(int addr, uint8_t val, sis_5513_pci_to_isa_t *dev) +{ + uint8_t old; + + switch (addr) { + case 0x61: /* IDEIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0xdf; + sff_set_mirq(dev->sis->bm[0], (val & 0x10) ? 7 : 2); + sff_set_mirq(dev->sis->bm[1], (val & 0x10) ? 2 : 7); + pci_set_mirq_routing(PCI_MIRQ7, 14 + (!!(val & 0x10))); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); + break; + + case 0x62: /* USBIRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf[addr] = val; + dev->sis->usb_enabled = !!(val & 0x40); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ3, val & 0xf); + break; + + case 0x63: /* PCI OutputBuffer Current Strength Register */ + dev->pci_conf[addr] = val; + if ((dev->apc_regs[0x03] & 0x40) && (val & 0x04)) { + plat_power_off(); + return; + } + if ((val & 0x18) == 0x18) { + dma_reset(); + dma_set_at(1); + + device_reset_all(DEVICE_ALL); + + cpu_alt_reset = 0; + + pci_reset(); + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); + } + break; + + case 0x64: /* INIT Enable Register */ + dev->pci_conf[addr] = val; + cpu_cpurst_on_sr = !(val & 0x20); + break; + + case 0x65: /* PHOLD# Timer */ + case 0x66: /* Priority Timer */ + case 0x67: /* Respond to C/D Segments Register */ + case 0x6b: /* Test Mode Register I */ + case 0x6c: /* Test Mode Register II */ + case 0x71: /* Reserved */ + case 0x72: /* Individual PC/PCI DMA Channel Enable */ + case 0x7c: /* Data Acquisition Module ADC Calibration */ + case 0x7d: /* Data Acquisition Module ADC Calibration */ + case 0x88: /* Serial Interrupt Control Register */ + case 0x89: /* Serial Interrupt Enable Register 1 */ + case 0x8a: /* Serial Interrupt Enable Register 2 */ + case 0x8c: /* Serial Interrupt Enable Register 3 */ + dev->pci_conf[addr] = val; + break; + + case 0x68: /* Data Acquistion Module Base Address */ + dev->pci_conf[addr] = val & 0xf8; + sis_5595_dam_recalc(dev); + break; + + case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: ACPI/SCI IRQ -> %02X\n", val); + dev->pci_conf[addr] = val & 0x8f; + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, val & 0xf); + break; + + case 0x6d: /* I2C Bus Control Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard/mouse swapping and keyboard hot key. */ + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf[addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf[addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf[addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf[addr] = val; + break; + + case 0x70: /* Misc. Controller Register */ + dev->pci_conf[addr] = val; + /* TODO: Keyboard Lock Enable/Disable. */ + break; + + case 0x73: + case 0x75 ... 0x79: + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + break; + + case 0x7a: /* Data Acquisition Module Function Selection Register */ + if (dev->rev == 0x81) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0x90; + break; + + case 0x7b: /* Data Acquisition Module Control Register */ + dev->pci_conf[addr] = val; + sis_5595_dam_recalc(dev); + break; + + case 0x7e: /* Data Acquisition Module and SMBUS IRQ Remapping Control Register */ + sis_5513_pci_to_isa_log("Set MIRQ routing: DAM/SMBUS IRQ -> %02X\n", val); + if (dev->rev == 0x81) + dev->pci_conf[addr] = val & 0x8f; + else { + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x10) | (val & 0xef); + + dev->dam_irq_enable = ((val & 0xc0) == 0x40); + smbus_sis5595_irq_enable(dev->smbus, (val & 0xa0) == 0x20); + } + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ6, val & 0xf); + break; + + case 0x80: /* Distributed DMA Master Configuration Register */ + case 0x81: /* Distributed DMA Master Configuration Register */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x84: /* Individual Distributed DMA Channel Enable */ + dev->pci_conf[addr] = val; + sis_5595_ddma_recalc(dev); + break; + + case 0x90: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val & 0xc0; + sis_5595_acpi_recalc(dev); + break; + case 0x91: /* ACPI Base Address Register */ + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + break; + + default: + break; + } +} + +void +sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x07: /* Status */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x30); + break; + + case 0x0d: /* Master Latency Timer */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x40: /* BIOS Control Register */ + if (dev->rev >= 0x11) { + dev->pci_conf[addr] = val; + sis_5595_acpi_recalc(dev); + } else + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + case 0x44: /* INTD# Remapping Control Register */ + if (dev->rev == 0x11) { + dev->pci_conf[addr] = val & 0xcf; + sis_5513_apc_recalc(dev, val & 0x10); + } else + dev->pci_conf[addr] = val & 0x8f; + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + + case 0x45: /* ISA Bus Control Register I */ + if (dev->rev >= 0x01) { + if (dev->rev == 0x01) + dev->pci_conf[addr] = val & 0xec; + else + dev->pci_conf[addr] = val; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + if (dev->rev == 0xb0) + sis_5513_apc_recalc(dev, val & 0x02); + } + break; + case 0x46: /* ISA Bus Control Register II */ + if (dev->rev >= 0x11) + dev->pci_conf[addr] = val; + else if (dev->rev == 0x00) + dev->pci_conf[addr] = val & 0xec; + break; + case 0x47: /* DMA Clock and Wait State Control Register */ + switch (dev->rev) { + case 0x01: + dev->pci_conf[addr] = val & 0x3e; + break; + case 0x11: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xb0: + dev->pci_conf[addr] = val & 0xfd; + break; + } + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf[addr] = val; + break; + + default: + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_write(addr, val, priv); + break; + case 0x01: + sis_5513_01_pci_to_isa_write(addr, val, priv); + break; + case 0x11: + sis_5513_11_pci_to_isa_write(addr, val, priv); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_write(addr, val, priv); + break; + } + break; + } +} + +uint8_t +sis_5513_pci_to_isa_read(int addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf[addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + case 0x60: + if (dev->rev >= 0x01) + ret = inb(0x0070); + else + ret = dev->pci_conf[addr]; + break; + } + + sis_5513_pci_to_isa_log("SiS 5513 P2I: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + switch (addr) { + case 0x22: + dev->index = val - 0x50; + break; + case 0x23: + sis_5513_pci_to_isa_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); + + switch (dev->index) { + case 0x00: + dev->regs[dev->index] = val & 0xed; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + break; + case 0x01: + dev->regs[dev->index] = val & 0xf4; + break; + case 0x03: + dev->regs[dev->index] = val & 3; + break; + case 0x04: /* BIOS Register */ + dev->regs[dev->index] = val; + break; + case 0x05: + dev->regs[dev->index] = val; + outb(0x70, val); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +sis_5513_isa_read(uint16_t addr, void *priv) +{ + const sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + uint8_t ret = 0xff; + + if (addr == 0x23) { + if (dev->index == 0x05) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + + sis_5513_pci_to_isa_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); + } + + return ret; +} + +static void +sis_5513_00_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = 0x04; + + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + + dev->regs[0x00] = dev->regs[0x01] = 0x00; + dev->regs[0x03] = dev->regs[0x04] = 0x00; + dev->regs[0x05] = 0x00; + dev->regs[0x08] = dev->regs[0x09] = 0x00; + dev->regs[0x0a] = dev->regs[0x0b] = 0x00; +} + +static void +sis_5513_01_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = 0x80; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0x80; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x80; + dev->pci_conf[0x69] = dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x02; + dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); +} + +static void +sis_5513_11_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = dev->pci_conf[0x68] = 0x00; + dev->pci_conf[0x69] = 0x01; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = dev->pci_conf[0x76] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + dev->sis->ide_bits_1_3_writable = 0; + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); +} + +static void +sis_5513_b0_pci_to_isa_reset(sis_5513_pci_to_isa_t *dev) +{ + dev->pci_conf[0x45] = dev->pci_conf[0x46] = 0x00; + dev->pci_conf[0x47] = 0x00; + + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0x80; + dev->pci_conf[0x63] = dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x01; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = 0x90; + dev->pci_conf[0x69] = 0x02; + dev->pci_conf[0x6a] = 0x80; + dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x20; + dev->pci_conf[0x6d] = 0x19; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = 0x12; + dev->pci_conf[0x71] = dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x88] = 0x00; + dev->pci_conf[0x89] = dev->pci_conf[0x8a] = 0x00; + dev->pci_conf[0x8b] = dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ6, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ7, 15); + + sff_set_mirq(dev->sis->bm[0], 2); + sff_set_mirq(dev->sis->bm[1], 7); + + picint_common(0xffff, 0, 0, NULL); + + sis_5595_ddma_recalc(dev); + sis_5595_acpi_recalc(dev); + + /* SiS 5595 Data Acquisition Module */ + sis_5595_dam_recalc(dev); + sis_5595_dam_reset(dev); + + dev->dam_irq_enable = 0; + + cpu_cpurst_on_sr = 1; + + dev->sis->usb_enabled = 0; + + sis_5513_apc_reset(dev); + sis_5513_apc_recalc(dev, 0); + + if (dev->rev == 0x81) + dev->dam_irq_enable = 1; +} + +static void +sis_5513_pci_to_isa_reset(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x08; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + if ((dev->rev == 0x11) || (dev->rev == 0x81)) + dev->pci_conf[0x08] = 0x01; + else + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x01; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x40] = 0x00; + dev->pci_conf[0x41] = dev->pci_conf[0x42] = 0x80; + dev->pci_conf[0x43] = dev->pci_conf[0x44] = 0x80; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + + switch (dev->rev) { + case 0x00: + sis_5513_00_pci_to_isa_reset(dev); + break; + case 0x01: + sis_5513_01_pci_to_isa_reset(dev); + break; + case 0x11: + sis_5513_11_pci_to_isa_reset(dev); + break; + case 0x81: + case 0xb0: + sis_5513_b0_pci_to_isa_reset(dev); + break; + } + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); +} + +static void +sis_5513_pci_to_isa_close(void *priv) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; + + free(dev); +} + +static void * +sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) +{ + sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) calloc(1, sizeof(sis_5513_pci_to_isa_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* IDEIRQ */ + pci_enable_mirq(2); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_device); + + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + switch (dev->rev) { + case 0x00: + /* MIRQ */ + pci_enable_mirq(0); + pci_enable_mirq(1); + + /* Ports 22h-23h: SiS 5513 ISA */ + io_sethandler(0x0022, 0x0002, + sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); + break; + case 0x01: + /* MIRQ */ + pci_enable_mirq(1); + break; + case 0x11: + case 0x81: + case 0xb0: + /* USBIRQ */ + pci_enable_mirq(3); + + /* ACPI/SCI IRQ */ + pci_enable_mirq(5); + + if (dev->rev == 0xb0) { + /* Data Acquisition Module and SMBUS IRQ */ + pci_enable_mirq(6); + + /* Non-remapped native IDE IRQ */ + pci_enable_mirq(7); + } + + dev->ddma = device_add(&ddma_device); + + switch (dev->rev) { + case 0x11: + dev->sis->acpi = device_add(&acpi_sis_5582_device); + break; + case 0x81: + dev->sis->acpi = device_add(&acpi_sis_5595_1997_device); + break; + case 0xb0: + dev->sis->acpi = device_add(&acpi_sis_5595_device); + dev->smbus = acpi_get_smbus(dev->sis->acpi); + break; + } + + dev->sis->acpi->priv = dev->sis; + acpi_set_slot(dev->sis->acpi, dev->sis->sb_pci_slot); + acpi_set_nvr(dev->sis->acpi, dev->nvr); + acpi_set_irq_mode(dev->sis->acpi, 2); + break; + } + + sis_5513_pci_to_isa_reset(dev); + + return dev; +} + +const device_t sis_5513_p2i_device = { + .name = "SiS 5513 PCI to ISA bridge", + .internal_name = "sis_5513_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5572_p2i_device = { + .name = "SiS 5572 PCI to ISA bridge", + .internal_name = "sis_5572_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_p2i_device = { + .name = "SiS 5582 PCI to ISA bridge", + .internal_name = "sis_5582_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x11, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5595 1997, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_1997_p2i_device = { + .name = "SiS 5595 (1997) PCI to ISA bridge", + .internal_name = "sis_5595_1997_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0x81, /* Actually, 0x01, but we need to somehow distinguish it + from SiS 5572 and SiS 5582, which are also revision 0x01. */ + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_p2i_device = { + .name = "SiS 5595 PCI to ISA bridge", + .internal_name = "sis_5595_pci_to_isa", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5513_pci_to_isa_init, + .close = sis_5513_pci_to_isa_close, + .reset = sis_5513_pci_to_isa_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index c158e2d635..3fb1119785 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -6,13 +6,11 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 5571 Chipset. + * Implementation of the SiS 5571/5572 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2021-2023 Miran Grca. */ #include #include @@ -25,36 +23,26 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - -#include <86box/dma.h> #include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> -#include <86box/hdc_ide.h> -#include <86box/hdc_ide_sff8038i.h> #include <86box/smram.h> -#include <86box/usb.h> - +#include <86box/spd.h> +#include <86box/sis_55xx.h> #include <86box/chipset.h> -/* Shadow RAM */ -#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) -#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) - -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - #ifdef ENABLE_SIS_5571_LOG int sis_5571_do_log = ENABLE_SIS_5571_LOG; @@ -74,660 +62,83 @@ sis_5571_log(const char *fmt, ...) #endif typedef struct sis_5571_t { - uint8_t pci_conf[256], pci_conf_sb[3][256]; - - int nb_pci_slot, sb_pci_slot; + uint8_t nb_slot; + uint8_t sb_slot; - port_92_t *port_92; - sff8038i_t *ide_drive[2]; - smram_t *smram; - usb_t *usb; - - usb_params_t usb_params; + void *h2p; + void *p2i; + void *ide; + void *usb; + sis_55xx_common_t *sis; } sis_5571_t; static void -sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +sis_5571_write(int func, int addr, uint8_t val, void *priv) { - if (cur_reg != 0x76) { - mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE); - mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE); - } else - mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); + const sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS 5571: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - flushmmucache_nopc(); + if (func == 0x00) + sis_5571_host_to_pci_write(addr, val, dev->h2p); } -static void -sis_5571_smm_recalc(sis_5571_t *dev) +static uint8_t +sis_5571_read(int func, int addr, void *priv) { - smram_disable_all(); + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; - switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) { - case 0x00: - smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); - break; - case 0x01: - smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); - break; - case 0x02: - smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); - break; - case 0x03: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); - break; - } + if (func == 0x00) + ret = sis_5571_host_to_pci_read(addr, dev->h2p); - flushmmucache(); -} + sis_5571_log("SiS 5571: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); -void -sis_5571_ide_handler(sis_5571_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) { - if (dev->pci_conf_sb[1][0x4a] & 4) { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void -sis_5571_bm_handler(sis_5571_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); + return ret; } static void -memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv) +sis_5572_write(int func, int addr, uint8_t val, void *priv) { - sis_5571_t *dev = (sis_5571_t *) priv; - - switch (addr) { - case 0x04: /* Command - low byte */ - case 0x05: /* Command - high byte */ - dev->pci_conf[addr] |= val; - break; - - case 0x06: /* Status - Low Byte */ - dev->pci_conf[addr] &= val; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= val & 0xbe; - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; - break; - - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xec; - break; - - case 0x51: /* CACHE */ - dev->pci_conf[addr] = val; - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x52: - dev->pci_conf[addr] = val & 0xd0; - break; - - case 0x53: /* DRAM */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x54: /* FP/EDO */ - dev->pci_conf[addr] = val; - break; - - case 0x55: - dev->pci_conf[addr] = val & 0xe0; - break; - - case 0x56: /* MDLE delay */ - case 0x57: /* SDRAM */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x59: /* Buffer strength and current rating */ - dev->pci_conf[addr] = val; - break; - - case 0x5a: - dev->pci_conf[addr] = val & 0x03; - break; - - case 0x60: /* Undocumented */ - case 0x61: /* Undocumented */ - case 0x62: /* Undocumented */ - case 0x63: /* Undocumented */ - case 0x64: /* Undocumented */ - case 0x65: /* Undocumented */ - case 0x66: /* Undocumented */ - case 0x67: /* Undocumented */ - case 0x68: /* Undocumented */ - case 0x69: /* Undocumented */ - case 0x6a: /* Undocumented */ - case 0x6b: /* Undocumented */ - dev->pci_conf[addr] = val; - break; - - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: /* Attribute of shadow RAM for BIOS area */ - dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); - sis_5571_shadow_recalc(addr, dev); - sis_5571_smm_recalc(dev); - break; - - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x78: /* Allocation of Non-Cacheable area #1 */ - case 0x79: /* NCA1REG2 */ - case 0x7a: /* Allocation of Non-Cacheable area #2 */ - case 0x7b: /* NCA2REG2 */ - dev->pci_conf[addr] = val; - break; - - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xcc; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); - break; - - case 0x84: - case 0x85: - case 0x86: - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellanea */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x90: /* PMU control register */ - case 0x91: /* Address trap for green function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - - if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) { - smi_raise(); - dev->pci_conf[0x9d] |= 1; - } - break; - - case 0x94: /* 6x86 and Green function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: /* Test mode control */ - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; + const sis_5571_t *dev = (sis_5571_t *) priv; - case 0x97: /* programmable 10-bit I/O port address */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - dev->pci_conf[addr] = val; - break; + sis_5571_log("SiS 5572: [W] dev->pci_conf[%02X] = %02X\n", addr, val); - case 0x9d: - dev->pci_conf[addr] &= val; + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); break; - - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0: - case 0xa1: - case 0xa2: - dev->pci_conf[addr] = val; + case 0x01: + sis_5513_ide_write(addr, val, dev->ide); break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5571_smm_recalc(dev); + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); break; } - sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val); } static uint8_t -memory_pci_bridge_read(int func, int addr, void *priv) +sis_5572_read(int func, int addr, void *priv) { - sis_5571_t *dev = (sis_5571_t *) priv; - sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); - return dev->pci_conf[addr]; -} + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; -static void -pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; switch (func) { - case 0: /* Bridge */ - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] |= val & 0x0f; - break; - - case 0x06: /* Status */ - dev->pci_conf_sb[0][addr] &= val; - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x41: /* INTA# Remapping Control Register */ - case 0x42: /* INTB# Remapping Control Register */ - case 0x43: /* INTC# Remapping Control Register */ - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xec; - switch ((val & 0xc0) >> 6) { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - } - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val & 0xec; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x3e; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x5f: - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x60: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x61: /* MIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val; - pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x62: /* On-board Device DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - dma_set_drq((val & 0x07), 1); - break; - - case 0x63: /* IDEIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) { - sff_set_irq_line(dev->ide_drive[0], val & 0x0f); - sff_set_irq_line(dev->ide_drive[1], val & 0x0f); - } - break; - - case 0x64: /* GPIO Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x65: - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x66: /* GPIO Output Mode Control Register */ - case 0x67: /* GPIO Output Mode Control Register */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x68: /* USBIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x1b; - break; - - case 0x69: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6a: - dev->pci_conf_sb[0][addr] = val & 0xfc; - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0x03; - break; - - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x70: - dev->pci_conf_sb[0][addr] = val & 0xde; - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xfe; - break; - - case 0x72: /* SMI Triggered By IRQ/GPIO Control */ - case 0x73: /* SMI Triggered By IRQ/GPIO Control */ - dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; - break; - - case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ - dev->pci_conf_sb[0][addr] = val; - break; - } - sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val); + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); break; - - case 1: /* IDE Controller */ - switch (addr) { - case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 0x05; - sis_5571_ide_handler(dev); - sis_5571_bm_handler(dev); - break; - - case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] &= val; - break; - - case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = val & 0xcf; - sis_5571_ide_handler(dev); - break; - - case 0x0d: /* Latency Time */ - case 0x10: /* Primary Channel Base Address Register */ - case 0x11: /* Primary Channel Base Address Register */ - case 0x12: /* Primary Channel Base Address Register */ - case 0x13: /* Primary Channel Base Address Register */ - case 0x14: /* Primary Channel Base Address Register */ - case 0x15: /* Primary Channel Base Address Register */ - case 0x16: /* Primary Channel Base Address Register */ - case 0x17: /* Primary Channel Base Address Register */ - case 0x18: /* Secondary Channel Base Address Register */ - case 0x19: /* Secondary Channel Base Address Register */ - case 0x1a: /* Secondary Channel Base Address Register */ - case 0x1b: /* Secondary Channel Base Address Register */ - case 0x1c: /* Secondary Channel Base Address Register */ - case 0x1d: /* Secondary Channel Base Address Register */ - case 0x1e: /* Secondary Channel Base Address Register */ - case 0x1f: /* Secondary Channel Base Address Register */ - dev->pci_conf_sb[1][addr] = val; - sis_5571_ide_handler(dev); - break; - - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5571_bm_handler(dev); - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - case 0x48: /* IDE Command Recovery Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0xaf; - sis_5571_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ - case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ - case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ - case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ - dev->pci_conf_sb[1][addr] = val; - break; - } - sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val); + case 0x01: + ret = sis_5513_ide_read(addr, dev->ide); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); break; - - case 2: /* USB Controller */ - switch (addr) { - case 0x04: /* Command - Low Byte */ - dev->pci_conf_sb[2][addr] = val; - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x05: /* Command - High Byte */ - dev->pci_conf_sb[2][addr] = val & 0x03; - break; - - case 0x06: /* Status - Low Byte */ - dev->pci_conf_sb[2][addr] &= val & 0xc0; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf_sb[2][addr] &= val; - break; - - case 0x10: /* Memory Space Base Address Register */ - case 0x11: /* Memory Space Base Address Register */ - case 0x12: /* Memory Space Base Address Register */ - case 0x13: /* Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x14: /* IO Space Base Address Register */ - case 0x15: /* IO Space Base Address Register */ - case 0x16: /* IO Space Base Address Register */ - case 0x17: /* IO Space Base Address Register */ - case 0x3c: /* Interrupt Line */ - dev->pci_conf_sb[2][addr] = val; - break; - } - sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val); - } -} - -static uint8_t -pci_isa_bridge_read(int func, int addr, void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - switch (func) { - case 0: - sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); - return dev->pci_conf_sb[0][addr]; - case 1: - sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); - return dev->pci_conf_sb[1][addr]; - case 2: - sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); - return dev->pci_conf_sb[2][addr]; - default: - return 0xff; - } -} - -static void -sis_5571_usb_update_interrupt(usb_t* usb, void* priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - if (dev->pci_conf_sb[0][0x68] & 0x80) { - /* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */ - switch (dev->pci_conf_sb[0][0x68] & 0x0F) { - case 0x00: - case 0x01: - case 0x02: - case 0x08: - case 0x0d: - break; - default: - if (usb->irq_level) - picint(1 << dev->pci_conf_sb[0][0x68] & 0x0f); - else - picintc(1 << dev->pci_conf_sb[0][0x68] & 0x0f); - break; - } - } else { - if (usb->irq_level) - pci_set_irq(dev->sb_pci_slot, PCI_INTA); - else - pci_clear_irq(dev->sb_pci_slot, PCI_INTA); } -} -static uint8_t -sis_5571_usb_handle_smi(usb_t* usb, void* priv) -{ - /* Left unimplemented for now. */ - return 1; -} + sis_5571_log("SiS 5572: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); -static void -sis_5571_reset(void *priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - /* Memory/PCI Bridge */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x71; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 0xfd; - dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - dev->pci_conf[0xa2] = 0xff; - - /* PCI to ISA bridge */ - dev->pci_conf_sb[0][0x00] = 0x39; - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 0x08; - dev->pci_conf_sb[0][0x04] = 0xfd; - dev->pci_conf_sb[0][0x08] = 0x01; - dev->pci_conf_sb[0][0x0a] = 0x01; - dev->pci_conf_sb[0][0x0b] = 0x06; - - /* IDE Controller */ - dev->pci_conf_sb[1][0x00] = 0x39; - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x08] = 0xc0; - dev->pci_conf_sb[1][0x0a] = 0x01; - dev->pci_conf_sb[1][0x0b] = 0x01; - dev->pci_conf_sb[1][0x0e] = 0x80; - dev->pci_conf_sb[1][0x4a] = 0x06; - sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot); - sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); - - /* USB Controller */ - dev->pci_conf_sb[2][0x00] = 0x39; - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 0x01; - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x08] = 0xb0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 0x03; - dev->pci_conf_sb[2][0x0b] = 0xc0; - dev->pci_conf_sb[2][0x0e] = 0x80; - dev->pci_conf_sb[2][0x14] = 0x01; - dev->pci_conf_sb[2][0x3d] = 0x01; + return ret; } static void @@ -735,37 +146,25 @@ sis_5571_close(void *priv) { sis_5571_t *dev = (sis_5571_t *) priv; - smram_del(dev->smram); free(dev); } static void * -sis_5571_init(const device_t *info) +sis_5571_init(UNUSED(const device_t *info)) { - sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); - memset(dev, 0x00, sizeof(sis_5571_t)); - - dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev); - dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev); - - /* MIRQ */ - pci_enable_mirq(0); - - /* Port 92 & SMRAM */ - dev->port_92 = device_add(&port_92_pci_device); - dev->smram = smram_add(); + sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); - /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + /* Device 0: SiS 5571 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5571_read, sis_5571_write, dev, &dev->nb_slot); + /* Device 1: SiS 5572 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5572_read, sis_5572_write, dev, &dev->sb_slot); - /* USB */ - dev->usb_params.parent_priv = dev; - dev->usb_params.update_interrupt = sis_5571_usb_update_interrupt; - dev->usb_params.smi_handle = sis_5571_usb_handle_smi; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); + dev->sis = device_add(&sis_55xx_common_device); - sis_5571_reset(dev); + dev->h2p = device_add_linked(&sis_5571_h2p_device, dev->sis); + dev->p2i = device_add_linked(&sis_5572_p2i_device, dev->sis); + dev->ide = device_add_linked(&sis_5572_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5572_usb_device, dev->sis); return dev; } @@ -777,7 +176,7 @@ const device_t sis_5571_device = { .local = 0, .init = sis_5571_init, .close = sis_5571_close, - .reset = sis_5571_reset, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c new file mode 100644 index 0000000000..26c74a3c0b --- /dev/null +++ b/src/chipset/sis_5571_h2p.c @@ -0,0 +1,458 @@ +/* + * 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. + * + * Implementation of the SiS 5571 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5571_HOST_TO_PCI_LOG +int sis_5571_host_to_pci_do_log = ENABLE_SIS_5571_HOST_TO_PCI_LOG; + +static void +sis_5571_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_host_to_pci_log(fmt, ...) +#endif + +typedef struct sis_5571_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5571_host_to_pci_t; + +static void +sis_5571_shadow_recalc(sis_5571_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5571_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5571_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + /* Undocumented - DRAM bank registers, the exact layout is currently unknown. */ + case 0x60 ... 0x6b: + dev->pci_conf[addr] = val; + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5571_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5571_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) { + smi_raise(); + dev->pci_conf[0x9d] |= 0x01; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99 ... 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0 ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5571_host_to_pci_read(int addr, void *priv) +{ + const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_host_to_pci_reset(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x54; + dev->pci_conf[0x56] = 0x03; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + + /* Undocumented DRAM bank registers. */ + dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04; + dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04; + dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04; + dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80; + dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6b] = 0x80; + + dev->pci_conf[0x70] = 0x00; + dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = 0x00; + dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = 0x00; + dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = 0x00; + + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = 0x00; + dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = 0x00; + dev->pci_conf[0x7b] = 0x00; + + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = 0x00; + dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = 0x00; + dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + dev->pci_conf[0x87] = 0x00; + + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x8e] = 0x00; + dev->pci_conf[0x8f] = 0x00; + + dev->pci_conf[0x90] = 0x00; + dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = 0x00; + dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = 0x00; + dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = 0x00; + dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = 0x00; + dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = 0x00; + dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5571_smram_recalc(dev); + sis_5571_shadow_recalc(dev); + + flushmmucache(); +} + +static void +sis_5571_host_to_pci_close(void *priv) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) calloc(1, sizeof(sis_5571_host_to_pci_t)); + + dev->sis = device_get_common_priv(); + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5571_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5571_h2p_device = { + .name = "SiS 5571 Host to PCI bridge", + .internal_name = "sis_5571_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5571_host_to_pci_init, + .close = sis_5571_host_to_pci_close, + .reset = sis_5571_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5571_old.c b/src/chipset/sis_5571_old.c new file mode 100644 index 0000000000..f130ecd8a0 --- /dev/null +++ b/src/chipset/sis_5571_old.c @@ -0,0 +1,772 @@ +/* + * 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. + * + * Implementation of the SiS 5571 Chipset. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2021 Tiseno100. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/smram.h> +#include <86box/usb.h> + +#include <86box/chipset.h> + +/* Shadow RAM */ +#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) +#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) +#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY) + +/* IDE Flags (1 Native / 0 Compatibility)*/ +#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) +#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) +#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) +#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) +#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) +#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) +#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + +#ifdef ENABLE_SIS_5571_LOG +int sis_5571_do_log = ENABLE_SIS_5571_LOG; + +static void +sis_5571_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5571_log(fmt, ...) +#endif + +typedef struct sis_5571_t { + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; + uint8_t usb_irq_state; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[3][256]; + + port_92_t *port_92; + sff8038i_t *ide_drive[2]; + smram_t *smram; + usb_t *usb; +} sis_5571_t; + +static void +sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +{ + if (cur_reg != 0x76) { + mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE); + mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE); + } else + mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE); + + flushmmucache_nopc(); +} + +static void +sis_5571_smm_recalc(sis_5571_t *dev) +{ + smram_disable_all(); + + switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) { + case 0x00: + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x01: + smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x02: + smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x03: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5571_ide_handler(sis_5571_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->pci_conf_sb[1][4] & 1) { + if (dev->pci_conf_sb[1][0x4a] & 4) { + ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); + ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); + ide_pri_enable(); + } + if (dev->pci_conf_sb[1][0x4a] & 2) { + ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); + ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); + ide_sec_enable(); + } + } +} + +void +sis_5571_bm_handler(sis_5571_t *dev) +{ + sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); + sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); +} + +static void +memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + switch (addr) { + case 0x04: /* Command - low byte */ + case 0x05: /* Command - high byte */ + dev->pci_conf[addr] |= val; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf[addr] &= val; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= val & 0xbe; + break; + + case 0x0d: /* Master latency timer */ + dev->pci_conf[addr] = val; + break; + + case 0x50: /* Host Interface and DRAM arbiter */ + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* CACHE */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: /* DRAM */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x54: /* FP/EDO */ + dev->pci_conf[addr] = val; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: /* MDLE delay */ + case 0x57: /* SDRAM */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x59: /* Buffer strength and current rating */ + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60: /* Undocumented */ + case 0x61: /* Undocumented */ + case 0x62: /* Undocumented */ + case 0x63: /* Undocumented */ + case 0x64: /* Undocumented */ + case 0x65: /* Undocumented */ + case 0x66: /* Undocumented */ + case 0x67: /* Undocumented */ + case 0x68: /* Undocumented */ + case 0x69: /* Undocumented */ + case 0x6a: /* Undocumented */ + case 0x6b: /* Undocumented */ + dev->pci_conf[addr] = val; + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: /* Attribute of shadow RAM for BIOS area */ + dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); + sis_5571_shadow_recalc(addr, dev); + sis_5571_smm_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); + break; + + case 0x84: + case 0x85: + case 0x86: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x90: /* PMU control register */ + case 0x91: /* Address trap for green function */ + case 0x92: + dev->pci_conf[addr] = val; + break; + + case 0x93: /* STPCLK# and APM SMI control */ + dev->pci_conf[addr] = val; + + if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) { + smi_raise(); + dev->pci_conf[0x9d] |= 1; + } + break; + + case 0x94: /* 6x86 and Green function control */ + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: /* Test mode control */ + case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x97: /* programmable 10-bit I/O port address */ + case 0x98: /* Programmable 16-bit I/O port */ + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + dev->pci_conf[addr] = val; + break; + + case 0x9d: + dev->pci_conf[addr] &= val; + break; + + case 0x9e: /* STPCLK# Assertion Timer */ + case 0x9f: /* STPCLK# De-assertion Timer */ + case 0xa0: + case 0xa1: + case 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0xa3: /* SMRAM access control and Power supply control */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smm_recalc(dev); + break; + + default: + break; + } + sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val); +} + +static uint8_t +memory_pci_bridge_read(UNUSED(int func), int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); + return dev->pci_conf[addr]; +} + +static void +pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + switch (func) { + case 0: /* Bridge */ + switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[0][addr] |= val & 0x0f; + break; + + case 0x06: /* Status */ + dev->pci_conf_sb[0][addr] &= val; + break; + + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x41: /* INTA# Remapping Control Register */ + case 0x42: /* INTB# Remapping Control Register */ + case 0x43: /* INTC# Remapping Control Register */ + case 0x44: /* INTD# Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xec; + switch ((val & 0xc0) >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } + break; + + case 0x46: + dev->pci_conf_sb[0][addr] = val & 0xec; + break; + + case 0x47: /* DMA Clock and Wait State Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x3e; + break; + + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x5f: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x60: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x61: /* MIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val; + pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x62: /* On-board Device DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x0f; + dma_set_drq((val & 0x07), 1); + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + if (val & 0x80) { + sff_set_irq_line(dev->ide_drive[0], val & 0x0f); + sff_set_irq_line(dev->ide_drive[1], val & 0x0f); + } + break; + + case 0x64: /* GPIO Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x66: /* GPIO Output Mode Control Register */ + case 0x67: /* GPIO Output Mode Control Register */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x68: /* USBIRQ Remapping Control Register */ + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x69: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6a: + dev->pci_conf_sb[0][addr] = val & 0xfc; + break; + + case 0x6b: + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0x03; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x70: + dev->pci_conf_sb[0][addr] = val & 0xde; + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xfe; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; + break; + + case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ + case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */ + dev->pci_conf_sb[0][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 1: /* IDE Controller */ + switch (addr) { + case 0x04: /* Command low byte */ + dev->pci_conf_sb[1][addr] = val & 0x05; + sis_5571_ide_handler(dev); + sis_5571_bm_handler(dev); + break; + + case 0x07: /* Status high byte */ + dev->pci_conf_sb[1][addr] &= val; + break; + + case 0x09: /* Programming Interface Byte */ + dev->pci_conf_sb[1][addr] = val & 0xcf; + sis_5571_ide_handler(dev); + break; + + case 0x0d: /* Latency Time */ + case 0x10: /* Primary Channel Base Address Register */ + case 0x11: /* Primary Channel Base Address Register */ + case 0x12: /* Primary Channel Base Address Register */ + case 0x13: /* Primary Channel Base Address Register */ + case 0x14: /* Primary Channel Base Address Register */ + case 0x15: /* Primary Channel Base Address Register */ + case 0x16: /* Primary Channel Base Address Register */ + case 0x17: /* Primary Channel Base Address Register */ + case 0x18: /* Secondary Channel Base Address Register */ + case 0x19: /* Secondary Channel Base Address Register */ + case 0x1a: /* Secondary Channel Base Address Register */ + case 0x1b: /* Secondary Channel Base Address Register */ + case 0x1c: /* Secondary Channel Base Address Register */ + case 0x1d: /* Secondary Channel Base Address Register */ + case 0x1e: /* Secondary Channel Base Address Register */ + case 0x1f: /* Secondary Channel Base Address Register */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_ide_handler(dev); + break; + + case 0x20: /* Bus Master IDE Control Register Base Address */ + case 0x21: /* Bus Master IDE Control Register Base Address */ + case 0x22: /* Bus Master IDE Control Register Base Address */ + case 0x23: /* Bus Master IDE Control Register Base Address */ + dev->pci_conf_sb[1][addr] = val; + sis_5571_bm_handler(dev); + break; + + case 0x30: /* Expansion ROM Base Address */ + case 0x31: /* Expansion ROM Base Address */ + case 0x32: /* Expansion ROM Base Address */ + case 0x33: /* Expansion ROM Base Address */ + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */ + case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ + case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ + case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ + case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ + case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ + case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ + case 0x48: /* IDE Command Recovery Time Control */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val; + break; + + case 0x4a: /* IDE General Control Register 0 */ + dev->pci_conf_sb[1][addr] = val & 0xaf; + sis_5571_ide_handler(dev); + break; + + case 0x4b: /* IDE General Control register 1 */ + case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */ + case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */ + case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */ + case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */ + dev->pci_conf_sb[1][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 2: /* USB Controller */ + switch (addr) { + case 0x04: /* Command - Low Byte */ + dev->pci_conf_sb[2][addr] = val; + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf_sb[2][addr] = val & 0x03; + break; + + case 0x06: /* Status - Low Byte */ + dev->pci_conf_sb[2][addr] &= val & 0xc0; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf_sb[2][addr] &= val; + break; + + case 0x10: /* Memory Space Base Address Register */ + case 0x11: /* Memory Space Base Address Register */ + case 0x12: /* Memory Space Base Address Register */ + case 0x13: /* Memory Space Base Address Register */ + dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); + break; + + case 0x14: /* IO Space Base Address Register */ + case 0x15: /* IO Space Base Address Register */ + case 0x16: /* IO Space Base Address Register */ + case 0x17: /* IO Space Base Address Register */ + case 0x3c: /* Interrupt Line */ + dev->pci_conf_sb[2][addr] = val; + break; + + default: + break; + } + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + default: + break; + } +} + +static uint8_t +pci_isa_bridge_read(int func, int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + + switch (func) { + case 0: + sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); + return dev->pci_conf_sb[0][addr]; + case 1: + sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); + return dev->pci_conf_sb[1][addr]; + case 2: + sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); + return dev->pci_conf_sb[2][addr]; + + default: + return 0xff; + } +} + +static void +sis_5571_reset(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + /* Memory/PCI Bridge */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0xfd; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x9e] = 0xff; + dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa2] = 0xff; + + /* PCI to ISA bridge */ + dev->pci_conf_sb[0][0x00] = 0x39; + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x04] = 0xfd; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + + /* IDE Controller */ + dev->pci_conf_sb[1][0x00] = 0x39; + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x0a] = 0x01; + dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x4a] = 0x06; + sff_set_slot(dev->ide_drive[0], dev->sb_slot); + sff_set_slot(dev->ide_drive[1], dev->sb_slot); + sff_bus_master_reset(dev->ide_drive[0]); + sff_bus_master_reset(dev->ide_drive[1]); + + /* USB Controller */ + dev->pci_conf_sb[2][0x00] = 0x39; + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 0x01; + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x08] = 0xb0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 0x03; + dev->pci_conf_sb[2][0x0b] = 0xc0; + dev->pci_conf_sb[2][0x0e] = 0x80; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x3d] = 0x01; +} + +static void +sis_5571_close(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_init(UNUSED(const device_t *info)) +{ + sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); + memset(dev, 0x00, sizeof(sis_5571_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot); + pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot); + + /* MIRQ */ + pci_enable_mirq(0); + + /* Port 92 & SMRAM */ + dev->port_92 = device_add(&port_92_pci_device); + dev->smram = smram_add(); + + /* SFF IDE */ + dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); + dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5571_reset(dev); + + return dev; +} + +const device_t sis_5571_device = { + .name = "SiS 5571", + .internal_name = "sis_5571", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5571_init, + .close = sis_5571_close, + .reset = sis_5571_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5572_usb.c b/src/chipset/sis_5572_usb.c new file mode 100644 index 0000000000..250c325878 --- /dev/null +++ b/src/chipset/sis_5572_usb.c @@ -0,0 +1,323 @@ +/* + * 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. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5572_USB_LOG +int sis_5572_usb_do_log = ENABLE_SIS_5572_USB_LOG; + +static void +sis_5572_usb_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5572_usb_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5572_usb_log(fmt, ...) +#endif + +typedef struct sis_5572_usb_t { + uint8_t rev; + + uint8_t usb_unk_regs[256]; + uint8_t pci_conf[256]; + + uint16_t usb_unk_base; + + usb_t *usb; + + sis_55xx_common_t *sis; +} sis_5572_usb_t; + +/* SiS 5572 unknown I/O port (second USB PCI BAR). */ +static void +sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + addr = (addr - dev->usb_unk_base) & 0x07; + + sis_5572_usb_log("SiS 5572 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); + + dev->usb_unk_regs[addr] = val; +} + +static uint8_t +sis_5572_usb_unk_read(uint16_t addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->usb_unk_base) & 0x07; + + ret = dev->usb_unk_regs[addr & 0x07]; + + sis_5572_usb_log("SiS 5572 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); + + return ret; +} + +void +sis_5572_usb_write(int addr, uint8_t val, void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + sis_5572_usb_log("SiS 5572 USB: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + if (dev->rev == 0xb0) + dev->pci_conf[addr] = val & 0x47; + else + dev->pci_conf[addr] = val & 0x57; + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + if (dev->pci_conf[0x04] & 0x01) + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf[addr] = val; + break; + + case 0x11 ... 0x13: /* Memory Space Base Address Register */ + dev->pci_conf[addr] = val & ((addr == 0x11) ? 0xf0 : 0xff); + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[4] & 0x02); + break; + + case 0x14 ... 0x15: /* IO Space Base Address Register */ + if (dev->rev == 0xb0) { + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + dev->pci_conf[addr] = val; + dev->usb_unk_base = (dev->pci_conf[0x14] & 0xf8) | + (dev->pci_conf[0x15] << 8); + if (dev->usb_unk_base != 0x0000) { + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + } + break; + + case 0x2c ... 0x2f: + if (dev->rev == 0x11) + dev->pci_conf[addr] = val; + break; + + case 0x3c: /* Interrupt Line */ + dev->pci_conf[addr] = val; + break; + } +} + +uint8_t +sis_5572_usb_read(int addr, void *priv) +{ + const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + uint8_t ret = 0xff; + + if (dev->sis->usb_enabled) { + ret = dev->pci_conf[addr]; + + sis_5572_usb_log("SiS 5572 USB: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5572_usb_reset(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x01; + dev->pci_conf[0x03] = 0x70; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = (dev->rev == 0xb0) ? 0x00 : 0x80; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->rev; + dev->pci_conf[0x09] = 0x10; + dev->pci_conf[0x0a] = 0x03; + dev->pci_conf[0x0b] = 0x0c; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = 0x00; + dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = 0x00; + dev->pci_conf[0x13] = 0x00; + if (dev->rev == 0xb0) { + dev->pci_conf[0x14] = 0x01; + dev->pci_conf[0x15] = 0x00; + dev->pci_conf[0x16] = 0x00; + dev->pci_conf[0x17] = 0x00; + } else if (dev->rev == 0x11) { + dev->pci_conf[0x2c] = 0x00; + dev->pci_conf[0x2d] = 0x00; + dev->pci_conf[0x2e] = 0x00; + dev->pci_conf[0x2f] = 0x00; + } + dev->pci_conf[0x3c] = 0x00; + dev->pci_conf[0x3d] = PCI_INTA; + dev->pci_conf[0x3e] = 0x00; + dev->pci_conf[0x3f] = 0x00; + + if (dev->rev == 0xb0) { + ohci_update_mem_mapping(dev->usb, + dev->pci_conf[0x11], dev->pci_conf[0x12], + dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02); + + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5572_usb_unk_read, NULL, NULL, + sis_5572_usb_unk_write, NULL, NULL, dev); + } + + dev->usb_unk_base = 0x0000; + + memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs)); + } +} + +static void +sis_5572_usb_close(void *priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + free(dev); +} + +static void * +sis_5572_usb_init(UNUSED(const device_t *info)) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) calloc(1, sizeof(sis_5572_usb_t)); + + dev->rev = info->local; + + dev->sis = device_get_common_priv(); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5572_usb_reset(dev); + + return dev; +} + +const device_t sis_5572_usb_device = { + .name = "SiS 5572 USB controller", + .internal_name = "sis_5572_usb", + .flags = DEVICE_PCI, + .local = 0xb0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5582_usb_device = { + .name = "SiS 5582 USB controller", + .internal_name = "sis_5582_usb", + .flags = DEVICE_PCI, + .local = 0xe0, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_usb_device = { + .name = "SiS 5595 USB controller", + .internal_name = "sis_5595_usb", + .flags = DEVICE_PCI, + .local = 0x11, + .init = sis_5572_usb_init, + .close = sis_5572_usb_close, + .reset = sis_5572_usb_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c new file mode 100644 index 0000000000..98b37897c7 --- /dev/null +++ b/src/chipset/sis_5581.c @@ -0,0 +1,185 @@ +/* + * 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. + * + * Implementation of the SiS 5581/5582 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#define ENABLE_SIS_5581_LOG 1 +#ifdef ENABLE_SIS_5581_LOG +int sis_5581_do_log = ENABLE_SIS_5581_LOG; + +static void +sis_5581_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_log(fmt, ...) +#endif + +typedef struct sis_5581_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + + sis_55xx_common_t *sis; +} sis_5581_t; + +static void +sis_5581_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5581: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5581_host_to_pci_write(addr, val, dev->h2p); +} + +static uint8_t +sis_5581_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5581_host_to_pci_read(addr, dev->h2p); + + sis_5581_log("SiS 5581: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5582_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + + sis_5581_log("SiS 5582: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5513_ide_write(addr, val, dev->ide); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5582_read(int func, int addr, void *priv) +{ + const sis_5581_t *dev = (sis_5581_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5513_ide_read(addr, dev->ide); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5581_log("SiS 5582: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_close(void *priv) +{ + sis_5581_t *dev = (sis_5581_t *) priv; + + free(dev); +} + +static void * +sis_5581_init(UNUSED(const device_t *info)) +{ + sis_5581_t *dev = (sis_5581_t *) calloc(1, sizeof(sis_5581_t)); + + /* Device 0: SiS 5581 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5581_read, sis_5581_write, dev, &dev->nb_slot); + /* Device 1: SiS 5582 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5582_read, sis_5582_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->p2i = device_add_linked(&sis_5582_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5581_h2p_device, dev->sis); + dev->ide = device_add_linked(&sis_5582_ide_device, dev->sis); + dev->usb = device_add_linked(&sis_5582_usb_device, dev->sis); + + return dev; +} + +const device_t sis_5581_device = { + .name = "SiS 5581", + .internal_name = "sis_5581", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5581_init, + .close = sis_5581_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c new file mode 100644 index 0000000000..48d61f25e5 --- /dev/null +++ b/src/chipset/sis_5581_h2p.c @@ -0,0 +1,553 @@ +/* + * 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. + * + * Implementation of the SiS 5581 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5581_HOST_TO_PCI_LOG +int sis_5581_host_to_pci_do_log = ENABLE_SIS_5581_HOST_TO_PCI_LOG; + +static void +sis_5581_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5581_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5581_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5581_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5581_io_trap_t; + +typedef struct sis_5581_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_5581_io_trap_t io_traps[10]; + + sis_55xx_common_t *sis; + + smram_t *smram; +} sis_5581_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5581_shadow_recalc(sis_5581_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5581_host_to_pci_log("000F0000-000FFFFF\n"); + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5581_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } + + flushmmucache_nopc(); +} + +static void +sis_5581_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5582_pmu_event(dev->sis->acpi); +} + +static void +sis_5581_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5581_trap_io(size, addr, write, val, priv); +} + +static void +sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5581_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x08) + trap->trap = io_trap_add(sis_5581_trap_io_mask, trap); + else + trap->trap = io_trap_add(sis_5581_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5581_trap_update(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + on = fregs[0x9a]; + + temp = ((fregs[0x96] & 0x02) | (fregs[0x97] << 2)) & 0x03ff; + mask = ~((1 << ((fregs[0x96] >> 3) & 0x07)) - 1); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x08, mask, &(fregs[0x9c]), 0x40, temp, 0x80); + + temp = fregs[0x98] | (fregs[0x99] << 8); + mask = 0xff; + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x08, mask, &(fregs[0x9c]), 0x20, temp, 0x80); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x378, 0x08); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x278, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9c]), 0x08, 0x3f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x9c]), 0x04, 0x2f8, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x9c]), 0x02, 0x1f0, 0x08); + + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x00, 0xff, &(fregs[0x9c]), 0x01, 0x170, 0x08); + + on = fregs[0x9b]; + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x064, 0x01); + sis_5581_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x060, 0x01); +} + +static void +sis_5581_smram_recalc(sis_5581_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0xa3] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +void +sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfc) | (val & 0x03); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x02; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xb8); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x54: + case 0x56 ... 0x57: + case 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xeb; + break; + + case 0x53: + case 0x55: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x58: + dev->pci_conf[addr] = val & 0xfc; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5581_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5581_shadow_recalc(dev); + break; + + case 0x77: /* Characteristics of non-cacheable area */ + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x78: /* Allocation of Non-Cacheable area #1 */ + case 0x79: /* NCA1REG2 */ + case 0x7a: /* Allocation of Non-Cacheable area #2 */ + case 0x7b: /* NCA2REG2 */ + dev->pci_conf[addr] = val; + break; + + case 0x80: /* PCI master characteristics */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xde; + break; + + case 0x82: + dev->pci_conf[addr] = val; + break; + + case 0x83: /* CPU to PCI characteristics */ + dev->pci_conf[addr] = val; + /* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */ + break; + + case 0x84 ... 0x86: + case 0x88 ... 0x8b: + dev->pci_conf[addr] = val; + break; + + case 0x87: /* Miscellanea */ + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x8c ... 0x92: + case 0x9e ... 0xa2: + dev->pci_conf[addr] = val; + break; + + case 0x93: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x9d] |= 0x01; + if (dev->pci_conf[0x9b] & 0x01) + acpi_sis5582_pmu_event(dev->sis->acpi); + } + break; + + case 0x94: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0x96: + dev->pci_conf[addr] = val & 0xfb; + sis_5581_trap_update(dev); + break; + case 0x97 ... 0x9b: + dev->pci_conf[addr] = val; + sis_5581_trap_update(dev); + break; + + case 0x9c ... 0x9d: + dev->pci_conf[addr] &= ~val; + break; + + case 0xa3: + dev->pci_conf[addr] = val; + sis_5581_smram_recalc(dev); + break; + } +} + +uint8_t +sis_5581_host_to_pci_read(int addr, void *priv) +{ + const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5581_host_to_pci_reset(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x97; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x00; + dev->pci_conf[0x53] = 0x38; + dev->pci_conf[0x54] = 0x54; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x80; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x95] = 0x00; + dev->pci_conf[0x96] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0xff; + dev->pci_conf[0xa0] = 0xff; + dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = 0xff; + dev->pci_conf[0xa3] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5581_shadow_recalc(dev); + + sis_5581_trap_update(dev); + + sis_5581_smram_recalc(dev); +} + +static void +sis_5581_host_to_pci_close(void *priv) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5581_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) calloc(1, sizeof(sis_5581_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + sis_5581_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5581_h2p_device = { + .name = "SiS 5581 Host to PCI bridge", + .internal_name = "sis_5581_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5581_host_to_pci_init, + .close = sis_5581_host_to_pci_close, + .reset = sis_5581_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c new file mode 100644 index 0000000000..969fcb8dd0 --- /dev/null +++ b/src/chipset/sis_5591.c @@ -0,0 +1,210 @@ +/* + * 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. + * + * Implementation of the SiS 5591/5592 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5591_LOG +int sis_5591_do_log = ENABLE_SIS_5591_LOG; + +static void +sis_5591_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_log(fmt, ...) +#endif + +typedef struct sis_5591_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5591_t; + +static void +sis_5591_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5591: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5591_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5591_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5591_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5591_log("SiS 5591: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + + sis_5591_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5591_t *dev = (sis_5591_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5591_log("SiS 5592: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_close(void *priv) +{ + sis_5591_t *dev = (sis_5591_t *) priv; + + free(dev); +} + +static void * +sis_5591_init(UNUSED(const device_t *info)) +{ + sis_5591_t *dev = (sis_5591_t *) calloc(1, sizeof(sis_5591_t)); + + /* Device 0: SiS 5591 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5591_read, sis_5591_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5591_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5591_1997_device = { + .name = "SiS 5591 (1997)", + .internal_name = "sis_5591_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5591_device = { + .name = "SiS 5591", + .internal_name = "sis_5591", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5591_init, + .close = sis_5591_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5591_h2p.c b/src/chipset/sis_5591_h2p.c new file mode 100644 index 0000000000..8fcbeeb6f7 --- /dev/null +++ b/src/chipset/sis_5591_h2p.c @@ -0,0 +1,493 @@ +/* + * 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. + * + * Implementation of the SiS 5591 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5591_HOST_TO_PCI_LOG +int sis_5591_host_to_pci_do_log = ENABLE_SIS_5591_HOST_TO_PCI_LOG; + +static void +sis_5591_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5591_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5591_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5591_host_to_pci_t { + uint8_t pci_conf[256]; + + uint8_t states[7]; + uint8_t states_bus[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5591_host_to_pci_t; + +static uint8_t bank_codes[6] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a }; + +static uint32_t bank_sizes[6] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000 }; /* 256 MB */ + +static void +sis_5591_shadow_recalc(sis_5591_host_to_pci_t *dev) +{ + uint32_t base; + uint32_t state; + uint8_t val; + + for (uint8_t i = 0x70; i <= 0x76; i++) { + if (i == 0x76) { + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states[i & 0x0f] = val; + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x5f; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(0xf0000, 0x10000, state); + sis_5591_host_to_pci_log("000F0000-000FFFFF\n"); + + dev->states_bus[i & 0x0f] = val; + } + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + val = dev->pci_conf[i]; + if ((dev->states[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_cpu_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0xf0) | (val & 0x0f); + } + + if (!(dev->pci_conf[0x76] & 0x08)) + val &= 0x55; + if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) { + state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0x0f) | (val & 0xf0); + } + if ((dev->states_bus[i & 0x0f] ^ val) & 0x0a) { + state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_bus_both(base + 0x4000, 0x4000, state); + sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + + dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0xf0) | (val & 0x0f); + } + } + } + + flushmmucache_nopc(); +} + +static void +sis_5591_smram_recalc(sis_5591_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x68] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5591_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= ~(val & 0xf0); + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x51: + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 0x80); + cpu_update_waitstates(); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x68: + dev->pci_conf[addr] = val; + sis_5591_smram_recalc(dev); + break; + + case 0x70 ... 0x75: + dev->pci_conf[addr] = val & 0xee; + sis_5591_shadow_recalc(dev); + break; + case 0x76: + dev->pci_conf[addr] = val & 0xe8; + sis_5591_shadow_recalc(dev); + break; + + case 0x0d: /* Master latency timer */ + case 0x50: + case 0x52: + case 0x54 ... 0x5a: + case 0x5c ... 0x5f: + case 0x64 ... 0x65: + case 0x69 ... 0x6c: + case 0x77 ... 0x7b: + case 0x80 ... 0x8d: + case 0x90: + case 0x97 ... 0xab: + case 0xb0: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xda: + case 0xe0 ... 0xe3: + case 0xef: + dev->pci_conf[addr] = val; + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0xb2: + dev->pci_conf[addr] &= ~(val & 0x01); + break; + } +} + +uint8_t +sis_5591_host_to_pci_read(int addr, void *priv) +{ + const sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5591_host_to_pci_log("SiS 5591 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5591_host_to_pci_reset(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x02; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x18; + dev->pci_conf[0x52] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x0e; + dev->pci_conf[0x56] = 0x40; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x50; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = dev->pci_conf[0x8d] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00; + dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0x00; + dev->pci_conf[0xa0] = dev->pci_conf[0xa1] = 0x00; + dev->pci_conf[0xa2] = dev->pci_conf[0xa3] = 0x00; + dev->pci_conf[0xa4] = dev->pci_conf[0xa5] = 0x00; + dev->pci_conf[0xa6] = dev->pci_conf[0xa7] = 0x00; + dev->pci_conf[0xa8] = dev->pci_conf[0xa9] = 0x00; + dev->pci_conf[0xaa] = dev->pci_conf[0xab] = 0x00; + dev->pci_conf[0xb0] = dev->pci_conf[0xb2] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xd9] = 0x00; + dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = dev->pci_conf[0xe1] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + dev->pci_conf[0xef] = 0x00; + + sis_5591_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_5591_shadow_recalc(dev); + + sis_5591_smram_recalc(dev); +} + +static void +sis_5591_host_to_pci_close(void *priv) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5591_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) calloc(1, sizeof(sis_5591_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 5; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5591_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5591_h2p_device = { + .name = "SiS 5591 Host to PCI bridge", + .internal_name = "sis_5591_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5591_host_to_pci_init, + .close = sis_5591_host_to_pci_close, + .reset = sis_5591_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c new file mode 100644 index 0000000000..4c6dbf7c9a --- /dev/null +++ b/src/chipset/sis_5595_pmu.c @@ -0,0 +1,455 @@ +/* + * 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. + * + * Implementation of the SiS 5572 USB controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_5595_PMU_LOG +int sis_5595_pmu_do_log = ENABLE_SIS_5595_PMU_LOG; + +static void +sis_5595_pmu_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5595_pmu_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5595_pmu_log(fmt, ...) +#endif + +typedef struct sis_5595_pmu_io_trap_t { + void *priv; + void *trap; + uint8_t flags, mask; + uint8_t *sts_reg, sts_mask; + uint16_t addr; +} sis_5595_pmu_io_trap_t; + +typedef struct sis_5595_pmu_t { + uint8_t is_1997; + + uint8_t pci_conf[256]; + + sis_5595_pmu_io_trap_t io_traps[22]; + + sis_55xx_common_t *sis; +} sis_5595_pmu_t; + +static void +sis_5595_pmu_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), + void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + trap->sts_reg[0x04] |= trap->sts_mask; + + if (trap->sts_reg[0x00] & trap->sts_mask) + acpi_sis5595_pmu_event(dev->sis->acpi); + + if (trap->sts_reg[0x20] & trap->sts_mask) + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->flags & 0x03]->selected) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + + if ((addr & trap->mask) == (trap->addr & trap->mask)) + sis_5595_pmu_trap_io(size, addr, write, val, priv); +} + +static void +sis_5595_pmu_trap_io_ide_bm(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; + + if (trap->flags & 0x01) { + dev->pci_conf[0x67] |= 0x01; + dev->pci_conf[0x64] |= 0x08; + } else { + dev->pci_conf[0x67] |= 0x02; + dev->pci_conf[0x64] |= 0x10; + } + acpi_sis5595_pmu_event(dev->sis->acpi); +} + +static void +sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t enable, + uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask, + uint16_t addr, uint16_t size) +{ + sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->priv = (void *) dev; + trap->flags = flags; + trap->mask = mask; + trap->addr = addr; + if (flags & 0x10) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide_bm, trap); + else if (flags & 0x08) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_mask, trap); + else if (flags & 0x04) + trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide, trap); + else + trap->trap = io_trap_add(sis_5595_pmu_trap_io, trap); + trap->sts_reg = sts_reg; + trap->sts_mask = sts_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + +static void +sis_5595_pmu_trap_update(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t trap_id = 0; + uint8_t *fregs = dev->pci_conf; + uint16_t temp; + uint8_t mask; + uint8_t on; + + temp = (fregs[0x7e] | (fregs[0x7f] << 8)) & 0xffe0; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x08, 0x10, 0xff, NULL, 0xff, temp, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + fregs[0x7e] & 0x04, 0x10, 0xff, NULL, 0xff, temp + 8, 0x08); + + on = fregs[0x63] | fregs[0x83]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x04, 0xff, &(fregs[0x63]), 0x02, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x01, 0x06, 0xff, &(fregs[0x63]), 0x01, 0x170, 0x08); + + on = fregs[0x62] | fregs[0x82]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x064, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x060, 0x01); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x62]), 0x40, 0x3f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x62]), 0x20, 0x2f8, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x378, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x278, 0x08); + + temp = (fregs[0x5c] | (fregs[0x5d] << 8)) & 0x03ff; + mask = fregs[0x5d] >> 2; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x08, mask, &(fregs[0x62]), 0x04, temp, 0x40); + + temp = fregs[0x5e] | (fregs[0x5f] << 8); + + if (dev->is_1997) { + mask = fregs[0x4d] & 0x1f; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x20); + } else { + mask = fregs[0x4d]; + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x100); + } + + on = fregs[0x61] | fregs[0x81]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x40, 0x00, 0xff, &(fregs[0x61]), 0x40, 0x3b0, 0x30); + + switch ((fregs[0x4c] >> 6) & 0x03) { + case 0x00: + temp = 0xf40; + break; + case 0x01: + temp = 0xe80; + break; + case 0x02: + temp = 0x604; + break; + default: + temp = 0x530; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x00, 0xff, &(fregs[0x61]), 0x10, temp, 0x08); + + switch ((fregs[0x4c] >> 4) & 0x03) { + case 0x00: + temp = 0x280; + break; + case 0x01: + temp = 0x260; + break; + case 0x02: + temp = 0x240; + break; + default: + temp = 0x220; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x00, 0xff, &(fregs[0x61]), 0x08, temp, 0x14); + + switch ((fregs[0x4c] >> 2) & 0x03) { + case 0x00: + temp = 0x330; + break; + case 0x01: + temp = 0x320; + break; + case 0x02: + temp = 0x310; + break; + default: + temp = 0x300; + break; + } + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x04, 0x00, 0xff, &(fregs[0x61]), 0x04, temp, 0x04); + + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x200, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x388, 0x04); + + on = fregs[0x60] | fregs[0x80]; + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x3f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x370, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x10, 0x05, 0xff, &(fregs[0x60]), 0x10, 0x1f0, 0x08); + sis_5595_pmu_trap_update_devctl(dev, trap_id++, + on & 0x08, 0x07, 0xff, &(fregs[0x60]), 0x08, 0x170, 0x08); +} + +void +sis_5595_pmu_write(int addr, uint8_t val, void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + sis_5595_pmu_log("SiS 5595 PMU: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (dev->sis->usb_enabled) switch (addr) { + default: + break; + + case 0x40 ... 0x4b: + case 0x50 ... 0x5b: + case 0x68 ... 0x7b: + case 0x7d: + dev->pci_conf[addr] = val; + break; + case 0x4c ... 0x4d: + case 0x5c ... 0x63: + case 0x7e ... 0x7f: + case 0x80 ... 0x83: + dev->pci_conf[addr] = val; + sis_5595_pmu_trap_update(dev); + break; + case 0x64 ... 0x67: + dev->pci_conf[addr] &= ~val; + break; + case 0x7c: + dev->pci_conf[addr] = val; + if (val & 0x02) { + dev->pci_conf[0x64] |= 0x04; + if (dev->pci_conf[0x60] & 0x04) + acpi_sis5595_pmu_event(dev->sis->acpi); + } + break; + } +} + +uint8_t +sis_5595_pmu_read(int addr, void *priv) +{ + const sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5595_pmu_log("SiS 5595 PMU: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_pmu_reset(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x09; + dev->pci_conf[0x03] = 0x00; + dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0xff; + dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00; + dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00; + dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00; + dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00; + dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00; + dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00; + dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00; + dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = dev->pci_conf[0x5b] = 0x00; + dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = dev->pci_conf[0x63] = 0x00; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + + sis_5595_pmu_trap_update(dev); + acpi_update_irq(dev->sis->acpi); +} + +static void +sis_5595_pmu_close(void *priv) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv; + + free(dev); +} + +static void * +sis_5595_pmu_init(UNUSED(const device_t *info)) +{ + sis_5595_pmu_t *dev = (sis_5595_pmu_t *) calloc(1, sizeof(sis_5595_pmu_t)); + + dev->sis = device_get_common_priv(); + dev->sis->pmu_regs = dev->pci_conf; + + dev->is_1997 = info->local; + + sis_5595_pmu_reset(dev); + + return dev; +} + +const device_t sis_5595_1997_pmu_device = { + .name = "SiS 5595 (1997) PMU", + .internal_name = "sis_5595_1997_pmu", + .flags = DEVICE_PCI, + .local = 0x01, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5595_pmu_device = { + .name = "SiS 5595 PMU", + .internal_name = "sis_5595_pmu", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5595_pmu_init, + .close = sis_5595_pmu_close, + .reset = sis_5595_pmu_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_55xx.c b/src/chipset/sis_55xx.c new file mode 100644 index 0000000000..2cad21f222 --- /dev/null +++ b/src/chipset/sis_55xx.c @@ -0,0 +1,96 @@ +/* + * 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. + * + * Implementation of the SiS 55xx common structure. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> + +#ifdef ENABLE_SIS_55XX_COMMON_LOG +int sis_55xx_common_do_log = ENABLE_SIS_55XX_COMMON_LOG; + +static void +sis_55xx_common_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_55xx_common_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_55xx_common_log(fmt, ...) +#endif + +static void +sis_55xx_common_close(void *priv) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) priv; + + free(dev); +} + +static void * +sis_55xx_common_init(UNUSED(const device_t *info)) +{ + sis_55xx_common_t *dev = (sis_55xx_common_t *) calloc(1, sizeof(sis_55xx_common_t)); + + return dev; +} + +const device_t sis_55xx_common_device = { + .name = "SiS 55xx Common Structure", + .internal_name = "sis_55xx_common", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_55xx_common_init, + .close = sis_55xx_common_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c new file mode 100644 index 0000000000..ed7384740a --- /dev/null +++ b/src/chipset/sis_5600.c @@ -0,0 +1,210 @@ +/* + * 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. + * + * Implementation of the SiS (5)600 Pentium PCI/ISA Chipset. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/acpi.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5600_LOG +int sis_5600_do_log = ENABLE_SIS_5600_LOG; + +static void +sis_5600_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_log(fmt, ...) +#endif + +typedef struct sis_5600_t { + uint8_t nb_slot; + uint8_t sb_slot; + + void *h2p; + void *p2i; + void *ide; + void *usb; + void *pmu; + + sis_55xx_common_t *sis; +} sis_5600_t; + +static void +sis_5600_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5600: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) + sis_5600_host_to_pci_write(addr, val, dev->h2p); + else if (func == 0x01) + sis_5513_ide_write(addr, val, dev->ide); +} + +static uint8_t +sis_5600_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = sis_5600_host_to_pci_read(addr, dev->h2p); + else if (func == 0x01) + ret = sis_5513_ide_read(addr, dev->ide); + + sis_5600_log("SiS 5600: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5595_write(int func, int addr, uint8_t val, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + + sis_5600_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (func) { + case 0x00: + sis_5513_pci_to_isa_write(addr, val, dev->p2i); + break; + case 0x01: + sis_5595_pmu_write(addr, val, dev->pmu); + break; + case 0x02: + sis_5572_usb_write(addr, val, dev->usb); + break; + } +} + +static uint8_t +sis_5595_read(int func, int addr, void *priv) +{ + const sis_5600_t *dev = (sis_5600_t *) priv; + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5513_pci_to_isa_read(addr, dev->p2i); + break; + case 0x01: + ret = sis_5595_pmu_read(addr, dev->pmu); + break; + case 0x02: + ret = sis_5572_usb_read(addr, dev->usb); + break; + } + + sis_5600_log("SiS 5602: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_close(void *priv) +{ + sis_5600_t *dev = (sis_5600_t *) priv; + + free(dev); +} + +static void * +sis_5600_init(UNUSED(const device_t *info)) +{ + sis_5600_t *dev = (sis_5600_t *) calloc(1, sizeof(sis_5600_t)); + + /* Device 0: SiS 5600 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5600_read, sis_5600_write, dev, &dev->nb_slot); + /* Device 1: SiS 5595 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot); + + dev->sis = device_add(&sis_55xx_common_device); + + dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis); + if (info->local) + dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis); + else + dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis); + dev->h2p = device_add_linked(&sis_5600_h2p_device, dev->sis); + dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis); + if (info->local) + dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis); + else + dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis); + + return dev; +} + +const device_t sis_5600_1997_device = { + .name = "SiS (5)600 (1997)", + .internal_name = "sis_5600_1997", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_5600_device = { + .name = "SiS (5)600", + .internal_name = "sis_5600", + .flags = DEVICE_PCI, + .local = 0, + .init = sis_5600_init, + .close = sis_5600_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_5600_h2p.c b/src/chipset/sis_5600_h2p.c new file mode 100644 index 0000000000..f6ee926da4 --- /dev/null +++ b/src/chipset/sis_5600_h2p.c @@ -0,0 +1,434 @@ +/* + * 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. + * + * Implementation of the SiS (5)600 Host to PCI bridge. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/hdd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> +#include <86box/spd.h> +#include <86box/apm.h> +#include <86box/ddma.h> +#include <86box/acpi.h> +#include <86box/smbus.h> +#include <86box/sis_55xx.h> +#include <86box/chipset.h> +#include <86box/usb.h> +#include <86box/agpgart.h> + +#ifdef ENABLE_SIS_5600_HOST_TO_PCI_LOG +int sis_5600_host_to_pci_do_log = ENABLE_SIS_5600_HOST_TO_PCI_LOG; + +static void +sis_5600_host_to_pci_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5600_host_to_pci_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define sis_5600_host_to_pci_log(fmt, ...) +#endif + +typedef struct { + uint8_t installed; + uint8_t code; + uint32_t phys_size; +} ram_bank_t; + +typedef struct sis_5600_host_to_pci_t { + uint8_t pci_conf[256]; + uint8_t states[7]; + + ram_bank_t ram_banks[3]; + + sis_55xx_common_t *sis; + + smram_t *smram; + + agpgart_t *agpgart; +} sis_5600_host_to_pci_t; + +static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b }; + +static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */ + 0x01000000, /* 16 MB */ + 0x02000000, /* 32 MB */ + 0x04000000, /* 64 MB */ + 0x08000000, /* 128 MB */ + 0x10000000, /* 256 MB */ + 0x20000000 }; /* 512 MB */ + +static void +sis_5600_shadow_recalc(sis_5600_host_to_pci_t *dev) +{ + int state; + uint32_t base; + + for (uint8_t i = 0; i < 8; i++) { + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x70] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x72] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x70] ^ dev->states[0]) & (1 << i)) || + ((dev->pci_conf[0x72] ^ dev->states[2]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + for (uint8_t i = 0; i < 4; i++) { + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x71] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << i)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << i))) { + mem_set_mem_state_both(base, 0x4000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff); + } + } + + base = 0x000f0000; + state = (dev->pci_conf[0x71] & (1 << 4)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[0x73] & (1 << 4)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << 4)) || + ((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << 4))) { + mem_set_mem_state_both(base, 0x10000, state); + sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0xffff); + } + + for (uint8_t i = 0; i < 4; i++) + dev->states[i] = dev->pci_conf[0x70 + i]; + + flushmmucache_nopc(); +} + +static void +sis_5600_smram_recalc(sis_5600_host_to_pci_t *dev) +{ + smram_disable_all(); + + switch (dev->pci_conf[0x6a] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1); + break; + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x6a] & 0x10, 1); + break; + + default: + break; + } + + flushmmucache(); +} + +static void +sis_5600_mask_bar(uint8_t *regs, void *agpgart) +{ + uint32_t bar; + uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x00000000 } ; + + /* Make sure the aperture's base is aligned to its size. */ + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; + + if (!agpgart) + return; + + /* Map aperture and GART. */ + agpgart_set_aperture(agpgart, + bar, + sizes[(regs[0x94] >> 4) & 0x07], + !!(regs[0x94] & 0x02)); + if (regs[0x94] & 0x01) + agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24)); + else + agpgart_set_gart(agpgart, 0x00000000); +} + +void +sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02); + break; + case 0x05: /* Command - High Byte */ + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] = (dev->pci_conf[addr] & ~(val & 0x70)) | (val & 0x01); + break; + + case 0x0d: /* Master latency timer */ + case 0x50 ... 0x5a: + case 0x64 ... 0x69: + case 0x6b ... 0x6c: + case 0x74 ... 0x75: + case 0x77 ... 0x80: + case 0x82 ... 0x8f: + case 0x97 ... 0x9b: + case 0xc8 ... 0xcb: + case 0xd4 ... 0xd8: + case 0xda: + case 0xe0: + case 0xe2 ... 0xe3: + dev->pci_conf[addr] = val; + break; + + case 0x12: + dev->pci_conf[addr] = val & 0xc0; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x13: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + + case 0x60 ... 0x62: + dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0; + break; + + case 0x63: + dev->pci_conf[addr] = dev->ram_banks[0].installed | + (dev->ram_banks[1].installed << 1) | + (dev->ram_banks[2].installed << 2); + break; + + case 0x6a: + dev->pci_conf[addr] = val; + sis_5600_smram_recalc(dev); + break; + + case 0x70 ... 0x73: + dev->pci_conf[addr] = val; + sis_5600_shadow_recalc(dev); + break; + + case 0x91 ... 0x93: + dev->pci_conf[addr] = val; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + case 0x94: + dev->pci_conf[addr] = val & 0x7f; + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + break; + } +} + +uint8_t +sis_5600_host_to_pci_read(int addr, void *priv) +{ + const sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + sis_5600_host_to_pci_log("SiS 5600 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5600_host_to_pci_reset(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x00; + dev->pci_conf[0x03] = 0x56; + dev->pci_conf[0x04] = 0x05; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x10; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0xff; + dev->pci_conf[0x0e] = 0x80; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00; + dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00; + dev->pci_conf[0x34] = 0xc0; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x02; + dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00; + dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00; + dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00; + dev->pci_conf[0x77] = 0x00; + dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00; + dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00; + dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00; + dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00; + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff; + dev->pci_conf[0x86] = 0xff; + dev->pci_conf[0x87] = 0x00; + dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00; + dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00; + dev->pci_conf[0x8c] = 0x00; + dev->pci_conf[0x8d] = 0x62; + dev->pci_conf[0x8e] = dev->pci_conf[0x8f] = 0x00; + dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00; + dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00; + dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00; + dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00; + dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00; + dev->pci_conf[0xc0] = 0x02; + dev->pci_conf[0xc1] = 0x00; + dev->pci_conf[0xc2] = 0x10; + dev->pci_conf[0xc3] = 0x00; + dev->pci_conf[0xc4] = 0x03; + dev->pci_conf[0xc5] = 0x02; + dev->pci_conf[0xc6] = 0x00; + dev->pci_conf[0xc7] = 0x1f; + dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00; + dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00; + dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00; + dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00; + dev->pci_conf[0xd8] = dev->pci_conf[0xda] = 0x00; + dev->pci_conf[0xe0] = 0x00; + dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00; + + sis_5600_mask_bar(dev->pci_conf, dev->agpgart); + + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + + sis_5600_shadow_recalc(dev); + + sis_5600_smram_recalc(dev); +} + +static void +sis_5600_host_to_pci_close(void *priv) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5600_host_to_pci_init(UNUSED(const device_t *info)) +{ + sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) calloc(1, sizeof(sis_5600_host_to_pci_t)); + uint32_t total_mem = mem_size << 10; + ram_bank_t *rb; + + dev->sis = device_get_common_priv(); + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 3; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + uint8_t index = 0; + for (int8_t j = 6; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + index = j; + break; + } + } + if (size != 0x00000000) { + rb->installed = 1; + rb->code = bank_codes[index]; + rb->phys_size = size; + total_mem -= size; + } else + rb->installed = 0; + } + + /* SMRAM */ + dev->smram = smram_add(); + + device_add(&sis_5xxx_agp_device); + dev->agpgart = device_add(&agpgart_device); + + sis_5600_host_to_pci_reset(dev); + + return dev; +} + +const device_t sis_5600_h2p_device = { + .name = "SiS (5)600 Host to PCI bridge", + .internal_name = "sis_5600_host_to_pci", + .flags = DEVICE_PCI, + .local = 0x00, + .init = sis_5600_host_to_pci_init, + .close = sis_5600_host_to_pci_close, + .reset = sis_5600_host_to_pci_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/sis_85c310.c b/src/chipset/sis_85c310.c index 64efba5bb2..296307fe15 100644 --- a/src/chipset/sis_85c310.c +++ b/src/chipset/sis_85c310.c @@ -10,12 +10,13 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t cur_reg, tries, - regs[258]; +typedef struct rabbit_t { + uint8_t cur_reg; + uint8_t tries; + uint8_t regs[258]; } rabbit_t; static void @@ -64,6 +65,8 @@ rabbit_recalcmapping(rabbit_t *dev) /* 128K at 0E0000-0FFFFF */ mem_set_mem_state(0x000e0000, 0x00020000, shflags); break; + default: + break; } flushmmucache(); @@ -89,6 +92,8 @@ rabbit_write(uint16_t addr, uint8_t val, void *priv) } else dev->regs[dev->cur_reg] = val; break; + default: + break; } } @@ -106,6 +111,9 @@ rabbit_read(uint16_t addr, void *priv) } else ret = dev->regs[dev->cur_reg]; break; + + default: + break; } return ret; @@ -120,7 +128,7 @@ rabbit_close(void *priv) } static void * -rabbit_init(const device_t *info) +rabbit_init(UNUSED(const device_t *info)) { rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t)); memset(dev, 0, sizeof(rabbit_t)); diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 6b09cf87e5..b9b2544c86 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -14,6 +14,7 @@ * * Copyright 2019-2020 Miran Grca. */ +#define USE_DRB_HACK #include #include #include @@ -32,16 +33,29 @@ #include <86box/dma.h> #include <86box/nvr.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/machine.h> #include <86box/chipset.h> #include <86box/spd.h> +#ifndef USE_DRB_HACK +#include <86box/row.h> +#endif typedef struct sis_85c496_t { - uint8_t cur_reg, rmsmiblk_count, - regs[127], - pci_conf[256]; + uint8_t cur_reg; + uint8_t rmsmiblk_count; + uint8_t pci_slot; + uint8_t pad; +#ifndef USE_DRB_HACK + uint8_t drb_default; + uint8_t drb_bits; + uint8_t pad0; + uint8_t pad1; +#endif + uint8_t regs[127]; + uint8_t pci_conf[256]; smram_t *smram; pc_timer_t rmsmiblk_timer; port_92_t *port_92; @@ -98,16 +112,18 @@ sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv) dev->regs[dev->cur_reg] = val & 0xfc; dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff); break; + default: + break; } } static uint8_t sis_85c497_isa_read(uint16_t port, void *priv) { - sis_85c496_t *dev = (sis_85c496_t *) priv; - uint8_t ret = 0xff; + const sis_85c496_t *dev = (sis_85c496_t *) priv; + uint8_t ret = 0xff; - if (port == 0x23) + if ((port == 0x23) && (dev->cur_reg < 0xc0)) ret = dev->regs[dev->cur_reg]; else if (port == 0x33) ret = 0x3c /*random_generate()*/; @@ -180,9 +196,29 @@ sis_85c496_ide_handler(sis_85c496_t *dev) } } +#ifndef USE_DRB_HACK +static void +sis_85c496_drb_recalc(sis_85c496_t *dev) +{ + int i; + uint32_t boundary; + + for (i = 7; i >= 0; i--) + row_disable(i); + + for (i = 0; i <= 7; i++) { + boundary = ((uint32_t) dev->pci_conf[0x48 + i]); + row_set_boundary(i, boundary); + } + + flushmmucache(); +} +#endif + + /* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */ static void -sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) +sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t old; @@ -255,8 +291,12 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) case 0x4d: case 0x4e: case 0x4f: - // dev->pci_conf[addr] = val; +#ifdef USE_DRB_HACK spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1); +#else + dev->pci_conf[addr] = val; + sis_85c496_drb_recalc(dev); +#endif break; case 0x50: case 0x51: /* Exclusive Area 0 Setup */ @@ -321,6 +361,8 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) host_base = 0x000e0000; ram_base = 0x000b0000; break; + default: + break; } smram_enable(dev->smram, host_base, ram_base, size, @@ -459,14 +501,17 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x6e; nvr_bank_set(0, !!(val & 0x40), dev->nvr); break; + + default: + break; } } static uint8_t -sis_85c49x_pci_read(int func, int addr, void *priv) +sis_85c49x_pci_read(UNUSED(int func), int addr, void *priv) { - sis_85c496_t *dev = (sis_85c496_t *) priv; - uint8_t ret = dev->pci_conf[addr]; + const sis_85c496_t *dev = (sis_85c496_t *) priv; + uint8_t ret = dev->pci_conf[addr]; switch (addr) { case 0xa0: @@ -481,6 +526,9 @@ sis_85c49x_pci_read(int func, int addr, void *priv) case 0x83: /*Port 70h Mirror*/ ret = inb(0x70); break; + + default: + break; } sis_85c496_log("[%04X:%08X] PCI Read %02X from %02X:%02X\n", CS, cpu_state.pc, ret, func, addr); @@ -538,7 +586,7 @@ sis_85c496_reset(void *priv) // sis_85c49x_pci_write(0, 0x5a, 0x06, dev); for (uint8_t i = 0; i < 8; i++) - sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev); + dev->pci_conf[0x48 + i] = 0x02; sis_85c49x_pci_write(0, 0x80, 0x00, dev); sis_85c49x_pci_write(0, 0x81, 0x00, dev); @@ -569,9 +617,9 @@ sis_85c496_reset(void *priv) } static void -sis_85c496_close(void *p) +sis_85c496_close(void *priv) { - sis_85c496_t *dev = (sis_85c496_t *) p; + sis_85c496_t *dev = (sis_85c496_t *) priv; smram_del(dev->smram); @@ -605,9 +653,11 @@ static void dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */ dev->pci_conf[0xd1] = 0xff; - pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev, &dev->pci_slot); - // sis_85c497_isa_reset(dev); +#if 0 + sis_85c497_isa_reset(dev); +#endif dev->port_92 = device_add(&port_92_device); port_92_set_period(dev->port_92, 2ULL * TIMER_USEC); @@ -627,6 +677,11 @@ static void timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0); +#ifndef USE_DRB_HACK + row_device.local = 7 | (1 << 8) | (0x02 << 16) | (8 << 24); + device_add((const device_t *) &row_device); +#endif + sis_85c496_reset(dev); return dev; diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 94a1fc876b..cf4ff42d7f 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -28,6 +28,7 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/mem.h> #include <86box/smram.h> @@ -35,14 +36,19 @@ #include <86box/machine.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t cur_reg, tries, - reg_base, reg_last, - reg_00, is_471, - force_flush, shadowed, - smram_enabled, pad, - regs[39], scratch[2]; +typedef struct sis_85c4xx_t { + uint8_t cur_reg; + uint8_t tries; + uint8_t reg_base; + uint8_t reg_last; + uint8_t reg_00; + uint8_t is_471; + uint8_t force_flush; + uint8_t shadowed; + uint8_t smram_enabled; + uint8_t pad; + uint8_t regs[39]; + uint8_t scratch[2]; uint32_t mem_state[8]; smram_t *smram; port_92_t *port_92; @@ -124,7 +130,7 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev) } static void -sis_85c4xx_sw_smi_out(uint16_t port, uint8_t val, void *priv) +sis_85c4xx_sw_smi_out(UNUSED(uint16_t port), UNUSED(uint8_t val), void *priv) { sis_85c4xx_t *dev = (sis_85c4xx_t *) priv; @@ -170,6 +176,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) valxor = val ^ dev->regs[rel_reg]; if (rel_reg == 0x19) dev->regs[rel_reg] &= ~val; + else if (rel_reg == 0x00) + dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0); else dev->regs[rel_reg] = val; @@ -235,6 +243,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) port_92_add(dev->port_92); } break; + default: + break; } } else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00)) dev->reg_00 = val; @@ -245,6 +255,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0xe2: dev->scratch[port - 0xe1] = val; return; + default: + break; } } @@ -273,6 +285,10 @@ sis_85c4xx_in(uint16_t port, void *priv) case 0xe1: case 0xe2: ret = dev->scratch[port - 0xe1]; + break; + + default: + break; } return ret; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index db274a60b5..8ec0498ff0 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -6,15 +6,13 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SiS 85C50x Chipset. + * Implementation of the SiS 85C50x and 550x Chipsets. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * Miran Grca, - * - * Copyright 2020-2021 Tiseno100. - * Copyright 2020-2021 Miran Grca. + * Copyright 2020-2024 Miran Grca. + * Copyright 2020-2024 Tiseno100. */ #include #include @@ -27,15 +25,20 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/timer.h> - #include <86box/apm.h> #include <86box/machine.h> #include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat_unused.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/smram.h> #include <86box/pci.h> #include <86box/port_92.h> - +#include <86box/spd.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -57,12 +60,23 @@ sis_85c50x_log(const char *fmt, ...) #endif typedef struct sis_85c50x_t { - uint8_t index, - pci_conf[256], pci_conf_sb[256], - regs[256]; + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t type; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[256]; + uint8_t pci_conf_ide[256]; + uint8_t regs[256]; + uint32_t states[13]; smram_t *smram[2]; port_92_t *port_92; + void *pit; + nvr_t *nvr; + + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_85c50x_t; static void @@ -71,23 +85,59 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev) uint32_t base; uint32_t can_read; uint32_t can_write; + uint32_t state; can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; - if (!can_read) - can_write = MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); - shadowbios = 1; - shadowbios_write = 1; + state = can_read | can_write; + if (dev->states[12] != state) { + mem_set_mem_state_both(0x000f0000, 0x00010000, state); + sis_85c50x_log("F0000-FFFFF: R%c, W%c\n", + (dev->pci_conf[0x53] & 0x40) ? 'I' : 'E', + (dev->pci_conf[0x53] & 0x20) ? 'P' : 'I'); + dev->states[12] = state; + } for (uint8_t i = 0; i < 4; i++) { - base = 0xe0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xd0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - base = 0xc0000 + (i << 14); - mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + base = 0x000e0000 + (i << 14); + state = (dev->pci_conf[0x54] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[8 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x543 & (0x80 >> i)) ? + ((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x54] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[8 + i] = state; + } + + base = 0x000d0000 + (i << 14); + state = (dev->pci_conf[0x55] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[4 + i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x55] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[4 + i] = state; + } + + base = 0x000c0000 + (i << 14); + state = (dev->pci_conf[0x56] & (0x80 >> i)) ? + (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->states[i] != state) { + mem_set_mem_state_both(base, 0x00004000, state); + sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff, + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E', + (dev->pci_conf[0x56] & (0x80 >> i)) ? + ((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E'); + dev->states[i] = state; + } } flushmmucache_nopc(); @@ -111,27 +161,37 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) break; case 0x01: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x02: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x10000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x10000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x10000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x04: host_base |= 0x000a0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x06: host_base |= 0x000b0000; - sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x8000 - 1); + sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", + host_base, host_base + 0x8000 - 1); smram_enable(dev->smram[0], host_base, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); - smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, + 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + break; + default: break; } } @@ -152,7 +212,10 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06); break; case 0x50: - dev->pci_conf[addr] = val; + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xf7; + else + dev->pci_conf[addr] = val; break; case 0x51: /* Cache */ dev->pci_conf[addr] = val; @@ -168,8 +231,6 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) case 0x56: dev->pci_conf[addr] = val; sis_85c50x_shadow_recalc(dev); - if (addr == 0x54) - sis_85c50x_smm_recalc(dev); break; case 0x57: case 0x58: @@ -213,7 +274,35 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = (val & 0x7f); break; case 0x69: - dev->pci_conf[addr] &= ~(val); + dev->pci_conf[addr] &= ~val; + break; + case 0x70 ... 0x77: + if (dev->type & 1) + spd_write_drbs(dev->pci_conf, 0x70, 0x77, 2); + break; + case 0x78: + case 0x7c ... 0x7e: + if (dev->type & 1) + dev->pci_conf[addr] = val; + break; + case 0x79: + if (dev->type & 1) { + spd_write_drbs(dev->pci_conf, 0xf8, 0xff, 4); + dev->pci_conf[addr] = 0x00; + for (uint8_t i = 0; i < 8; i++) + if (dev->pci_conf[0xf8 + i] & 0x80) dev->pci_conf[addr] |= (1 << i); + } + break; + case 0x7a: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xfe; + break; + case 0x7b: + if (dev->type & 1) + dev->pci_conf[addr] = val & 0xe0; + break; + + default: break; } } @@ -221,17 +310,36 @@ 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_t *dev = (sis_85c50x_t *) priv; - uint8_t ret = 0xff; - - if (func == 0x00) - ret = dev->pci_conf[addr]; + const sis_85c50x_t *dev = (sis_85c50x_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) { + if (addr >= 0xf8) + ret = 0x00; + else + ret = dev->pci_conf[addr]; + } sis_85c50x_log("85C501: [R] (%02X, %02X) = %02X\n", func, addr, ret); return ret; } +static void +sis_85c50x_ide_recalc(sis_85c50x_t *dev) +{ + ide_pri_disable(); + ide_set_base(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0170 : 0x01f0); + ide_set_side(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0376 : 0x03f6); + ide_pri_enable(); + + ide_sec_disable(); + ide_set_base(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x01f0 : 0x0170); + ide_set_side(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x03f6 : 0x0376); + if (dev->pci_conf_ide[0x41] & 0x01) + ide_sec_enable(); +} + static void sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) { @@ -239,45 +347,90 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, val); - if (func == 0x00) - switch (addr) { - case 0x04: /* Command */ - dev->pci_conf_sb[addr] = val & 0x0f; - break; - case 0x07: /* Status */ - dev->pci_conf_sb[addr] &= ~(val & 0x30); - break; - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[addr] = val & 0x3f; - break; - case 0x41: - case 0x42: - case 0x43: - case 0x44: - /* INTA/B/C/D# Remapping Control Register */ - dev->pci_conf_sb[addr] = val & 0x8f; - if (val & 0x80) - pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); - break; - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - dev->pci_conf_sb[addr] = val; - break; - } + if (func == 0x00) switch (addr) { + case 0x04: /* Command */ + dev->pci_conf_sb[addr] = val & 0x0f; + break; + case 0x07: /* Status */ + dev->pci_conf_sb[addr] &= ~(val & 0x30); + break; + case 0x40: /* BIOS Control Register */ + dev->pci_conf_sb[addr] = val & 0x3f; + break; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + /* INTA/B/C/D# Remapping Control Register */ + dev->pci_conf_sb[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf); + break; + case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ + case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ + case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ + case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ + dev->pci_conf_sb[addr] = val; + break; + + default: + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) switch (addr) { + case 0x40: + case 0x41: + dev->pci_conf_ide[addr] = val; + sis_85c50x_ide_recalc(dev); + break; + + default: + break; + } } static uint8_t sis_85c50x_sb_read(int func, int addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - uint8_t ret = 0xff; + const sis_85c50x_t *dev = (sis_85c50x_t *) priv; + uint8_t ret = 0xff; - if (func == 0x00) - ret = dev->pci_conf_sb[addr]; + if (func == 0x00) switch (addr) { + default: + ret = dev->pci_conf_sb[addr]; + break; + case 0x4c ... 0x4f: + if (dev->type & 2) + ret = pic_read_icw(0, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x50 ... 0x53: + if (dev->type & 2) + ret = pic_read_icw(1, addr & 0x03); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x54 ... 0x55: + if (dev->type & 2) + ret = pic_read_ocw(0, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x56 ... 0x57: + if (dev->type & 2) + ret = pic_read_ocw(1, addr & 0x01); + else + ret = dev->pci_conf_sb[addr]; + break; + case 0x58 ... 0x5f: + if (dev->type & 2) + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + else + ret = dev->pci_conf_sb[addr]; + break; + } else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) + ret = dev->pci_conf_ide[addr]; sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, ret); @@ -299,10 +452,39 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) case 0x23: switch (dev->index) { case 0x80: - dev->regs[dev->index] = val & 0xe7; + if (dev->type & 2) { + dev->regs[dev->index] = val; + nvr_bank_set(0, !!(val & 0x08), dev->nvr); + } else + dev->regs[dev->index] = val & 0xe7; + switch (val >> 6) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: + cpu_set_isa_pci_div(4); + break; + case 2: + cpu_set_isa_pci_div(3); + break; + + default: + break; + } break; case 0x81: - dev->regs[dev->index] = val & 0xf4; + if (dev->type & 2) + dev->regs[dev->index] = val & 0xf6; + else + dev->regs[dev->index] = val & 0xf4; + break; + case 0x82: + if (dev->type & 2) + dev->regs[dev->index] = val; + break; + case 0x83: + if (dev->type & 2) + dev->regs[dev->index] = val & 0x03; break; case 0x84: case 0x88: @@ -314,16 +496,22 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv) case 0x85: outb(0x70, val); break; + + default: + break; } break; + + default: + break; } } static uint8_t sis_85c50x_isa_read(uint16_t addr, void *priv) { - sis_85c50x_t *dev = (sis_85c50x_t *) priv; - uint8_t ret = 0xff; + const sis_85c50x_t *dev = (sis_85c50x_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0x22: @@ -336,6 +524,9 @@ sis_85c50x_isa_read(uint16_t addr, void *priv) else ret = dev->regs[dev->index]; break; + + default: + break; } sis_85c50x_log("85C503 ISA: [R] (%04X) = %02X\n", addr, ret); @@ -371,6 +562,12 @@ sis_85c50x_reset(void *priv) sis_85c50x_write(0, 0x68, 0x00, dev); sis_85c50x_write(0, 0x69, 0xff, dev); + if (dev->type & 1) { + for (uint8_t i = 0; i < 8; i++) + dev->pci_conf[0x70 + i] = 0x00; + dev->pci_conf[0x79] = 0x00; + } + /* South Bridge (SiS 85C503) */ dev->pci_conf_sb[0x00] = 0x39; dev->pci_conf_sb[0x01] = 0x10; @@ -384,10 +581,51 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x09] = 0x00; dev->pci_conf_sb[0x0a] = 0x01; 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); + + if (dev->type & 2) { + /* IDE (SiS 5503) */ + dev->pci_conf_ide[0x00] = 0x39; + dev->pci_conf_ide[0x01] = 0x10; + dev->pci_conf_ide[0x02] = 0x01; + dev->pci_conf_ide[0x03] = 0x06; + dev->pci_conf_ide[0x04] = 0x89; + dev->pci_conf_ide[0x05] = 0x00; + dev->pci_conf_ide[0x06] = 0x00; + dev->pci_conf_ide[0x07] = 0x00; + dev->pci_conf_ide[0x08] = 0x00; + dev->pci_conf_ide[0x09] = 0x00; + dev->pci_conf_ide[0x0a] = 0x01; + dev->pci_conf_ide[0x0b] = 0x01; + dev->pci_conf_ide[0x0c] = 0x00; + dev->pci_conf_ide[0x0d] = 0x00; + dev->pci_conf_ide[0x0e] = 0x80; + dev->pci_conf_ide[0x0f] = 0x00; + dev->pci_conf_ide[0x10] = 0x71; + dev->pci_conf_ide[0x11] = 0x01; + dev->pci_conf_ide[0x14] = 0xf1; + dev->pci_conf_ide[0x15] = 0x01; + dev->pci_conf_ide[0x18] = 0x71; + dev->pci_conf_ide[0x19] = 0x03; + dev->pci_conf_ide[0x1c] = 0xf1; + dev->pci_conf_ide[0x1d] = 0x03; + dev->pci_conf_ide[0x20] = 0x01; + dev->pci_conf_ide[0x24] = 0x01; + dev->pci_conf_ide[0x40] = 0x00; + dev->pci_conf_ide[0x41] = 0x40; + + sis_85c50x_ide_recalc(dev); + } + + cpu_set_isa_speed(7159091); + + if (dev->type & 2) + nvr_bank_set(0, 0, dev->nvr); } static void @@ -401,16 +639,18 @@ sis_85c50x_close(void *priv) } static void * -sis_85c50x_init(const device_t *info) +sis_85c50x_init(UNUSED(const device_t *info)) { - sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t)); - memset(dev, 0x00, sizeof(sis_85c50x_t)); + sis_85c50x_t *dev = (sis_85c50x_t *) calloc(1, sizeof(sis_85c50x_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + + dev->type = info->local; /* 501/502 (Northbridge) */ - pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot); /* 503 (Southbridge) */ - pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev, &dev->sb_slot); io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev); dev->smram[0] = smram_add(); @@ -418,6 +658,17 @@ sis_85c50x_init(const device_t *info) dev->port_92 = device_add(&port_92_device); + if (dev->type & 2) { + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + + device_add(&ide_pci_2ch_device); + } + sis_85c50x_reset(dev); return dev; @@ -436,3 +687,45 @@ const device_t sis_85c50x_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_550x_85c503_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 1, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_85c50x_5503_device = { + .name = "SiS 85C50x", + .internal_name = "sis_85c50x", + .flags = DEVICE_PCI, + .local = 2, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t sis_550x_device = { + .name = "SiS 550x", + .internal_name = "sis_550x", + .flags = DEVICE_PCI, + .local = 3, + .init = sis_85c50x_init, + .close = sis_85c50x_close, + .reset = sis_85c50x_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index eecaa0a585..dbe39ec5c7 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -30,6 +30,7 @@ #include <86box/timer.h> #include <86box/pit.h> #include <86box/device.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/usb.h> #include <86box/hdc_ide.h> @@ -44,6 +45,11 @@ #define STPC_CLIENT 0x100e55cc typedef struct stpc_t { + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t ide_slot; + uint8_t usb_slot; + uint32_t local; /* Main registers (port 22h/23h) */ @@ -53,23 +59,20 @@ typedef struct stpc_t { /* Host bus interface */ uint16_t host_base; uint8_t host_offset; + uint8_t usb_irq_state; uint8_t host_regs[256]; /* Local bus */ uint16_t localbus_base; uint8_t localbus_offset; + uint8_t pad0; uint8_t localbus_regs[256]; /* PCI devices */ uint8_t pci_conf[4][256]; smram_t *smram; usb_t *usb; - int ide_slot; - int usb_slot; sff8038i_t *bm[2]; - - /* Miscellaneous */ - usb_params_t usb_params; } stpc_t; typedef struct stpc_serial_t { @@ -165,8 +168,8 @@ stpc_host_write(uint16_t addr, uint8_t val, void *priv) static uint8_t stpc_host_read(uint16_t addr, void *priv) { - stpc_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (addr == dev->host_base) ret = dev->host_offset; @@ -195,8 +198,8 @@ stpc_localbus_write(uint16_t addr, uint8_t val, void *priv) static uint8_t stpc_localbus_read(uint16_t addr, void *priv) { - stpc_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (addr == dev->localbus_base) ret = dev->localbus_offset; @@ -248,6 +251,9 @@ stpc_nb_write(int func, int addr, uint8_t val, void *priv) case 0x52: val &= 0x70; break; + + default: + break; } dev->pci_conf[0][addr] = val; @@ -256,8 +262,8 @@ 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_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (func > 0) ret = 0xff; @@ -432,14 +438,17 @@ stpc_ide_write(int func, int addr, uint8_t val, void *priv) sff_bus_master_set_irq(0x00, dev->bm[1]); } break; + + default: + break; } } static uint8_t stpc_ide_read(int func, int addr, void *priv) { - stpc_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (func > 0) ret = 0xff; @@ -489,6 +498,9 @@ stpc_isab_write(int func, int addr, uint8_t val, void *priv) case 0x05: val &= 0x01; break; + + default: + break; } dev->pci_conf[1][addr] = val; @@ -497,8 +509,8 @@ 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_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if ((func == 1) && (dev->local != STPC_ATLAS)) ret = stpc_ide_read(0, addr, priv); @@ -551,6 +563,8 @@ stpc_usb_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[3][addr] = val; ohci_update_mem_mapping(dev->usb, dev->pci_conf[3][0x11], dev->pci_conf[3][0x12], dev->pci_conf[3][0x13], 1); break; + default: + break; } dev->pci_conf[3][addr] = val; @@ -559,8 +573,8 @@ 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_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (func > 0) ret = 0xff; @@ -602,7 +616,8 @@ stpc_remap_localbus(stpc_t *dev, uint16_t localbus_base) static uint8_t stpc_serial_handlers(uint8_t val) { - stpc_serial_t *dev = device_get_priv(&stpc_serial_device); + const stpc_serial_t *dev = device_get_priv(&stpc_serial_device); + if (!dev) { stpc_log("STPC: Not remapping UARTs, disabled by strap (raw %02X)\n", val); return 0; @@ -720,6 +735,9 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv) val &= 0xf1; stpc_serial_handlers(val); break; + + default: + break; } dev->regs[dev->reg_offset] = val; @@ -729,8 +747,8 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv) static uint8_t stpc_reg_read(uint16_t addr, void *priv) { - stpc_t *dev = (stpc_t *) priv; - uint8_t ret; + const stpc_t *dev = (stpc_t *) priv; + uint8_t ret; if (addr == 0x22) ret = dev->reg_offset; @@ -877,17 +895,6 @@ stpc_setup(stpc_t *dev) pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); } -static void -stpc_usb_update_interrupt(usb_t* usb, void* priv) -{ - stpc_t *dev = (stpc_t *) priv; - - if (usb->irq_level) - pci_set_irq(dev->usb_slot, PCI_INTA); - else - pci_clear_irq(dev->usb_slot, PCI_INTA); -} - static void stpc_close(void *priv) { @@ -910,26 +917,21 @@ stpc_init(const device_t *info) dev->local = info->local; - pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev); - dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot); + pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot); if (dev->local == STPC_ATLAS) { - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = stpc_usb_update_interrupt; - dev->usb_params.parent_priv = dev; + pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot); - dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev); - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); - dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev); + dev->usb = device_add(&usb_device); + pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot); } dev->bm[0] = device_add_inst(&sff8038i_device, 1); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); stpc_setup(dev); stpc_reset(dev); @@ -957,7 +959,7 @@ stpc_serial_close(void *priv) } static void * -stpc_serial_init(const device_t *info) +stpc_serial_init(UNUSED(const device_t *info)) { stpc_log("STPC: serial_init()\n"); @@ -990,6 +992,8 @@ stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val) case 0x3: lpt2_remove(); break; + default: + break; } switch (new_addr) { @@ -1068,7 +1072,7 @@ stpc_lpt_close(void *priv) } static void * -stpc_lpt_init(const device_t *info) +stpc_lpt_init(UNUSED(const device_t *info)) { stpc_log("STPC: lpt_init()\n"); diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index dea5ac99a9..7a049b1cbe 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -79,17 +79,14 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> - #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/pic.h> #include <86box/pci.h> - +#include <86box/port_92.h> #include <86box/chipset.h> -#define IDE_BIT 0x01 - #ifdef ENABLE_UMC_8886_LOG int umc_8886_do_log = ENABLE_UMC_8886_LOG; @@ -108,34 +105,32 @@ umc_8886_log(const char *fmt, ...) # define umc_8886_log(fmt, ...) #endif -/* PCI IRQ Flags */ -#define INTA (PCI_INTA + (2 * !(addr & 1))) -#define INTB (PCI_INTB + (2 * !(addr & 1))) -#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED) -#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED) +typedef struct umc_8886_t { + uint8_t max_func; /* Last function number */ + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; -/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */ -#define HAS_IDE dev->has_ide + uint8_t pci_conf_sb[2][256]; /* PCI Registers */ -/* Southbridge Revision */ -#define SB_ID dev->sb_id + uint16_t sb_id; /* Southbridge Revision */ + uint16_t ide_id; /* IDE Revision */ -typedef struct umc_8886_t { - uint8_t max_func, /* Last function number */ - pci_conf_sb[2][256]; /* PCI Registers */ - uint16_t sb_id; /* Southbridge Revision */ - int has_ide; /* Check if Southbridge Revision is AF or F */ + int has_ide; /* Check if Southbridge Revision is F, AF, or BF */ } umc_8886_t; static void -umc_8886_ide_handler(int status) +umc_8886_ide_handler(umc_8886_t *dev) { ide_pri_disable(); ide_sec_disable(); - if (status) { - ide_pri_enable(); - ide_sec_enable(); + if (dev->pci_conf_sb[1][0x04] & 0x01) { + if (dev->pci_conf_sb[1][0x40] & 0x80) + ide_pri_enable(); + + if (dev->pci_conf_sb[1][0x40] & 0x40) + ide_sec_enable(); } } @@ -143,6 +138,7 @@ static void umc_8886_write(int func, int addr, uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; + int irq_routing; if (func <= dev->max_func) switch (func) { @@ -150,8 +146,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80)); switch (addr) { - case 0x04: - case 0x05: + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x42: + case 0x45: + case 0x50 ... 0x55: + case 0x57: + case 0x70 ... 0x76: + case 0x80 ... 0x82: + case 0x90 ... 0x92: + case 0xa0 ... 0xa1: + case 0xa5 ... 0xa8: dev->pci_conf_sb[func][addr] = val; break; @@ -159,50 +164,35 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf_sb[func][addr] &= ~(val & 0xf9); break; - case 0x0c: - case 0x0d: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x40: - case 0x41: - case 0x42: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x43: - case 0x44: dev->pci_conf_sb[func][addr] = val; - pci_set_irq_routing(INTA, IRQRECALCA); - pci_set_irq_routing(INTB, IRQRECALCB); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTA, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTB, irq_routing); break; - - case 0x45: + case 0x44: dev->pci_conf_sb[func][addr] = val; + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTC, irq_routing); + irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) : + PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTD, irq_routing); break; - case 0x46: + case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */ + case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */ /* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */ dev->pci_conf_sb[func][addr] = val; break; - case 0x47: - dev->pci_conf_sb[func][addr] = val; - break; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - dev->pci_conf_sb[func][addr] = val; - break; - case 0x56: dev->pci_conf_sb[func][addr] = val; - switch (val & 2) { + switch (val & 3) { case 0: cpu_set_isa_pci_div(3); break; @@ -212,17 +202,9 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) case 2: cpu_set_isa_pci_div(2); break; + default: + break; } - - break; - - case 0x57: - case 0x70 ... 0x76: - case 0x80: - case 0x81: - case 0x90 ... 0x92: - case 0xa0 ... 0xa1: - dev->pci_conf_sb[func][addr] = val; break; case 0xa2: @@ -236,7 +218,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10)); else smi_raise(); - dev->pci_conf_sb[0][0xa3] |= 0x04; } dev->pci_conf_sb[func][addr] = val; @@ -247,8 +228,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2)); break; - case 0xa5 ... 0xa8: - dev->pci_conf_sb[func][addr] = val; + default: break; } break; @@ -259,7 +239,8 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: dev->pci_conf_sb[func][addr] = val; - umc_8886_ide_handler(val & 1); + if (dev->ide_id == 0x673a) + umc_8886_ide_handler(dev); break; case 0x07: @@ -267,20 +248,33 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) break; case 0x3c: + case 0x41 ... 0x4b: + case 0x54 ... 0x59: + if (dev->ide_id == 0x673a) + dev->pci_conf_sb[func][addr] = val; + break; + case 0x40: - case 0x41: - dev->pci_conf_sb[func][addr] = val; + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[func][addr] = val; + umc_8886_ide_handler(dev); + } + break; + + default: break; } break; + default: + break; } } static uint8_t umc_8886_read(int func, int addr, void *priv) { - umc_8886_t *dev = (umc_8886_t *) priv; - uint8_t ret = 0xff; + const umc_8886_t *dev = (umc_8886_t *) priv; + uint8_t ret = 0xff; if (func <= dev->max_func) ret = dev->pci_conf_sb[func][addr]; @@ -296,50 +290,76 @@ umc_8886_reset(void *priv) memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0])); memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1])); - dev->pci_conf_sb[0][0] = 0x60; /* UMC */ - dev->pci_conf_sb[0][1] = 0x10; - - dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */ - dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff); - - dev->pci_conf_sb[0][4] = 0x0f; - dev->pci_conf_sb[0][7] = 2; - - dev->pci_conf_sb[0][8] = 0x0e; - + dev->pci_conf_sb[0][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = (dev->sb_id & 0xff); /* 8886xx */ + dev->pci_conf_sb[0][0x03] = ((dev->sb_id >> 8) & 0xff); + dev->pci_conf_sb[0][0x04] = 0x0f; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = 0x0e; dev->pci_conf_sb[0][0x09] = 0x00; dev->pci_conf_sb[0][0x0a] = 0x01; dev->pci_conf_sb[0][0x0b] = 0x06; - - dev->pci_conf_sb[0][0x40] = 1; - dev->pci_conf_sb[0][0x41] = 6; - dev->pci_conf_sb[0][0x42] = 8; - dev->pci_conf_sb[0][0x43] = 0x9a; - dev->pci_conf_sb[0][0x44] = 0xbc; - dev->pci_conf_sb[0][0x45] = 4; + dev->pci_conf_sb[0][0x40] = 0x01; + dev->pci_conf_sb[0][0x41] = 0x06; + dev->pci_conf_sb[0][0x42] = 0x08; + dev->pci_conf_sb[0][0x43] = 0x00; + dev->pci_conf_sb[0][0x44] = 0x00; + dev->pci_conf_sb[0][0x45] = 0x04; + dev->pci_conf_sb[0][0x46] = 0x00; dev->pci_conf_sb[0][0x47] = 0x40; - dev->pci_conf_sb[0][0x50] = 1; - dev->pci_conf_sb[0][0x51] = 3; + dev->pci_conf_sb[0][0x50] = 0x01; + dev->pci_conf_sb[0][0x51] = 0x03; + dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00; + dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; + dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; + dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00; + dev->pci_conf_sb[0][0x82] = 0x00; + dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00; + dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00; + dev->pci_conf_sb[0][0xa4] = 0x00; dev->pci_conf_sb[0][0xa8] = 0x20; - if (HAS_IDE) { - dev->pci_conf_sb[1][0] = 0x60; /* UMC */ - dev->pci_conf_sb[1][1] = 0x10; - - dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */ - dev->pci_conf_sb[1][3] = 0x67; - - dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */ - - dev->pci_conf_sb[1][8] = 0x10; - - dev->pci_conf_sb[1][0x09] = 0x0f; - dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1; - - umc_8886_ide_handler(1); + if (dev->has_ide) { + dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */ + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = (dev->ide_id & 0xff); /* 8886xx IDE */ + dev->pci_conf_sb[1][0x03] = ((dev->ide_id >> 8) & 0xff); + dev->pci_conf_sb[1][0x04] = 0x05; /* Start with Internal IDE Enabled */ + dev->pci_conf_sb[1][0x08] = 0x10; + dev->pci_conf_sb[1][0x09] = 0x8f; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0x10; + + if (dev->ide_id == 0x673a) { + dev->pci_conf_sb[1][0x40] = 0xc0; + dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; + dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; + dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; + dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00; + dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00; + dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00; + + umc_8886_ide_handler(dev); + + picintc(1 << 14); + picintc(1 << 15); + } } - for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */ + for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */ pci_set_irq_routing(i, PCI_IRQ_DISABLED); cpu_set_isa_pci_div(3); @@ -360,17 +380,28 @@ umc_8886_init(const device_t *info) umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t)); memset(dev, 0, sizeof(umc_8886_t)); - dev->has_ide = !!(info->local == 0x886a); - pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */ + /* Device 12: UMC 8886xx */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); - /* Add IDE if UM8886AF variant */ - if (HAS_IDE) - device_add(&ide_pci_2ch_device); + /* Get the Southbridge Revision */ + dev->sb_id = info->local & 0xffff; - dev->max_func = (HAS_IDE) ? 1 : 0; + /* IDE Revision */ + dev->ide_id = info->local >> 16; - /* Get the Southbridge Revision */ - SB_ID = info->local; + dev->has_ide = (dev->ide_id != 0x0000); + + dev->max_func = 0; + + /* Add IDE if this is the UM8886AF or UM8886BF. */ + if (dev->ide_id == 0x673a) { + /* UM8886BF */ + device_add(&ide_pci_2ch_device); + dev->max_func = 1; + } else if (dev->ide_id == 0x1001) { + /* UM8886AF */ + device_add(&ide_um8673f_device); + } umc_8886_reset(dev); @@ -381,7 +412,7 @@ const device_t umc_8886f_device = { .name = "UMC 8886F", .internal_name = "umc_8886f", .flags = DEVICE_PCI, - .local = 0x8886, + .local = 0x00008886, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, @@ -392,10 +423,24 @@ const device_t umc_8886f_device = { }; const device_t umc_8886af_device = { - .name = "UMC 8886AF/8886BF", + .name = "UMC 8886AF", .internal_name = "umc_8886af", .flags = DEVICE_PCI, - .local = 0x886a, + .local = 0x1001886a, + .init = umc_8886_init, + .close = umc_8886_close, + .reset = umc_8886_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t umc_8886bf_device = { + .name = "UMC 8886BF", + .internal_name = "umc_8886bf", + .flags = DEVICE_PCI, + .local = 0x673a888a, .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c new file mode 100644 index 0000000000..7de2ca1d08 --- /dev/null +++ b/src/chipset/umc_8890.c @@ -0,0 +1,241 @@ +/* + * 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. + * + * Implementation of the UMC 8890 Chipset. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2021 Tiseno100. + * Copyright 2021-2024 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/apm.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UMC_8890_LOG +int umc_8890_do_log = ENABLE_UMC_8890_LOG; + +static void +umc_8890_log(const char *fmt, ...) +{ + va_list ap; + + if (umc_8890_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define umc_8890_log(fmt, ...) +#endif + +typedef struct umc_8890_t { + uint8_t pci_slot; + + uint8_t pci_conf[256]; /* PCI Registers */ + + int mem_state[2]; + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ +} umc_8890_t; + +static void +um8890_shadow(umc_8890_t *dev) +{ + uint8_t flag; + uint16_t state; + + flag = (dev->pci_conf[0x5f] & 0x0c) >> 2; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) { + mem_set_mem_state_both(0xe0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[1] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f); + } + + flag = (dev->pci_conf[0x5f] & 0xc0) >> 6; + state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0xc0) { + mem_set_mem_state_both(0xf0000, 0x10000, state); + dev->mem_state[1] = (dev->mem_state[1] & 0x0f) | (dev->pci_conf[0x5f] & 0xf0); + } + + for (uint8_t i = 0; i < 8; i++) { + state = (dev->pci_conf[0x5d] & (1 << i)) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : + (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((dev->mem_state[0] ^ dev->pci_conf[0x5d]) & (1 << i)) { + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, state); + dev->mem_state[0] = (dev->mem_state[0] & ~(1 << i)) | (dev->pci_conf[0x5d] & (1 << i)); + } + } + + flushmmucache_nopc(); +} + + +static void +um8890_smram(umc_8890_t *dev) +{ + smram_disable_all(); + + /* Bit 4, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled + in SMM, and is always set to A0000-BFFFF. */ + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x65] & 0x10, 1); +} + +static void +um8890_write(int func, int addr, uint8_t val, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + if (func == 0) switch (addr) { + case 0x04 ... 0x05: + case 0x0c ... 0x0d: + case 0x40 ... 0x5b: + case 0x60 ... 0x63: + case 0x66 ... 0xff: + dev->pci_conf[addr] = val; + break; + + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf9); + break; + + case 0x5c ... 0x5f: + dev->pci_conf[addr] = val; + um8890_shadow(dev); + break; + + /* Register 64h, 16-bit: + Bit 12: SMRAM enabled outside SMM (1 = yes, 0 = no); + Bit 10: ???? (set by Award BIOS); + Bits 7- 0: SMM handler offset to SMBASE, shifted to the right by 14. + */ + case 0x64: case 0x65: + dev->pci_conf[addr] = val; + if (addr == 0x65) + um8890_smram(dev); + break; + } + + umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + + +static uint8_t +um8890_read(int func, int addr, void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pci_conf[addr]; + + return ret; +} + +static void +umc_8890_reset(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); + + /* Defaults */ + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x91; /* 8891F */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x01; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = 0x00; + dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = 0x00; + dev->pci_conf[0x64] = 0x00; + dev->pci_conf[0x65] = 0x00; + + um8890_shadow(dev); + + um8890_smram(dev); +} + + +static void +umc_8890_close(void *priv) +{ + umc_8890_t *dev = (umc_8890_t *)priv; + + smram_del(dev->smram); + free(dev); +} + + +static void * +umc_8890_init(const device_t *info) +{ + umc_8890_t *dev = (umc_8890_t *) calloc(1, sizeof(umc_8890_t)); + + /* Device 0: UMC 8890 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev, &dev->pci_slot); + + /* Port 92 */ + device_add(&port_92_pci_device); + + dev->smram = smram_add(); + + umc_8890_reset(dev); + + return dev; +} + +const device_t umc_8890_device = { + .name = "UMC 8890(8891BF/8892BF)", + .internal_name = "umc_8890", + .flags = DEVICE_PCI, + .local = 0x886a, + .init = umc_8890_init, + .close = umc_8890_close, + .reset = umc_8890_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index e3174be8ab..a7ed0b880e 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -14,13 +14,11 @@ * Note 2: Additional information were also used from all * around the web. * - * - * * Authors: Tiseno100, * Miran Grca, * * Copyright 2021 Tiseno100. - * Copyright 2021 Miran Grca. + * Copyright 2021-2024 Miran Grca. */ /* @@ -75,15 +73,24 @@ Bit 3: CC000-CFFFF Read Enable Bit 2: C8000-CBFFF Read Enable Bit 1: C0000-C7FFF Read Enable - Bit 0: Enable C0000-DFFFF Shadow Segment Bits + Bit 0: E0000-EFFFF Read Enable Register 55: - Bit 7: E0000-FFFF Read Enable + Bit 7: F0000-FFFF Read Enable Bit 6: Shadow Write Status (1: Write Protect/0: Write) Register 56h & 57h: DRAM Bank 0 Configuration Register 58h & 59h: DRAM Bank 1 Configuration + Register 5A: + Bit 2: Detrubo + + Register 5C: + Bits 7-0: SMRAM base A27-A20 + + Register 5D: + Bits 3-0: SMRAM base A31-A28 + Register 60: Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM @@ -103,24 +110,11 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> - #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/smram.h> - -#ifdef USE_DYNAREC -# include "codegen_public.h" -#else -# ifdef USE_NEW_DYNAREC -# define PAGE_MASK_SHIFT 6 -# else -# define PAGE_MASK_INDEX_MASK 3 -# define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_SHIFT 4 -# endif -# define PAGE_MASK_MASK 63 -#endif #include <86box/chipset.h> #ifdef ENABLE_HB4_LOG @@ -142,11 +136,15 @@ hb4_log(const char *fmt, ...) #endif typedef struct hb4_t { - uint8_t shadow, - shadow_read, shadow_write, - pci_conf[256]; /* PCI Registers */ + uint8_t pci_slot; + + uint8_t pci_conf[256]; /* PCI Registers */ + int mem_state[9]; - smram_t *smram[3]; /* SMRAM Handlers */ + + uint32_t smram_base; + + smram_t *smram; /* SMRAM Handler */ } hb4_t; static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY), @@ -177,7 +175,8 @@ hb4_shadow_bios_low(hb4_t *dev) { int state; - state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)]; + /* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */ + state = shadow_bios[dev->pci_conf[0x55] >> 6]; if (state != dev->mem_state[7]) { mem_set_mem_state_both(0xe0000, 0x10000, state); @@ -195,7 +194,8 @@ hb4_shadow_main(hb4_t *dev) int n = 0; for (uint8_t i = 0; i < 6; i++) { - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[i + 1]) { n++; @@ -212,7 +212,8 @@ hb4_shadow_video(hb4_t *dev) { int state; - state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[0]) { mem_set_mem_state_both(0xc0000, 0x8000, state); @@ -242,26 +243,30 @@ static void hb4_smram(hb4_t *dev) { smram_disable_all(); + if (dev->smram_base != 0x00000000) + umc_smram_recalc(dev->smram_base >> 12, 0); + + dev->smram_base = ((uint32_t) dev->pci_conf[0x5c]) << 20; + dev->smram_base |= ((uint32_t) (dev->pci_conf[0x5d] & 0x0f)) << 28; + dev->smram_base |= 0x000a0000; /* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled in SMM, and is always set to A0000-BFFFF. */ - smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */ - smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); - /* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */ - smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + smram_enable(dev->smram, dev->smram_base, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); /* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses this. */ if (dev->pci_conf[0x60] & 0x20) { if (dev->pci_conf[0x60] & 0x01) - mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02); - mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02); + mem_set_mem_state_smram_ex(0, dev->smram_base, 0x20000, 0x02); + mem_set_mem_state_smram_ex(1, dev->smram_base, 0x20000, 0x02); } + + umc_smram_recalc(dev->smram_base >> 12, 1); } static void -hb4_write(int func, int addr, uint8_t val, void *priv) +hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) { hb4_t *dev = (hb4_t *) priv; @@ -288,48 +293,40 @@ hb4_write(int func, int addr, uint8_t val, void *priv) cpu_update_waitstates(); break; - case 0x51: - case 0x52: - dev->pci_conf[addr] = val; - break; - - case 0x53: + case 0x51 ... 0x53: dev->pci_conf[addr] = val; - hb4_log("HB53: %02X\n", val); break; - case 0x55: - dev->shadow_read = (val & 0x80); - dev->shadow_write = (val & 0x40); - dev->pci_conf[addr] = val; - hb4_shadow(dev); - break; - case 0x54: - dev->shadow = (val & 0x01) << 1; + case 0x54 ... 0x55: dev->pci_conf[addr] = val; hb4_shadow(dev); break; - case 0x56 ... 0x5f: + case 0x56 ... 0x5b: + case 0x5e ... 0x5f: dev->pci_conf[addr] = val; break; + case 0x5c ... 0x5d: case 0x60: dev->pci_conf[addr] = val; hb4_smram(dev); break; - case 0x61: + case 0x61 ... 0x62: dev->pci_conf[addr] = val; break; + + default: + break; } } static uint8_t hb4_read(int func, int addr, void *priv) { - hb4_t *dev = (hb4_t *) priv; - uint8_t ret = 0xff; + const hb4_t *dev = (hb4_t *) priv; + uint8_t ret = 0xff; if (func == 0) ret = dev->pci_conf[addr]; @@ -343,30 +340,35 @@ hb4_reset(void *priv) hb4_t *dev = (hb4_t *) priv; memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); - dev->pci_conf[0] = 0x60; /* UMC */ - dev->pci_conf[1] = 0x10; - - dev->pci_conf[2] = 0x81; /* 8881x */ - dev->pci_conf[3] = 0x88; - - dev->pci_conf[7] = 2; - - dev->pci_conf[8] = 4; - + dev->pci_conf[0x00] = 0x60; /* UMC */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x81; /* 8881x */ + dev->pci_conf[0x03] = 0x88; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x04; dev->pci_conf[0x09] = 0x00; dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; - - dev->pci_conf[0x51] = 1; - dev->pci_conf[0x52] = 1; - dev->pci_conf[0x5a] = 4; - dev->pci_conf[0x5c] = 0xc0; + dev->pci_conf[0x50] = 0x00; + dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x01; + dev->pci_conf[0x53] = 0x00; + dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = 0x00; + dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = 0x00; + dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = 0x00; + dev->pci_conf[0x5a] = 0x04; + dev->pci_conf[0x5c] = 0x00; dev->pci_conf[0x5d] = 0x20; dev->pci_conf[0x5f] = 0xff; + dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = 0x00; + dev->pci_conf[0x62] = 0x00; - hb4_write(0, 0x54, 0x00, dev); - hb4_write(0, 0x55, 0x00, dev); - hb4_write(0, 0x60, 0x80, dev); + hb4_shadow(dev); + hb4_smram(dev); cpu_cache_ext_enabled = 0; cpu_update_waitstates(); @@ -379,25 +381,25 @@ hb4_close(void *priv) { hb4_t *dev = (hb4_t *) priv; + smram_del(dev->smram); free(dev); } static void * -hb4_init(const device_t *info) +hb4_init(UNUSED(const device_t *info)) { hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t)); memset(dev, 0, sizeof(hb4_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */ + pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */ /* Port 92 */ device_add(&port_92_pci_device); /* SMRAM */ - dev->smram[0] = smram_add(); - dev->smram[1] = smram_add(); - dev->smram[2] = smram_add(); + dev->smram = smram_add(); + dev->smram_base = 0x000a0000; hb4_reset(dev); return dev; diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 61485fc91e..7c1203c3ab 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -10,13 +10,12 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, + * RichardG, * Tiseno100, * * Copyright 2020 Miran Grca. - * Copyright 2020 Melissa Goad. + * Copyright 2020 RichardG. * Copyright 2020 Tiseno100. */ #include @@ -45,10 +44,15 @@ #define VIA_8601 0x86010500 typedef struct via_apollo_t { - uint32_t id; uint8_t drb_unit; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pci_conf[256]; + uint32_t id; + smram_t *smram; agpgart_t *agpgart; } via_apollo_t; @@ -69,6 +73,8 @@ apollo_map(uint32_t addr, uint32_t size, int state) case 3: mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; + default: + break; } flushmmucache_nopc(); @@ -392,8 +398,8 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) smram_disable_all(); if (dev->id >= VIA_691) switch (val & 0x03) { - case 0x00: default: + case 0x00: apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); /* Non-SMM: Code PCI, Data PCI */ break; @@ -412,8 +418,8 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) } else if (dev->id >= VIA_597) switch (val & 0x03) { - case 0x00: default: + case 0x00: /* Disable SMI Address Redirection (default) */ apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0); apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); @@ -458,6 +464,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 3); apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 3); break; + + default: + break; } break; case 0x65: @@ -666,13 +675,15 @@ 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_t *dev = (via_apollo_t *) priv; - uint8_t ret = 0xff; + const via_apollo_t *dev = (via_apollo_t *) priv; + uint8_t ret = 0xff; switch (func) { case 0: ret = dev->pci_conf[addr]; break; + default: + break; } return ret; @@ -685,6 +696,8 @@ via_apollo_write(int func, int addr, uint8_t val, void *priv) case 0: via_apollo_host_bridge_write(func, addr, val, priv); break; + default: + break; } } @@ -706,7 +719,7 @@ via_apollo_init(const device_t *info) if (dev->id != VIA_8601) apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ - pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev, &dev->pci_slot); dev->id = info->local; @@ -728,6 +741,9 @@ via_apollo_init(const device_t *info) case VIA_694: device_add(&via_mvp3_agp_device); break; + + default: + break; } if (dev->id >= VIA_597) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index aa83c99b96..1f153092be 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -10,14 +10,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, * RichardG, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. * Copyright 2020-2021 RichardG. */ #include @@ -41,6 +37,8 @@ #include <86box/ddma.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -109,22 +107,30 @@ enum { typedef struct { struct _pipc_ *dev; void *trap; - uint32_t *sts_reg, *en_reg, mask; + uint32_t *sts_reg; + uint32_t *en_reg; + uint32_t mask; } pipc_io_trap_t; typedef struct _pipc_ { - uint32_t local; - uint8_t max_func, max_pcs; + uint8_t max_func; + uint8_t max_pcs; + uint8_t pci_slot; + uint8_t pad; + + uint8_t pci_isa_regs[256]; + uint8_t ide_regs[256]; + uint8_t usb_regs[2][256]; + uint8_t power_regs[256]; + uint8_t ac97_regs[2][256]; + uint8_t fmnmi_regs[4]; + uint8_t fmnmi_status; - uint8_t pci_isa_regs[256], - ide_regs[256], - usb_regs[2][256], - power_regs[256], - ac97_regs[2][256], fmnmi_regs[4], fmnmi_status; + uint32_t local; sff8038i_t *bm[2]; nvr_t *nvr; - int nvr_enabled, slot; + int nvr_enabled; ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; @@ -132,9 +138,14 @@ typedef struct _pipc_ { acpi_t *acpi; pipc_io_trap_t io_traps[TRAP_MAX]; - void *gameport, *ac97, *sio, *hwm; + void *gameport; + void *ac97; + void *sio; + void *hwm; sb_t *sb; - uint16_t midigame_base, sb_base, fmnmi_base; + uint16_t midigame_base; + uint16_t sb_base; + uint16_t fmnmi_base; } pipc_t; #ifdef ENABLE_PIPC_LOG @@ -162,7 +173,7 @@ 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 void -pipc_io_trap_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +pipc_io_trap_pact(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv) { pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; @@ -175,7 +186,7 @@ pipc_io_trap_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *pri } static void -pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +pipc_io_trap_glb(UNUSED(int size), UNUSED(uint16_t addr), uint8_t write, UNUSED(uint8_t val), void *priv) { pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; @@ -199,10 +210,9 @@ pipc_reset_hard(void *priv) pipc_log("PIPC: reset_hard()\n"); pipc_t *dev = (pipc_t *) priv; - uint16_t old_base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - sff_bus_master_reset(dev->bm[0], old_base); - sff_bus_master_reset(dev->bm[1], old_base + 8); + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); memset(dev->pci_isa_regs, 0, 256); memset(dev->ide_regs, 0, 256); @@ -226,7 +236,8 @@ pipc_reset_hard(void *priv) dev->pci_isa_regs[0x4a] = 0x04; dev->pci_isa_regs[0x4f] = 0x03; - dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; /* 686A/B default value does not line up with default bits */ + /* 686A/B default value does not line up with default bits */ + dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; dev->pci_isa_regs[0x59] = 0x04; if (dev->local >= VIA_PIPC_686A) dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04; @@ -332,6 +343,8 @@ pipc_reset_hard(void *priv) case VIA_PIPC_8231: dev->usb_regs[i][0x08] = 0x1e; break; + default: + break; } dev->usb_regs[i][0x0a] = 0x03; @@ -392,6 +405,9 @@ pipc_reset_hard(void *priv) case VIA_PIPC_686B: dev->power_regs[0x08] = 0x40; break; + + default: + break; } if (dev->local == VIA_PIPC_686B) dev->power_regs[0x34] = 0x68; @@ -453,6 +469,9 @@ pipc_reset_hard(void *priv) case VIA_PIPC_8231: dev->ac97_regs[i][0x08] = (i == 0) ? 0x40 : 0x20; break; + + default: + break; } if (i == 0) { @@ -547,19 +566,17 @@ pipc_ide_handlers(pipc_t *dev) static void pipc_ide_irqs(pipc_t *dev) { - int irq_mode[2] = { 0, 0 }; + int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; if (dev->ide_regs[0x09] & 0x01) - irq_mode[0] = (dev->ide_regs[0x3d] & 0x01); + irq_mode[0] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; if (dev->ide_regs[0x09] & 0x04) - irq_mode[1] = (dev->ide_regs[0x3d] & 0x01); + irq_mode[1] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); } static void @@ -730,8 +747,8 @@ pipc_codec_handlers(pipc_t *dev, uint8_t modem) static uint8_t pipc_fmnmi_read(uint16_t addr, void *priv) { - pipc_t *dev = (pipc_t *) priv; - uint8_t ret = dev->fmnmi_regs[addr & 0x03]; + const pipc_t *dev = (pipc_t *) priv; + uint8_t ret = dev->fmnmi_regs[addr & 0x03]; pipc_log("PIPC: fmnmi_read(%02X) = %02X\n", addr & 0x03, ret); @@ -766,7 +783,7 @@ pipc_fmnmi_handlers(pipc_t *dev, uint8_t modem) static uint8_t pipc_fm_read(uint16_t addr, void *priv) { - pipc_t *dev = (pipc_t *) priv; + const pipc_t *dev = (pipc_t *) priv; #ifdef VIA_PIPC_FM_EMULATION uint8_t ret = ((addr & 0x03) == 0x00) ? dev->fmnmi_status : 0x00; #else @@ -1073,7 +1090,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x47: if (val & 0x01) - trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL); + pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL); pic_set_shadow(!!(val & 0x10)); pic_elcr_io_handler(!!(val & 0x20)); dev->pci_isa_regs[0x47] = val & 0xfe; @@ -1454,7 +1471,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0xd2: if (dev->local == VIA_PIPC_686B) smbus_piix4_setclock(dev->smbus, (val & 0x04) ? 65536 : 16384); - /* fall-through */ + fallthrough; case 0x90: case 0x91: @@ -1567,36 +1584,44 @@ pipc_write(int func, int addr, uint8_t val, void *priv) } static void -pipc_reset(void *p) +pipc_reset(void *priv) { - pipc_t *dev = (pipc_t *) p; + pipc_t *dev = (pipc_t *) priv; uint8_t pm_func = dev->usb[1] ? 4 : 3; - pipc_write(pm_func, 0x41, 0x00, p); - pipc_write(pm_func, 0x48, 0x01, p); - pipc_write(pm_func, 0x49, 0x00, p); - - pipc_write(1, 0x04, 0x80, p); - pipc_write(1, 0x09, 0x85, p); - pipc_write(1, 0x10, 0xf1, p); - pipc_write(1, 0x11, 0x01, p); - pipc_write(1, 0x14, 0xf5, p); - pipc_write(1, 0x15, 0x03, p); - pipc_write(1, 0x18, 0x71, p); - pipc_write(1, 0x19, 0x01, p); - pipc_write(1, 0x1c, 0x75, p); - pipc_write(1, 0x1d, 0x03, p); - pipc_write(1, 0x20, 0x01, p); - pipc_write(1, 0x21, 0xcc, p); + pipc_write(pm_func, 0x41, 0x00, priv); + pipc_write(pm_func, 0x48, 0x01, priv); + pipc_write(pm_func, 0x49, 0x00, priv); + + 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); if (dev->local <= VIA_PIPC_586B) - pipc_write(1, 0x40, 0x04, p); + pipc_write(1, 0x40, 0x04, priv); else - pipc_write(1, 0x40, 0x00, p); + pipc_write(1, 0x40, 0x00, priv); if (dev->local < VIA_PIPC_586B) - pipc_write(0, 0x44, 0x00, p); + pipc_write(0, 0x44, 0x00, priv); + + pipc_write(0, 0x77, 0x00, priv); + + sff_set_slot(dev->bm[0], dev->pci_slot); + sff_set_slot(dev->bm[1], dev->pci_slot); - pipc_write(0, 0x77, 0x00, p); + if (dev->local >= VIA_PIPC_686A) + ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC); + if (dev->acpi) + acpi_set_slot(dev->acpi, dev->pci_slot); } static void * @@ -1608,27 +1633,23 @@ pipc_init(const device_t *info) pipc_log("PIPC: init()\n"); dev->local = info->local; - dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot); dev->bm[0] = device_add_inst(&sff8038i_device, 1); - sff_set_slot(dev->bm[0], dev->slot); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); sff_set_irq_pin(dev->bm[0], PCI_INTA); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_slot(dev->bm[1], dev->slot); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); sff_set_irq_pin(dev->bm[1], PCI_INTA); - dev->nvr = device_add(&via_nvr_device); - if (dev->local == VIA_PIPC_686B) dev->smbus = device_add(&via_smbus_device); else if (dev->local >= VIA_PIPC_596A) dev->smbus = device_add(&piix4_smbus_device); + dev->nvr = device_add(&via_nvr_device); + if (dev->local >= VIA_PIPC_596A) { dev->acpi = device_add(&acpi_via_596b_device); acpi_set_trap_update(dev->acpi, pipc_trap_update_596, dev); @@ -1642,7 +1663,6 @@ pipc_init(const device_t *info) dev->usb[1] = device_add_inst(&usb_device, 2); dev->ac97 = device_add(&ac97_via_device); - ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC); dev->sb = device_add_inst(&sb_pro_compat_device, 2); sound_add_handler(pipc_sb_get_buffer, dev); @@ -1672,7 +1692,6 @@ pipc_init(const device_t *info) dev->ddma = device_add(&ddma_device); if (dev->acpi) { - acpi_set_slot(dev->acpi, dev->slot); acpi_set_nvr(dev->acpi, dev->nvr); acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f); @@ -1682,13 +1701,13 @@ pipc_init(const device_t *info) } static void -pipc_close(void *p) +pipc_close(void *priv) { - pipc_t *dev = (pipc_t *) p; + pipc_t *dev = (pipc_t *) priv; pipc_log("PIPC: close()\n"); - for (int i = 0; i < TRAP_MAX; i++) + for (uint8_t i = 0; i < TRAP_MAX; i++) io_trap_remove(dev->io_traps[i].trap); free(dev); diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c index 3be28b155c..de55f70609 100644 --- a/src/chipset/via_vt82c49x.c +++ b/src/chipset/via_vt82c49x.c @@ -30,18 +30,20 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pic.h> +#include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct -{ - uint8_t has_ide, index, - regs[256]; +typedef struct vt82c49x_t { + uint8_t has_ide; + uint8_t index; + uint8_t regs[256]; - smram_t *smram_smm, *smram_low, - *smram_high; + smram_t *smram_smm; + smram_t *smram_low; + smram_t *smram_high; } vt82c49x_t; #ifdef ENABLE_VT82C49X_LOG @@ -65,7 +67,6 @@ vt82c49x_log(const char *fmt, ...) static void vt82c49x_recalc(vt82c49x_t *dev) { - int i; int relocate; uint8_t reg; uint8_t bit; @@ -78,7 +79,7 @@ vt82c49x_recalc(vt82c49x_t *dev) shadowbios = 0; shadowbios_write = 0; - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { base = 0xc0000 + (i << 14); reg = 0x30 + (i >> 2); bit = (i & 3) << 1; @@ -123,7 +124,7 @@ vt82c49x_recalc(vt82c49x_t *dev) mem_set_mem_state_both(base, 0x4000, state); } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { base = 0xe0000 + (i << 15); bit = 6 - (i & 2); @@ -189,6 +190,8 @@ vt82c49x_recalc(vt82c49x_t *dev) if (!shadow_bitmap) mem_remap_top(384); break; + default: + break; } } @@ -280,16 +283,22 @@ vt82c49x_write(uint16_t addr, uint8_t val, void *priv) (val & 0x40) ? "second" : "prim"); } break; + + default: + break; } break; + + default: + break; } } static uint8_t vt82c49x_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - vt82c49x_t *dev = (vt82c49x_t *) priv; + uint8_t ret = 0xff; + const vt82c49x_t *dev = (vt82c49x_t *) priv; switch (addr) { case 0xa9: @@ -303,6 +312,9 @@ vt82c49x_read(uint16_t addr, void *priv) else if (dev->index < 0x80) ret = dev->regs[dev->index]; break; + + default: + break; } return ret; diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 5d494d7c17..34efbead9c 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -26,11 +26,16 @@ #include <86box/io.h> #include <86box/pic.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/device.h> #include <86box/chipset.h> typedef struct vt82c505_t { uint8_t index; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pci_conf[256]; } vt82c505_t; @@ -116,14 +121,17 @@ vt82c505_write(int func, int addr, uint8_t val, void *priv) case 0x93: dev->pci_conf[addr] = val & 0xe0; break; + + default: + break; } } static uint8_t vt82c505_read(int func, int addr, void *priv) { - vt82c505_t *dev = (vt82c505_t *) priv; - uint8_t ret = 0xff; + const vt82c505_t *dev = (vt82c505_t *) priv; + uint8_t ret = 0xff; if (func != 0) return ret; @@ -147,8 +155,8 @@ vt82c505_out(uint16_t addr, uint8_t val, void *priv) static uint8_t vt82c505_in(uint16_t addr, void *priv) { - vt82c505_t *dev = (vt82c505_t *) priv; - uint8_t ret = 0xff; + const vt82c505_t *dev = (vt82c505_t *) priv; + uint8_t ret = 0xff; if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f)) ret = vt82c505_read(0, dev->index, priv); @@ -194,12 +202,12 @@ vt82c505_close(void *priv) } static void * -vt82c505_init(const device_t *info) +vt82c505_init(UNUSED(const device_t *info)) { vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t)); memset(dev, 0, sizeof(vt82c505_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot); dev->pci_conf[0x00] = 0x06; dev->pci_conf[0x01] = 0x11; diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 4b9df40faa..00adcc2a47 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -29,9 +29,9 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct { - uint8_t idx, - regs[256]; +typedef struct vl82c480_t { + uint8_t idx; + uint8_t regs[256]; } vl82c480_t; static int @@ -40,8 +40,8 @@ vl82c480_shflags(uint8_t access) int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY; switch (access) { - case 0x00: default: + case 0x00: ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY; break; case 0x01: @@ -81,9 +81,9 @@ vl82c480_recalc(vl82c480_t *dev) } static void -vl82c480_write(uint16_t addr, uint8_t val, void *p) +vl82c480_write(uint16_t addr, uint8_t val, void *priv) { - vl82c480_t *dev = (vl82c480_t *) p; + vl82c480_t *dev = (vl82c480_t *) priv; switch (addr) { case 0xec: @@ -121,18 +121,24 @@ vl82c480_write(uint16_t addr, uint8_t val, void *p) } break; +/* TODO: This is actually Fast A20 disable. */ +#if 0 case 0xee: if (mem_a20_alt) outb(0x92, inb(0x92) & ~2); break; +#endif + + default: + break; } } static uint8_t -vl82c480_read(uint16_t addr, void *p) +vl82c480_read(uint16_t addr, void *priv) { - vl82c480_t *dev = (vl82c480_t *) p; - uint8_t ret = 0xff; + const vl82c480_t *dev = (vl82c480_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0xec: @@ -143,24 +149,30 @@ vl82c480_read(uint16_t addr, void *p) ret = dev->regs[dev->idx]; break; +/* TODO: This is actually Fast A20 enable. */ +#if 0 case 0xee: if (!mem_a20_alt) outb(0x92, inb(0x92) | 2); break; +#endif case 0xef: softresetx86(); cpu_set_edx(); break; + + default: + break; } return ret; } static void -vl82c480_close(void *p) +vl82c480_close(void *priv) { - vl82c480_t *dev = (vl82c480_t *) p; + vl82c480_t *dev = (vl82c480_t *) priv; free(dev); } diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 41fad04185..ef076b6060 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -8,14 +8,10 @@ * * Implementation of the Western Digital WD76C10 chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Authors: Miran Grca, * + * Copyright 2024 Miran Grca. * - * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 */ #include #include @@ -37,91 +33,452 @@ #include <86box/hdc_ide.h> #include <86box/lpt.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/port_92.h> #include <86box/serial.h> +#include <86box/plat_fallthrough.h> #include <86box/chipset.h> /* Lock/Unlock Procedures */ -#define LOCK dev->lock -#define UNLOCKED !dev->lock +#define LOCK dev->locked +#define UNLOCKED !dev->locked + +#define WD76C10_ADDR_INVALID 0x80000000 #ifdef ENABLE_WD76C10_LOG int wd76c10_do_log = ENABLE_WD76C10_LOG; - static void wd76c10_log(const char *fmt, ...) { va_list ap; - if (wd76c10_do_log) { + if (wd76c10_do_log) + { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); } } #else -# define wd76c10_log(fmt, ...) +#define wd76c10_log(fmt, ...) #endif +typedef struct { + uint32_t enable; + uint32_t virt_addr, phys_addr; + uint32_t virt_size, phys_size; +} ram_bank_t; + +typedef struct { + uint8_t enabled; + + uint32_t virt, phys; + uint32_t size; +} ems_page_t; + typedef struct { - uint16_t lock_reg, oscillator_40mhz, cache_flush, ems_page_reg, - ems_page_reg_pointer, port_shadow, pmc_interrupt, - high_mem_protect_boundry, delay_line, diagnostic, - nmi_status, pmc_input, pmc_timer, - pmc_output, ems_control_low_address_boundry, shadow_ram, - split_addr, bank32staddr, bank10staddr, - non_page_mode_dram_timing, mem_control, - refresh_control, disk_chip_select, prog_chip_sel_addr, - bus_timing_power_down_ctl, clk_control; - - int lock; - - fdc_t *fdc_controller; - mem_mapping_t *mem_mapping; - serial_t *uart[2]; + uint8_t ep, p92; + + uint8_t vbios_states[4]; + uint8_t bios_states[8]; + uint8_t high_bios_states[8]; + uint8_t mem_pages[1024]; + + uint16_t toggle, cpuclk, fpu_ctl, mem_ctl, + split_sa, sh_wp, hmwpb, npmdmt, + ems_ctl, ems_pp, ser_par_cs, rtc_disk_cs, + prog_cs, pmc_in; + + union + { + uint16_t bank_base_regs[2]; + uint8_t bank_bases[4]; + }; + + uint16_t ems_page_regs[40]; + + int locked; + + uint32_t mem_top, hmwp_base; + + ram_bank_t ram_banks[5]; + + ems_page_t ems_pages[40]; + + mem_mapping_t ram_mapping; + + nvr_t *nvr; + + fdc_t *fdc; + serial_t *uart[2]; } wd76c10_t; +static uint32_t bank_sizes[4] = { 0x00020000, /* 64 Kbit X 16 = 1024 Kbit = 128 kB, 8x 8 */ + 0x00080000, /* 256 Kbit X 16 = 4096 Kbit = 512 kB, 9x 9 */ + 0x00200000, /* 1 Mbit X 16 = 16 Mbit = 2 MB, 10x10 */ + 0x00800000 }; /* 4 Mbit X 16 = 64 Mbit = 8 MB, 11x11 */ + +static uint32_t +wd76c10_calc_addr(wd76c10_t *dev, uint32_t addr) +{ + uint32_t ret; + uint8_t ems_page; + uint8_t ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + ems_page_t *ep; + uint8_t en_res = (uint8_t) ((dev->ems_ctl >> 7) & 0x01); + uint32_t low_boundary = (((uint32_t) (dev->ems_ctl & 0x007f)) << 17) + 131072; + ram_bank_t *rb = &(dev->ram_banks[4]); + + addr &= 0x00ffffff; + ems_page = dev->mem_pages[addr >> 14]; + + ep = &dev->ems_pages[ems_page]; + + ret = addr; + + /* First, do any address translation (EMS, low boundary filtering). */ + if ((ems_page < 0x20) && (ems_en == 0x03)) + /* Low EMS pages. */ + ret = addr - ep->virt + ep->phys; + else if ((ems_page >= 0x20) && (ems_page < 0x2a) && (ems_en >= 0x02) && ep->enabled) + /* High EMS pages. */ + ret = addr - ep->virt + ep->phys; + else if (en_res && (addr >= low_boundary)) + /* EMS low boundary. */ + ret = WD76C10_ADDR_INVALID; + + /* Then, do the split. */ + if (rb->enable && (ret >= rb->virt_addr) && (ret < (rb->virt_addr + rb->virt_size))) + ret = ret - rb->virt_addr + rb->phys_addr; + + /* Then, disable the required amount of on-board memory between 128k and 640k if so requested. */ + if ((ret >= dev->mem_top) && (ret < 0x000a0000)) + ret = WD76C10_ADDR_INVALID; + + /* Then, handle the physical memory banks. */ + if (ret >= (mem_size << 10)) + /* The physical memory address is too high or disabled, which is invalid. */ + ret = WD76C10_ADDR_INVALID; + /* Otherwise, map it to the correct bank so the BIOS can auto-size it correctly. */ + else for (uint8_t i = 0; i < 4; i++) { + rb = &(dev->ram_banks[i]); + if (rb->enable && (ret >= rb->virt_addr) && (ret < (rb->virt_addr + rb->virt_size))) { + if (rb->phys_size == 0x00000000) + ret = WD76C10_ADDR_INVALID; + else + ret = ((ret - rb->virt_addr) % rb->phys_size) + rb->phys_addr; + break; + } + } + + return ret; +} + +static uint8_t +wd76c10_read_ram(uint32_t addr, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + uint8_t ret = 0xff; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + ret = mem_read_ram(addr, priv); + + return ret; +} + +static uint16_t +wd76c10_read_ramw(uint32_t addr, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + uint16_t ret = 0xffff; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + ret = mem_read_ramw(addr, priv); + + return ret; +} + static void -wd76c10_refresh_control(wd76c10_t *dev) +wd76c10_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + mem_write_ram(addr, val, priv); +} + +static void +wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + + addr = wd76c10_calc_addr(dev, addr); + + if (addr != WD76C10_ADDR_INVALID) + mem_write_ramw(addr, val, priv); +} + +static void +wd76c10_banks_recalc(wd76c10_t *dev) +{ + for (uint8_t i = 0; i < 4; i++) { + ram_bank_t *rb = &(dev->ram_banks[i]); + uint8_t bit = i << 1; + rb->virt_size = bank_sizes[(dev->mem_ctl >> bit) & 0x03]; + bit = i + 12; + rb->enable = (dev->split_sa >> bit) & 0x01; + rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17; + } +} + +static void +wd76c10_split_recalc(wd76c10_t *dev) +{ + uint32_t sp_size = (dev->split_sa >> 8) & 0x03; + uint32_t split_size = ((sp_size - 1) * 65536); + ram_bank_t *rb = &(dev->ram_banks[4]); + + if (rb->enable && (rb->virt_size != 0x00000000)) + mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + rb->virt_addr = ((uint32_t) ((dev->split_sa >> 2) & 0x3f)) << 19; + switch (sp_size) { + case 0x00: + rb->virt_size = 0x00000000; + break; + default: + rb->virt_size = 256 * 1024 + split_size; + break; + } + rb->enable = !!sp_size; + if (rb->enable && (rb->virt_size != 0x00000000)) + mem_set_mem_state(rb->virt_addr, rb->virt_size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} + +static void +wd76c10_dis_mem_recalc(wd76c10_t *dev) +{ + uint8_t dis_mem = (uint8_t) ((dev->sh_wp >> 14) & 0x03); + uint32_t mem_top; + + switch (dis_mem) { + case 0x00: + default: + mem_top = 640 * 1024; + break; + case 0x01: + mem_top = 512 * 1024; + break; + case 0x02: + mem_top = 256 * 1024; + break; + case 0x03: + mem_top = 128 * 1024; + break; + } + + dev->mem_top = mem_top; +} + +static void +wd76c10_shadow_ram_do_recalc(uint8_t *new_st, uint8_t *old_st, uint8_t min, uint8_t max, uint32_t addr) +{ + uint32_t base = 0x00000000; + int flags = 0; + + for (uint8_t i = min; i < max; i++) { + if (new_st[i] != old_st[i]) { + old_st[i] = new_st[i]; + base = addr + ((uint32_t) i) * 0x00004000; + flags = (new_st[i] & 0x01) ? MEM_READ_INTERNAL : + ((new_st[i] & 0x04) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL); + flags |= (new_st[i] & 0x02) ? MEM_WRITE_INTERNAL : + ((new_st[i] & 0x04) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL); + mem_set_mem_state_both(base, 0x00004000, flags); + } + } +} + + +static void +wd76c10_shadow_ram_recalc(wd76c10_t *dev) +{ + uint8_t vbios_states[4] = { 0 }; + uint8_t bios_states[8] = { 0 }; + uint8_t high_bios_states[8] = { 0 }; + uint8_t wp = (uint8_t) ((dev->sh_wp >> 12) & 0x01); + uint8_t shd = (uint8_t) ((dev->sh_wp >> 8) & 0x03); + uint8_t x_mem = (uint8_t) ((dev->sh_wp >> 7) & 0x01); + uint8_t vb_siz = (uint8_t) ((dev->sh_wp >> 4) & 0x03); + uint8_t vb_top = vb_siz + 1; + uint8_t rom_typ = (uint8_t) ((dev->sh_wp >> 2) & 0x03); + + switch (shd) { + case 0x03: + for (uint8_t i = 0; i < vb_top; i++) { + vbios_states[i] |= 0x01; /* Read. */ + if (!wp) + vbios_states[i] |= 0x02; /* Write. */ + } + if (x_mem) { + for (uint8_t i = 2; i < 4; i++) + bios_states[i] |= 0x03; /* Read/write. */ + } + fallthrough; + case 0x01: + for (uint8_t i = 4; i < 8; i++) { + bios_states[i] |= 0x01; /* Read. */ + if (!wp) + bios_states[i] |= 0x02; /* Write. */ + } + break; + case 0x02: + for (uint8_t i = 0; i < 8; i++) { + bios_states[i] |= 0x01; /* Read. */ + if (!wp) + bios_states[i] |= 0x02; /* Write. */ + } + break; + } + + switch (rom_typ) { + case 0x00: + for (uint8_t i = 0; i < 8; i++) { + bios_states[i] |= 0x04; /* CSPROM#. */ + high_bios_states[i] |= 0x04; /* CSPROM#. */ + } + break; + case 0x02: + for (uint8_t i = 0; i < vb_top; i++) + vbios_states[i] |= 0x04; /* CSPROM#. */ + fallthrough; + case 0x01: + for (uint8_t i = 4; i < 8; i++) { + bios_states[i] |= 0x04; /* CSPROM#. */ + high_bios_states[i] |= 0x04; /* CSPROM#. */ + } + break; + } + + wd76c10_shadow_ram_do_recalc(vbios_states, dev->vbios_states, 0, 4, 0x000c0000); + wd76c10_shadow_ram_do_recalc(bios_states, dev->bios_states, 0, 8, 0x000e0000); + + /* This is not shadowed, but there is a CSPROM# (= ROMCS#) toggle. */ + wd76c10_shadow_ram_do_recalc(high_bios_states, dev->high_bios_states, 0, 8, 0x00fe0000); + + flushmmucache_nopc(); +} + +static void +wd76c10_high_mem_wp_recalc(wd76c10_t *dev) +{ + uint8_t hm_wp = (uint8_t) ((dev->sh_wp >> 13) & 0x01); + uint32_t base = ((uint32_t) (dev->hmwpb & 0x00f0)) << 17; + uint32_t size = 0x01000000 - dev->hmwp_base; + + /* ACCESS_NORMAL means both ACCESS_BUS and ACCESS_CPU are set. */ + mem_set_wp(dev->hmwp_base, size, ACCESS_NORMAL, 0); + + size = 0x01000000 - base; + mem_set_wp(base, size, ACCESS_NORMAL, hm_wp); + + dev->hmwp_base = base; +} + +static void +wd76c10_pf_loc_reset(wd76c10_t *dev) +{ + uint32_t base; + + for (uint8_t i = 0x031; i <= 0x03b; i++) { + dev->mem_pages[i] = 0xff; + base = ((uint32_t) i) << 14; + mem_set_mem_state(base, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } + + /* Re-apply any ROMCS#, etc. flags. */ + wd76c10_shadow_ram_recalc(dev); +} + +static void +wd76c10_pf_loc_recalc(wd76c10_t *dev) +{ + uint8_t pf_loc = (uint8_t) ((dev->ems_ctl >> 13) & 0x03); + uint8_t ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + uint8_t ems_page; + uint32_t base; + + for (uint8_t i = (0x031 + pf_loc); i <= (0x037 + pf_loc); i++) { + ems_page = (i - 0x10) & 0xf7; + dev->mem_pages[i] = ems_page; + base = ((uint32_t) i) << 14; + dev->ems_pages[ems_page].virt = base; + if ((ems_en >= 0x02) && dev->ems_pages[ems_page].enabled) + mem_set_mem_state(dev->ems_pages[ems_page].virt, 0x00004000, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } +} + +static void +wd76c10_low_pages_recalc(wd76c10_t *dev) +{ + uint8_t ems_page; + uint32_t base; + + for (uint8_t i = 0x008; i <= 0x027; i++) { + ems_page = i & 0x1f; + dev->mem_pages[i] = ems_page; + base = ((uint32_t) i) << 14; + dev->ems_pages[ems_page].virt = base; + } +} + +static void +wd76c10_ser_par_cs_recalc(wd76c10_t *dev) { - serial_remove(dev->uart[1]); /* Serial B */ - switch ((dev->refresh_control >> 1) & 7) { - case 1: + serial_remove(dev->uart[1]); + switch ((dev->ser_par_cs >> 1) & 0x07) { + case 0x01: serial_setup(dev->uart[1], 0x3f8, 3); break; - case 2: + case 0x02: serial_setup(dev->uart[1], 0x2f8, 3); break; - case 3: + case 0x03: serial_setup(dev->uart[1], 0x3e8, 3); break; - case 4: + case 0x04: serial_setup(dev->uart[1], 0x2e8, 3); break; } - serial_remove(dev->uart[0]); /* Serial A */ - switch ((dev->refresh_control >> 5) & 7) { - case 1: + serial_remove(dev->uart[0]); + switch ((dev->ser_par_cs >> 5) & 0x07) { + case 0x01: serial_setup(dev->uart[0], 0x3f8, 4); break; - case 2: + case 0x02: serial_setup(dev->uart[0], 0x2f8, 4); break; - case 3: + case 0x03: serial_setup(dev->uart[0], 0x3e8, 4); break; - case 4: + case 0x04: serial_setup(dev->uart[0], 0x2e8, 4); break; } - lpt1_remove(); /* LPT */ - switch ((dev->refresh_control >> 9) & 3) { + lpt1_remove(); + switch ((dev->ser_par_cs >> 9) & 0x03) { case 1: lpt1_init(0x3bc); lpt1_irq(7); @@ -138,393 +495,459 @@ wd76c10_refresh_control(wd76c10_t *dev) } static void -wd76c10_split_addr(wd76c10_t *dev) +wd76c10_disk_cs_recalc(wd76c10_t *dev) { - switch ((dev->split_addr >> 8) & 3) { - case 1: - if (((dev->shadow_ram >> 8) & 3) == 2) - mem_remap_top(256); - break; - case 2: - if (((dev->shadow_ram >> 8) & 3) == 1) - mem_remap_top(320); - break; - case 3: - if (((dev->shadow_ram >> 8) & 3) == 3) - mem_remap_top(384); - break; - } + ide_pri_disable(); + ide_set_base(0, (dev->rtc_disk_cs & 0x0010) ? 0x0170 : 0x01f0); + ide_set_side(0, (dev->rtc_disk_cs & 0x0010) ? 0x0376 : 0x03f6); + if (!(dev->rtc_disk_cs & 0x0002)) + ide_pri_enable(); + + fdc_remove(dev->fdc); + if (!(dev->rtc_disk_cs & 0x0001)) + fdc_set_base(dev->fdc, (dev->rtc_disk_cs & 0x0010) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } static void -wd76c10_disk_chip_select(wd76c10_t *dev) +wd76c10_outb(uint16_t port, uint8_t val, void *priv) { - ide_pri_disable(); - if (!(dev->disk_chip_select & 1)) { - ide_set_base(0, !(dev->disk_chip_select & 0x0010) ? 0x1f0 : 0x170); - ide_set_side(0, !(dev->disk_chip_select & 0x0010) ? 0x3f6 : 0x376); - } - ide_pri_enable(); + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t lk_psw = (uint8_t) ((dev->rtc_disk_cs >> 2) & 0x01); + uint8_t valxor; - fdc_remove(dev->fdc_controller); - if (!(dev->disk_chip_select & 2)) - fdc_set_base(dev->fdc_controller, !(dev->disk_chip_select & 0x0010) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); -} + switch (port) { + case 0x0092: + if ((lk_psw && (val & 0x08)) || ((dev->p92 & 0x08) && !(val & 0x08))) + val = (val & 0xf7) | (dev->p92 & 0x08); -static void -wd76c10_shadow_recalc(wd76c10_t *dev) -{ - switch ((dev->shadow_ram >> 14) & 3) { - case 0: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 1: - mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - case 2: - mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - case 3: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED); - break; - } + valxor = (dev->p92 ^ val) & 0x08; + dev->p92 = (val & 0x08) | 0xf7; - switch ((dev->shadow_ram >> 8) & 3) { - case 0: - mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); - break; - case 2: - mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); - break; - case 3: - mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)); + if (valxor) + nvr_lock_set(0x38, 0x08, (val & 0x08) ? 0x03 : 0x00, dev->nvr); break; } } static void -wd76c10_write(uint16_t addr, uint16_t val, void *priv) +wd76c10_outw(uint16_t port, uint16_t val, void *priv) { - wd76c10_t *dev = (wd76c10_t *) priv; - - if (UNLOCKED) { - switch (addr) { - case 0x1072: - dev->clk_control = val; - break; + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t inc = (uint8_t) ((dev->ems_ctl >> 15) & 0x01); + uint8_t ems_en; - case 0x1872: - dev->bus_timing_power_down_ctl = val; - break; - - case 0x2072: - dev->refresh_control = val; - wd76c10_refresh_control(dev); - break; - - case 0x2872: - dev->disk_chip_select = val; - wd76c10_disk_chip_select(dev); - break; - - case 0x3072: - dev->prog_chip_sel_addr = val; - break; - - case 0x3872: - dev->non_page_mode_dram_timing = val; - break; - - case 0x4072: - dev->mem_control = val; - break; - - case 0x4872: - dev->bank10staddr = val; - break; - - case 0x5072: - dev->bank32staddr = val; - break; - - case 0x5872: - dev->split_addr = val; - wd76c10_split_addr(dev); - break; + if (!dev->locked || (port < 0x1072) || (port > 0xf872) || + (port == 0xe072) || (port == 0xe872) || (port == 0xf073)) switch (port) { + case 0x1072: + dev->cpuclk = val; + break; - case 0x6072: - dev->shadow_ram = val & 0xffbf; - wd76c10_shadow_recalc(dev); - break; + case 0x1872: + dev->fpu_ctl = val; + break; - case 0x6872: - dev->ems_control_low_address_boundry = val & 0xecff; - break; + case 0x2072: + dev->ser_par_cs = val; + wd76c10_ser_par_cs_recalc(dev); + break; - case 0x7072: - dev->pmc_output = (val >> 8) & 0x00ff; - break; + case 0x2872: + dev->rtc_disk_cs = val; + wd76c10_disk_cs_recalc(dev); + break; - case 0x7872: - dev->pmc_output = val & 0xff00; - break; + case 0x3072: + dev->prog_cs = val; + break; - case 0x8072: - dev->pmc_timer = val; - break; + /* TODO: Log this to determine how the BIOS does bank sizing. */ + case 0x3872: + dev->mem_ctl = val; + wd76c10_banks_recalc(dev); + break; - case 0x8872: - dev->pmc_input = val; - break; + case 0x4072: + dev->npmdmt = val; + break; - case 0x9072: - dev->nmi_status = val & 0x00fc; - break; + /* A17-A24 */ + case 0x4872: + dev->bank_base_regs[0] = val; + wd76c10_banks_recalc(dev); + break; - case 0x9872: - dev->diagnostic = val & 0xfdff; - break; + /* A17-A24 */ + case 0x5072: + dev->bank_base_regs[1] = val; + wd76c10_banks_recalc(dev); + break; - case 0xa072: - dev->delay_line = val; - break; + case 0x5872: + dev->split_sa = val; + wd76c10_banks_recalc(dev); + wd76c10_split_recalc(dev); + break; - case 0xc872: - dev->pmc_interrupt = val & 0xfcfc; - break; + case 0x6072: + dev->sh_wp = val; + wd76c10_dis_mem_recalc(dev); + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + wd76c10_high_mem_wp_recalc(dev); + break; - case 0xf072: - dev->oscillator_40mhz = 0; - break; + case 0x6872: + dev->ems_ctl = val; + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + break; - case 0xf472: - dev->oscillator_40mhz = 1; - break; + case 0x8872: + dev->pmc_in = val; + break; - case 0xf872: - dev->cache_flush = val; - flushmmucache(); - break; - } - wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val); - } + case 0xc072: + dev->hmwpb = val; + wd76c10_high_mem_wp_recalc(dev); + break; - switch (addr) { case 0xe072: - dev->ems_page_reg_pointer = val & 0x003f; + dev->ems_pp = val; + dev->ep = (val & 0x3f) % 40; break; case 0xe872: - dev->ems_page_reg = val & 0x8fff; + ems_en = (uint8_t) ((dev->ems_ctl >> 10) & 0x03); + if (ems_en) { + dev->ems_page_regs[dev->ep] = val; + dev->ems_pages[dev->ep].phys = ((uint32_t) (val & 0x0fff)) << 14; + if (dev->ep >= 32) { + dev->ems_pages[dev->ep].enabled = !!(val & 0x8000); + if (ems_en >= 0x02) { + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + } + } else { + dev->ems_pages[dev->ep].enabled = (ems_en == 0x03); + if (ems_en == 0x03) + wd76c10_low_pages_recalc(dev); + } + } + if (inc) + dev->ep = (dev->ep + 1) % 40; break; case 0xf073: - dev->lock_reg = val & 0x00ff; - LOCK = !(val & 0x00da); + dev->locked = ((val & 0x00ff) != 0x00da); + break; + + case 0xf872: + flushmmucache(); break; } } +static uint8_t +wd76c10_inb(uint16_t port, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t ret = 0xff; + + switch (port) { + case 0x0092: + ret = (dev->p92 & 0x08) | 0xf7; + break; + } + + return ret; +} + static uint16_t -wd76c10_read(uint16_t addr, void *priv) +wd76c10_inw(uint16_t port, void *priv) { - wd76c10_t *dev = (wd76c10_t *) priv; - wd76c10_log("WD76C10: R dev->regs[%04x]\n", addr); - switch (addr) { + wd76c10_t *dev = (wd76c10_t *)priv; + uint8_t inc = (uint8_t) ((dev->ems_ctl >> 15) & 0x01); + uint16_t ret = 0xffff; + + wd76c10_log("WD76C10: R dev->regs[%04x]\n", port); + + if (!dev->locked || (port < 0x1072) || (port > 0xf872) || + (port == 0xe072) || (port == 0xe872) || (port == 0xf073)) switch (port) { case 0x1072: - return dev->clk_control; + ret = dev->cpuclk; + break; case 0x1872: - return dev->bus_timing_power_down_ctl; + ret = dev->fpu_ctl; + break; case 0x2072: - return dev->refresh_control; + ret = dev->ser_par_cs; + break; case 0x2872: - return dev->disk_chip_select; + ret = dev->rtc_disk_cs; + break; case 0x3072: - return dev->prog_chip_sel_addr; + ret = dev->prog_cs; + break; case 0x3872: - return dev->non_page_mode_dram_timing; + ret = dev->mem_ctl; + break; case 0x4072: - return dev->mem_control; + ret = dev->npmdmt; + break; case 0x4872: - return dev->bank10staddr; + ret = dev->bank_base_regs[0]; + break; case 0x5072: - return dev->bank32staddr; + ret = dev->bank_base_regs[1]; + break; case 0x5872: - return dev->split_addr; + ret = dev->split_sa; + break; case 0x6072: - return dev->shadow_ram; + ret = dev->sh_wp; + break; case 0x6872: - return dev->ems_control_low_address_boundry; - - case 0x7072: - return (dev->pmc_output << 8) & 0xff00; - - case 0x7872: - return (dev->pmc_output) & 0xff00; - - case 0x8072: - return dev->pmc_timer; + ret = dev->ems_ctl; + break; case 0x8872: - return dev->pmc_input; - - case 0x9072: - return dev->nmi_status; - - case 0x9872: - return dev->diagnostic; - - case 0xa072: - return dev->delay_line; + ret = dev->pmc_in; + break; case 0xb872: - return (inb(0x040b) << 8) | inb(0x04d6); + ret = dma[0].mode; + ret |= (((uint16_t) dma[1].mode) << 8); + break; - case 0xc872: - return dev->pmc_interrupt; + case 0xc072: + ret = dev->hmwpb; + break; case 0xd072: - return dev->port_shadow; + ret = (serial_read(0x0002, dev->uart[0]) & 0xc0) << 8; + ret |= (serial_read(0x0002, dev->uart[1]) & 0xc0) << 6; + ret |= (lpt_read_port(0, 0x0002) & 0x0f) << 8; + ret |= lpt_read_port(0, 0x0000); + break; case 0xe072: - return dev->ems_page_reg_pointer; + ret = (dev->ems_pp & 0xffc0) | dev->ep; + break; case 0xe872: - return dev->ems_page_reg; + ret = dev->ems_page_regs[dev->ep]; + if (inc) + dev->ep = (dev->ep + 1) % 40; + break; case 0xfc72: - return 0x0ff0; - - default: - return 0xffff; + ret = ((lpt_read_status(0) & 0x20) >> 2); + ret |= (((uint16_t) dma_m) << 4); + ret |= dev->toggle; + dev->toggle ^= 0x8000; + break; } + + return ret; } static void wd76c10_close(void *priv) { - wd76c10_t *dev = (wd76c10_t *) priv; + wd76c10_t *dev = (wd76c10_t *)priv; free(dev); } + +static void +wd76c10_reset(void *priv) +{ + wd76c10_t *dev = (wd76c10_t *)priv; + + dev->locked = 1; + dev->toggle = 0; + + dev->p92 = 0xf7; + + dev->cpuclk = 0x1000; + dev->fpu_ctl = 0x00ca; + dev->mem_ctl = 0x0000; + dev->bank_base_regs[0] = 0x0000; + dev->bank_base_regs[1] = 0x0000; + dev->split_sa = 0x0000; + dev->sh_wp = 0x0000; + dev->hmwpb = 0x0000; + dev->npmdmt = 0x0000; + dev->ems_ctl = 0x0000; + dev->ems_pp = 0x0000; + dev->ser_par_cs = 0x0000; + dev->rtc_disk_cs = 0x0000; + + for (uint8_t i = 0; i < 40; i++) { + dev->ems_page_regs[i] = 0x0000; + dev->ems_pages[i].enabled = 0; + dev->ems_pages[i].phys = 0x00000000; + } + + nvr_lock_set(0x38, 0x08, 0x00, dev->nvr); + + wd76c10_banks_recalc(dev); + wd76c10_split_recalc(dev); + wd76c10_dis_mem_recalc(dev); + wd76c10_high_mem_wp_recalc(dev); + wd76c10_pf_loc_reset(dev); + wd76c10_pf_loc_recalc(dev); + wd76c10_low_pages_recalc(dev); + wd76c10_ser_par_cs_recalc(dev); + wd76c10_disk_cs_recalc(dev); +} + + static void * wd76c10_init(const device_t *info) { - wd76c10_t *dev = (wd76c10_t *) malloc(sizeof(wd76c10_t)); - memset(dev, 0, sizeof(wd76c10_t)); + wd76c10_t *dev = (wd76c10_t *) calloc(1, sizeof(wd76c10_t)); + uint32_t total_mem = mem_size << 10; + uint32_t accum_mem = 0x00000000; + ram_bank_t *rb; + + /* Calculate the physical RAM banks. */ + for (uint8_t i = 0; i < 4; i++) { + rb = &(dev->ram_banks[i]); + uint32_t size = 0x00000000; + for (int8_t j = 3; j >= 0; j--) { + uint32_t *bs = &(bank_sizes[j]); + if (*bs <= total_mem) { + size = *bs; + break; + } + } + if (size != 0x00000000) { + rb->phys_addr = accum_mem; + rb->phys_size = size; + total_mem -= size; + accum_mem += size; + } + } + + rb = &(dev->ram_banks[4]); + rb->phys_addr = 0x000a0000; + rb->phys_size = 0x00060000; + + memset(dev->mem_pages, 0xff, sizeof(dev->mem_pages)); + for (uint8_t i = 0x008; i < 0x01f; i++) + dev->mem_pages[i] = i; + for (uint8_t i = 0x020; i < 0x027; i++) + dev->mem_pages[i] = i - 0x20; device_add(&port_92_inv_device); - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); - dev->fdc_controller = device_add(&fdc_at_device); + dev->nvr = device_add(&amstrad_megapc_nvr_device); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->fdc = device_add(&fdc_at_device); device_add(&ide_isa_device); - /* Lock Configuration */ - LOCK = 1; + wd76c10_reset(dev); + + /* Password Lock */ + io_sethandler(0x0092, 1, wd76c10_inb, NULL, NULL, wd76c10_outb, NULL, NULL, dev); /* Clock Control */ - io_sethandler(0x1072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x1072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Bus Timing & Power Down Control */ - io_sethandler(0x1872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* FPU Bus Timing & Power Down Control */ + io_sethandler(0x1872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Refresh Control(Serial & Parallel) */ - io_sethandler(0x2072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* Refresh Control, Serial and Parallel Chip Selects */ + io_sethandler(0x2072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Disk Chip Select */ - io_sethandler(0x2872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* RTC, PVGA, 80287 Timing, and Disk Chip Selects */ + io_sethandler(0x2872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Programmable Chip Select Address(Needs more further examination!) */ - io_sethandler(0x3072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* Programmable Chip Select Address */ + io_sethandler(0x3072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); + + /* Memory Control */ + io_sethandler(0x3872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); + + /* Non-page Mode DRAM Memory Timing */ + io_sethandler(0x4072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Bank 1 & 0 Start Address */ - io_sethandler(0x4872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x4872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Bank 3 & 2 Start Address */ - io_sethandler(0x5072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x5072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Split Address */ - io_sethandler(0x5872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* EMS Control & EMS Low level boundry */ - io_sethandler(0x6072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* EMS Control & EMS Low level boundry */ - io_sethandler(0x6872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0x5872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Output */ - io_sethandler(0x7072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* RAM Shadow And Write Protect */ + io_sethandler(0x6072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Output */ - io_sethandler(0x7872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* EMS Control And Lower EMS Boundary */ + io_sethandler(0x6872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Status */ - io_sethandler(0x8072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* PMC Inputs */ + io_sethandler(0x8872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* PMC Status */ - io_sethandler(0x8872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* DMA Mode Shadow Register */ + io_sethandler(0xb872, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); - /* NMI Status (Needs further checkup) */ - io_sethandler(0x9072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + /* High Memory Write Protect Boundry */ + io_sethandler(0xc072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); - /* Diagnostics */ - io_sethandler(0x9872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* Delay Line */ - io_sethandler(0xa072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); - - /* DMA Mode Shadow(Needs Involvement on the DMA code) */ - io_sethandler(0xb872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* High Memory Protection Boundry */ - io_sethandler(0xc072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* PMC Interrupt Enable */ - io_sethandler(0xc872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* Port Shadow (Needs further lookup) */ - io_sethandler(0xd072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + /* Shadow Register */ + io_sethandler(0xd072, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); /* EMS Page Register Pointer */ - io_sethandler(0xe072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xe072, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* EMS Page Register */ - io_sethandler(0xe872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xe872, 1, NULL, wd76c10_inw, NULL, NULL, wd76c10_outw, NULL, dev); /* Lock/Unlock Configuration */ - io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); + io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_outw, NULL, dev); - /* 40Mhz Oscillator Enable Disable */ - io_sethandler(0xf072, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); - io_sethandler(0xf472, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev); + /* Cache Flush */ + io_sethandler(0xf872, 1, NULL, NULL, NULL, NULL, wd76c10_outw, NULL, dev); /* Lock Status */ - io_sethandler(0xfc72, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); - - /* Cache Flush */ - io_sethandler(0xf872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev); + io_sethandler(0xfc72, 1, NULL, wd76c10_inw, NULL, NULL, NULL, NULL, dev); dma_ext_mode_init(); - wd76c10_shadow_recalc(dev); - wd76c10_refresh_control(dev); - wd76c10_disk_chip_select(dev); + mem_mapping_add(&dev->ram_mapping, + 0x00000000, + (mem_size + 384) << 10, + wd76c10_read_ram, + wd76c10_read_ramw, + NULL, + wd76c10_write_ram, + wd76c10_write_ramw, + NULL, + ram, + MEM_MAPPING_INTERNAL, + dev); + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + mem_mapping_enable(&dev->ram_mapping); + return dev; } diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index f2d6780675..79b26015c9 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -33,6 +33,8 @@ int codegen_in_recompile; void codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ +#if 0 + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); } diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index ddcf5095ff..6d30211a69 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -74,19 +74,25 @@ */ typedef struct codeblock_t { - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; + uint64_t page_mask; + uint64_t page_mask2; + uint64_t *dirty_mask; + uint64_t *dirty_mask2; uint64_t cmp; /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ - struct codeblock_t *prev, *next; - struct codeblock_t *prev_2, *next_2; + struct codeblock_t *prev; + struct codeblock_t *next; + struct codeblock_t *prev_2; + struct codeblock_t *next_2; /*Pointers for codeblock tree, used to search for blocks when hash lookup fails.*/ - struct codeblock_t *parent, *left, *right; + struct codeblock_t *parent; + struct codeblock_t *left; + struct codeblock_t *right; int pnt; int ins; diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index 46a49f1180..a81eef67e1 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -5,10 +5,13 @@ #include <86box/86box.h> #include <86box/mem.h> +#include <86box/plat_unused.h> #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "386_common.h" #include "cpu.h" @@ -128,6 +131,54 @@ RecompOpFn recomp_opcodes_0f[512] = { // clang-format on }; +RecompOpFn recomp_opcodes_0f_no_mmx[512] = { + // clang-format off + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on +}; + RecompOpFn recomp_opcodes_d8[512] = { // clang-format off /*16-bit data*/ diff --git a/src/codegen/codegen_ops.h b/src/codegen/codegen_ops.h index f92ba4f6db..5c19fb666d 100644 --- a/src/codegen/codegen_ops.h +++ b/src/codegen/codegen_ops.h @@ -7,6 +7,7 @@ typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; +extern RecompOpFn recomp_opcodes_0f_no_mmx[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index e6561208e1..28ee6d06ca 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -8,7 +8,9 @@ ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM_W(host_reg, 1); +#if 0 + ADD_HOST_REG_IMM_W(host_reg, 1); +#endif INC_HOST_REG_W(host_reg); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16); @@ -29,7 +31,9 @@ ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM(host_reg, 1); +#if 0 + ADD_HOST_REG_IMM(host_reg, 1); +#endif INC_HOST_REG(host_reg); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32); @@ -50,7 +54,9 @@ ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM_W(host_reg, 1); +#if 0 + SUB_HOST_REG_IMM_W(host_reg, 1); +#endif DEC_HOST_REG_W(host_reg); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16); @@ -71,7 +77,9 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM(host_reg, 1); +#if 0 + SUB_HOST_REG_IMM(host_reg, 1); +#endif DEC_HOST_REG(host_reg); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32); @@ -83,194 +91,206 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } -#define ROP_ARITH_RMW(name, op, writeback) \ - static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ +#define ROP_ARITH_RMW(name, op, writeback) \ + static uint32_t \ + rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ } -#define ROP_ARITH_RM(name, op, writeback) \ - static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ - op##_HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ +#define ROP_ARITH_RM(name, op, writeback) \ + static uint32_t \ + rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ } ROP_ARITH_RMW(ADD, ADD, 1) diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 323a255420..1021cc7426 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -194,23 +194,24 @@ ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return new_pc; } -#define ropFarith(name, size, load, op) \ - static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_##name); \ - \ - return op_pc + 1; \ +#define ropFarith(name, size, load, op) \ + static uint32_t \ + ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(FPU_##name); \ + \ + return op_pc + 1; \ } ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); @@ -239,7 +240,8 @@ ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); #define ropFcompare(name, size, load, op) \ - static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + static uint32_t \ + ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ x86seg *target_seg; \ \ @@ -270,74 +272,80 @@ ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW); ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL); -/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +#if 0 +static uint32_t +ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_OP_S(FPU_ADD); + FP_OP_S(FPU_ADD); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_OP_S(FPU_DIV); + FP_OP_S(FPU_DIV); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_OP_S(FPU_MUL); + FP_OP_S(FPU_MUL); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_OP_S(FPU_SUB); + FP_OP_S(FPU_SUB); - return op_pc + 1; -}*/ + return op_pc + 1; +} +#endif static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) @@ -658,15 +666,16 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } -#define opFLDimm(name, v) \ - static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - static double fp_imm = v; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ - \ - return op_pc; \ +#define opFLDimm(name, v) \ + static uint32_t \ + ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + static double fp_imm = v; \ + \ + FP_ENTER(); \ + FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ + \ + return op_pc; \ } // clang-format off @@ -678,7 +687,8 @@ opFLDimm(EG2, 0.3010299956639812); opFLDimm(Z, 0.0) // clang-format on -static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDLN2(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ULL); diff --git a/src/codegen/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h index f5c66dd1ba..da16ce03e2 100644 --- a/src/codegen/codegen_ops_jump.h +++ b/src/codegen/codegen_ops_jump.h @@ -214,42 +214,45 @@ BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) } } -#define ropBRANCH(name, func, not ) \ - static uint32_t rop##name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ - { \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not ); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ - { \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not ); \ - \ - return op_pc + 2; \ - } \ - static uint32_t rop##name##_l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ - { \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not ); \ - \ - return op_pc + 4; \ +#define ropBRANCH(name, func, not ) \ + static uint32_t \ + rop##name(uint8_t opcode, uint32_t fetchdat, \ + uint32_t op_32, uint32_t op_pc, \ + codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xff; \ + \ + if (offset & 0x80) \ + offset |= 0xffffff00; \ + \ + func(1, op_pc, offset, not ); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xffff; \ + \ + if (offset & 0x8000) \ + offset |= 0xffff0000; \ + \ + func(2, op_pc, offset, not ); \ + \ + return op_pc + 2; \ + } \ + static uint32_t \ + rop##name##_l(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + \ + func(4, op_pc, offset, not ); \ + \ + return op_pc + 4; \ } // clang-format off diff --git a/src/codegen/codegen_ops_logic.h b/src/codegen/codegen_ops_logic.h index d0216644c6..9f23723e26 100644 --- a/src/codegen/codegen_ops_logic.h +++ b/src/codegen/codegen_ops_logic.h @@ -1,171 +1,183 @@ -#define ROP_LOGIC(name, op, writeback) \ - static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - op##_HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - op##_HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } else { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - op##_HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ - op##_HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ - op##_HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ - op##_HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ - if (writeback) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ +#define ROP_LOGIC(name, op, writeback) \ + static uint32_t \ + rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg; \ + int dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ } ROP_LOGIC(AND, AND, 1) diff --git a/src/codegen/codegen_ops_mmx.h b/src/codegen/codegen_ops_mmx.h index e667bc40e8..4c5a92c8f1 100644 --- a/src/codegen/codegen_ops_mmx.h +++ b/src/codegen/codegen_ops_mmx.h @@ -95,33 +95,36 @@ ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } -#define MMX_OP(name, func) \ - static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg1, src_reg2; \ - int xmm_src, xmm_dst; \ - \ - MMX_ENTER(); \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ - } \ - xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ - STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ - \ - return op_pc + 1; \ +#define MMX_OP(name, func) \ + static uint32_t \ + name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg1; \ + int src_reg2; \ + int xmm_src; \ + int xmm_dst; \ + \ + MMX_ENTER(); \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + \ + MEM_LOAD_ADDR_EA_Q(target_seg); \ + src_reg1 = LOAD_Q_REG_1; \ + src_reg2 = LOAD_Q_REG_2; \ + xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ + } \ + xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ + func(xmm_dst, xmm_src); \ + STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ + \ + return op_pc + 1; \ } MMX_OP(ropPAND, MMX_AND) diff --git a/src/codegen/codegen_ops_stack.h b/src/codegen/codegen_ops_stack.h index 265369771a..342ddedd4d 100644 --- a/src/codegen/codegen_ops_stack.h +++ b/src/codegen/codegen_ops_stack.h @@ -224,30 +224,32 @@ ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc; } -#define ROP_PUSH_SEG(seg) \ - static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-2); \ - host_reg = LOAD_VAR_W((uintptr_t) &seg); \ - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ - } \ - static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-4); \ - host_reg = LOAD_VAR_W((uintptr_t) &seg); \ - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ +#define ROP_PUSH_SEG(seg) \ + static uint32_t \ + ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-2); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-2); \ + \ + return op_pc; \ + } \ + static uint32_t \ + ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-4); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-4); \ + \ + return op_pc; \ } ROP_PUSH_SEG(CS) @@ -257,26 +259,28 @@ ROP_PUSH_SEG(FS) ROP_PUSH_SEG(GS) ROP_PUSH_SEG(SS) -#define ROP_POP_SEG(seg, rseg) \ - static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ - } \ - static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ +#define ROP_POP_SEG(seg, rseg) \ + static uint32_t \ + ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(2); \ + \ + return op_pc; \ + } \ + static uint32_t \ + ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(4); \ + \ + return op_pc; \ } ROP_POP_SEG(DS, cpu_state.seg_ds) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 18480a6b56..bc6293c0bf 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -219,8 +219,9 @@ CALL_FUNC(uintptr_t func) } static __inline void -RELEASE_REG(int host_reg) +RELEASE_REG(UNUSED(int host_reg)) { + // } static __inline int @@ -536,7 +537,7 @@ FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) addlong((fetchdat >> 8) & 0xffff); (*op_pc) += 2; } else { - int base_reg = 0; + int base_reg = 0; int index_reg = 0; switch (rm) { @@ -3949,7 +3950,8 @@ FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) static __inline int64_t x87_fround16_64(double b) { - int16_t a, c; + int16_t a; + int16_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -3974,7 +3976,8 @@ x87_fround16_64(double b) static __inline int64_t x87_fround32_64(double b) { - int32_t a, c; + int32_t a; + int32_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -3999,7 +4002,8 @@ x87_fround32_64(double b) static __inline int64_t x87_fround(double b) { - int64_t a, c; + int64_t a; + int64_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -4550,8 +4554,9 @@ FP_COMPARE_IL(void) } static __inline void -UPDATE_NPXC(int reg) +UPDATE_NPXC(UNUSED(int reg)) { + // } static __inline void @@ -4775,13 +4780,14 @@ STORE_MMX_Q_MMX(int guest_reg, int host_reg) addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ - static __inline void MMX_##name(int dst_reg, int src_reg) \ - { \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ +#define MMX_x86_OP(name, opcode) \ + static __inline void \ + MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ } MMX_x86_OP(AND, 0xdb) @@ -5014,7 +5020,9 @@ LOAD_EA(void) static __inline void MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3 = NULL; + uint8_t *jump1 = NULL; + uint8_t *jump2 = NULL; + uint8_t *jump3 = NULL; CHECK_SEG_WRITE(seg); @@ -5115,7 +5123,10 @@ MEM_CHECK_WRITE(x86seg *seg) static __inline void MEM_CHECK_WRITE_W(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + uint8_t *jump1 = NULL; + uint8_t *jump2 = NULL; + uint8_t *jump3 = NULL; + uint8_t *jump4 = NULL; int jump_pos; CHECK_SEG_WRITE(seg); @@ -5248,7 +5259,10 @@ MEM_CHECK_WRITE_W(x86seg *seg) static __inline void MEM_CHECK_WRITE_L(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + uint8_t *jump1 = NULL; + uint8_t *jump2 = NULL; + uint8_t *jump3 = NULL; + uint8_t *jump4 = NULL; int jump_pos; CHECK_SEG_WRITE(seg); diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 80e0812207..410ce8e17a 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -3619,37 +3619,39 @@ STORE_MMX_Q_MMX(int guest_reg, int host_reg) addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ - static __inline void MMX_##name(int dst_reg, int src_reg) \ - { \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ +#define MMX_x86_OP(name, opcode) \ + static \ + __inline void MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ } +// clang-format off MMX_x86_OP(AND, 0xdb) - MMX_x86_OP(ANDN, 0xdf) - MMX_x86_OP(OR, 0xeb) - MMX_x86_OP(XOR, 0xef) - - MMX_x86_OP(ADDB, 0xfc) - MMX_x86_OP(ADDW, 0xfd) - MMX_x86_OP(ADDD, 0xfe) - MMX_x86_OP(ADDSB, 0xec) - MMX_x86_OP(ADDSW, 0xed) - MMX_x86_OP(ADDUSB, 0xdc) - MMX_x86_OP(ADDUSW, 0xdd) - - MMX_x86_OP(SUBB, 0xf8) - MMX_x86_OP(SUBW, 0xf9) - MMX_x86_OP(SUBD, 0xfa) - MMX_x86_OP(SUBSB, 0xe8) - MMX_x86_OP(SUBSW, 0xe9) - MMX_x86_OP(SUBUSB, 0xd8) - MMX_x86_OP(SUBUSW, 0xd9) - - MMX_x86_OP(PUNPCKLBW, 0x60); +MMX_x86_OP(ANDN, 0xdf) +MMX_x86_OP(OR, 0xeb) +MMX_x86_OP(XOR, 0xef) + +MMX_x86_OP(ADDB, 0xfc) +MMX_x86_OP(ADDW, 0xfd) +MMX_x86_OP(ADDD, 0xfe) +MMX_x86_OP(ADDSB, 0xec) +MMX_x86_OP(ADDSW, 0xed) +MMX_x86_OP(ADDUSB, 0xdc) +MMX_x86_OP(ADDUSW, 0xdd) + +MMX_x86_OP(SUBB, 0xf8) +MMX_x86_OP(SUBW, 0xf9) +MMX_x86_OP(SUBD, 0xfa) +MMX_x86_OP(SUBSB, 0xe8) +MMX_x86_OP(SUBSW, 0xe9) +MMX_x86_OP(SUBUSB, 0xd8) +MMX_x86_OP(SUBUSW, 0xd9) + +MMX_x86_OP(PUNPCKLBW, 0x60); MMX_x86_OP(PUNPCKLWD, 0x61); MMX_x86_OP(PUNPCKLDQ, 0x62); MMX_x86_OP(PCMPGTB, 0x64); @@ -3672,6 +3674,7 @@ MMX_x86_OP(PSLLQ, 0xf3); MMX_x86_OP(PMULLW, 0xd5); MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); +// clang-format on static __inline void MMX_PACKSSWB(int dst_reg, int src_reg) diff --git a/src/codegen/codegen_ops_xchg.h b/src/codegen/codegen_ops_xchg.h index 820d4461a2..28a5580780 100644 --- a/src/codegen/codegen_ops_xchg.h +++ b/src/codegen/codegen_ops_xchg.h @@ -1,15 +1,16 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_##reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ +#define OP_XCHG_AX_(reg) \ + static uint32_t \ + ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int ax_reg, host_reg, temp_reg; \ + \ + ax_reg = LOAD_REG_W(REG_AX); \ + host_reg = LOAD_REG_W(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ + STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ + \ + return op_pc; \ } OP_XCHG_AX_(BX) @@ -20,18 +21,19 @@ OP_XCHG_AX_(DI) OP_XCHG_AX_(SP) OP_XCHG_AX_(BP) -#define OP_XCHG_EAX_(reg) \ - static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_##reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ +#define OP_XCHG_EAX_(reg) \ + static uint32_t \ + ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int eax_reg, host_reg, temp_reg; \ + \ + eax_reg = LOAD_REG_L(REG_EAX); \ + host_reg = LOAD_REG_L(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ + STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ + \ + return op_pc; \ } OP_XCHG_EAX_(EBX) diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index c02e8a7c23..421f200262 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -11,8 +11,11 @@ # include "x86.h" # include "x86_flags.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "386_common.h" @@ -29,7 +32,8 @@ # include # endif -int codegen_flat_ds, codegen_flat_ss; +int codegen_flat_ds; +int codegen_flat_ss; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; int codegen_fpu_loaded_iq[8]; @@ -63,8 +67,6 @@ static int last_ssegs; void codegen_init(void) { - int c; - # if _WIN64 codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); # elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) @@ -77,26 +79,25 @@ codegen_init(void) memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (int c = 0; c < BLOCK_SIZE; c++) codeblock[c].valid = 0; } void codegen_reset(void) { - int c; - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); mem_reset_page_blocks(); - for (c = 0; c < BLOCK_SIZE; c++) + for (int c = 0; c < BLOCK_SIZE; c++) codeblock[c].valid = 0; } void dump_block(void) { + // } static void @@ -534,6 +535,7 @@ int opcode_0f_modrm[256] = { void codegen_debug(void) { + // } static x86seg * @@ -845,7 +847,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p switch (opcode) { case 0x0f: op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index c4b32c8a2e..456f93ae9b 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -49,6 +49,8 @@ # include "x86.h" # include "x86_flags.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" /*ex*/ # include <86box/nmi.h> @@ -1256,7 +1258,7 @@ codegen_init(void) # else __asm { - fstcw cpu_state.old_npxc + fstcw cpu_state.old_npxc } # endif } @@ -1677,6 +1679,7 @@ int opcode_0f_modrm[256] = { void codegen_debug(void) { + // } static x86seg * @@ -1884,7 +1887,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p switch (opcode) { case 0x0f: op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index d49fcecbf3..a3f4ede8f4 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -2,10 +2,13 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86_ops.h" #include "codegen.h" #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" @@ -90,7 +93,7 @@ codegen_generate_reset(void) } void -codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) +codegen_check_seg_read(UNUSED(codeblock_t *block), ir_data_t *ir, x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) @@ -108,7 +111,7 @@ codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) seg->checked = 1; } void -codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) +codegen_check_seg_write(UNUSED(codeblock_t *block), ir_data_t *ir, x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) @@ -140,10 +143,10 @@ codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int offset; switch (cpu_rm & 7) { + default: case 0: case 1: case 7: - default: base_reg = IREG_EBX; break; case 2: @@ -180,6 +183,9 @@ codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); (*op_pc) += 2; break; + + default: + break; } uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); @@ -241,12 +247,16 @@ codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, (*op_pc) += 4; uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); break; + + default: + break; } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) { /*ESP*/ uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); - // addbyte(0x05); - // addlong(stack_offset); +#if 0 + addbyte(0x05); + addlong(stack_offset); +#endif } if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) op_ea_seg = &cpu_state.seg_ss; @@ -264,6 +274,9 @@ codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, case 3: uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); break; + + default: + break; } } } else { @@ -374,7 +387,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p codeblock_t *block = &codeblock[block_current]; ir_data_t *ir = codegen_get_ir_data(); uint32_t op_pc = new_pc; - const OpFn *op_table = (OpFn *) x86_dynarec_opcodes; + const OpFn *op_table = x86_dynarec_opcodes; RecompOpFn *recomp_op_table = recomp_opcodes; int opcode_shift = 0; int opcode_mask = 0x3ff; @@ -399,7 +412,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p last_prefix = 0x0f; #endif op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; @@ -634,11 +647,11 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p } opcode_3dnow = fastreadb(cs + opcode_pc); - if (recomp_opcodes_3DNOW[opcode_3dnow]) { + if (!fpu_softfloat && recomp_opcodes_3DNOW[opcode_3dnow]) { next_pc = opcode_pc + 1; - op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; - recomp_op_table = recomp_opcodes_3DNOW; + op_table = x86_dynarec_opcodes_3DNOW; + recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_3DNOW; opcode = opcode_3dnow; recomp_opcode_mask = 0xff; opcode_mask = 0xff; @@ -646,8 +659,10 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p } codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); /* It is apparently a prefixed instruction. */ - // if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) - // goto codegen_skip; +#if 0 + if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) + goto codegen_skip; +#endif if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); @@ -668,7 +683,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p // codegen_skip: if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { - op_table = (OpFn *) x86_dynarec_opcodes; + op_table = x86_dynarec_opcodes; recomp_op_table = recomp_opcodes; } @@ -719,7 +734,9 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p last_op_32 = op_32; last_op_ea_seg = op_ea_seg; last_op_ssegs = op_ssegs; - // codegen_block_ins++; +#if 0 + codegen_block_ins++; +#endif block->ins++; @@ -728,6 +745,8 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p codegen_endpc = (cs + cpu_state.pc) + 8; - // if (has_ea) - // fatal("Has EA\n"); +#if 0 + if (has_ea) + fatal("Has EA\n"); +#endif } diff --git a/src/codegen_new/codegen.h b/src/codegen_new/codegen.h index 547f867e35..deeeb899c8 100644 --- a/src/codegen_new/codegen.h +++ b/src/codegen_new/codegen.h @@ -290,7 +290,6 @@ codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) } extern void codegen_init(void); -extern void codegen_close(void); extern void codegen_reset(void); extern void codegen_block_init(uint32_t phys_addr); extern void codegen_block_remove(void); diff --git a/src/codegen_new/codegen_accumulate.c b/src/codegen_new/codegen_accumulate.c index d9ae38af88..29b05ad770 100644 --- a/src/codegen_new/codegen_accumulate.c +++ b/src/codegen_new/codegen_accumulate.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "codegen.h" #include "codegen_accumulate.h" @@ -16,7 +17,7 @@ static struct }; void -codegen_accumulate(ir_data_t *ir, int acc_reg, int delta) +codegen_accumulate(UNUSED(ir_data_t *ir), int acc_reg, int delta) { acc_regs[acc_reg].count += delta; diff --git a/src/codegen_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c index 9661cf631f..90e619d702 100644 --- a/src/codegen_new/codegen_allocator.c +++ b/src/codegen_new/codegen_allocator.c @@ -13,6 +13,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "codegen.h" #include "codegen_allocator.h" @@ -112,7 +113,7 @@ codeblock_allocator_get_ptr(mem_block_t *block) } void -codegen_allocator_clean_blocks(struct mem_block_t *block) +codegen_allocator_clean_blocks(UNUSED(struct mem_block_t *block)) { #if defined __ARM_EABI__ || defined _ARM_ || defined __aarch64__ || defined _M_ARM || defined _M_ARM64 while (1) { diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index a389f239f7..b1e904096c 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -13,6 +13,8 @@ # include "codegen_backend_arm_ops.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # if defined(__linux__) || defined(__APPLE__) @@ -44,7 +46,7 @@ void *codegen_gpf_rout; void *codegen_exit_rout; host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - {REG_R4, 0}, + { REG_R4, 0}, { REG_R5, 0}, { REG_R6, 0}, { REG_R7, 0}, @@ -54,7 +56,7 @@ host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { }; host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - {REG_D8, 0}, + { REG_D8, 0}, { REG_D9, 0}, { REG_D10, 0}, { REG_D11, 0}, @@ -288,7 +290,6 @@ void codegen_backend_init(void) { codeblock_t *block; - int c; codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -296,7 +297,7 @@ codegen_backend_init(void) memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (int c = 0; c < BLOCK_SIZE; c++) codeblock[c].pc = BLOCK_PC_INVALID; block_current = 0; @@ -306,7 +307,9 @@ codegen_backend_init(void) block->data = codeblock_allocator_get_ptr(block->head_mem_block); block_write_data = block->data; build_loadstore_routines(&codeblock[block_current]); - // pclog("block_pos=%i\n", block_pos); +# if 0 + pclog("block_pos=%i\n", block_pos); +# endif codegen_fp_round = &block_write_data[block_pos]; build_fp_round_routine(&codeblock[block_current]); @@ -322,7 +325,9 @@ codegen_backend_init(void) host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); block_write_data = NULL; - // fatal("block_pos=%i\n", block_pos); +# if 0 + fatal("block_pos=%i\n", block_pos); +# endif asm("vmrs %0, fpscr\n" : "=r"(cpu_state.old_fp_control)); if ((cpu_state.old_fp_control >> 22) & 3) diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c index 48d9494068..1eb94a9090 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -13,6 +13,8 @@ # include "codegen_backend_arm64_ops.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # if defined(__linux__) || defined(__APPLE__) @@ -45,7 +47,7 @@ void *codegen_gpf_rout; void *codegen_exit_rout; host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - {REG_X19, 0}, + { REG_X19, 0}, { REG_X20, 0}, { REG_X21, 0}, { REG_X22, 0}, @@ -58,7 +60,7 @@ host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { }; host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - {REG_V8, 0}, + { REG_V8, 0}, { REG_V9, 0}, { REG_V10, 0}, { REG_V11, 0}, @@ -281,7 +283,6 @@ void codegen_backend_init(void) { codeblock_t *block; - int c; codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -289,7 +290,7 @@ codegen_backend_init(void) memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) { + for (int c = 0; c < BLOCK_SIZE; c++) { codeblock[c].pc = BLOCK_PC_INVALID; } diff --git a/src/codegen_new/codegen_backend_arm64_imm.c b/src/codegen_new/codegen_backend_arm64_imm.c index 6e5034cc07..88d28aee02 100644 --- a/src/codegen_new/codegen_backend_arm64_imm.c +++ b/src/codegen_new/codegen_backend_arm64_imm.c @@ -6,7 +6,7 @@ search over*/ #define IMM_NR 1302 static uint32_t imm_table[][2] = { - {0x800, 0x00000001}, + { 0x800, 0x00000001}, { 0xfc0, 0x00000002}, { 0x801, 0x00000003}, { 0xf80, 0x00000004}, diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index aa5e5870a3..915cae93dc 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -1,9 +1,11 @@ #if defined __aarch64__ || defined _M_ARM64 +# include # include # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" @@ -340,7 +342,7 @@ host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm } else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else - fatal("ADD_IMM_X %016llx\n", imm_data); + fatal("ADD_IMM_X %016" PRIu64 "\n", imm_data); } void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) @@ -662,7 +664,7 @@ host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) } else if (!(imm_data & 0xfffffffffffff000ull)) { codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); } else - fatal("CMNX_IMM %08x\n", imm_data); + fatal("CMNX_IMM %016" PRIx64 "\n", imm_data); } void @@ -683,7 +685,7 @@ host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) } else if (!(imm_data & 0xfffffffffffff000ull)) { codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); } else - fatal("CMPX_IMM %08x\n", imm_data); + fatal("CMPX_IMM %08" PRIu64 "\n", imm_data); } void diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 91fb9c903f..7514e1f0c3 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -4,8 +4,11 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" @@ -28,8 +31,12 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); @@ -59,8 +66,10 @@ codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -90,8 +99,12 @@ codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); @@ -138,8 +151,10 @@ codegen_AND(codeblock_t *block, uop_t *uop) static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -162,8 +177,12 @@ codegen_AND_IMM(codeblock_t *block, uop_t *uop) static int codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); @@ -259,8 +278,10 @@ codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -276,8 +297,10 @@ codegen_CMP_JB(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -294,8 +317,10 @@ codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -315,8 +340,10 @@ codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -336,8 +363,10 @@ codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -357,8 +386,10 @@ codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -378,8 +409,10 @@ codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -399,8 +432,10 @@ codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -420,8 +455,10 @@ codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -441,8 +478,10 @@ codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -462,8 +501,10 @@ codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -483,8 +524,10 @@ codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -504,8 +547,10 @@ codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -525,8 +570,10 @@ codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_CMP_REG(block, src_reg_a, src_reg_b); @@ -547,47 +594,55 @@ codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm64_FABS_D(block, dest_reg, src_reg_a); } else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + fatal("codegen_FABS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; } static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm64_FNEG_D(block, dest_reg, src_reg_a); } else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + fatal("codegen_FCHS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; } static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm64_FSQRT_D(block, dest_reg, src_reg_a); } else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + fatal("codegen_FSQRT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; } static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); @@ -608,8 +663,12 @@ codegen_FTST(codeblock_t *block, uop_t *uop) static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); @@ -621,8 +680,12 @@ codegen_FADD(codeblock_t *block, uop_t *uop) static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_MOVZ_IMM(block, dest_reg, 0); @@ -641,8 +704,12 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); @@ -654,8 +721,12 @@ codegen_FDIV(codeblock_t *block, uop_t *uop) static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); @@ -667,8 +738,12 @@ codegen_FMUL(codeblock_t *block, uop_t *uop) static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); @@ -818,7 +893,8 @@ codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); @@ -846,7 +922,9 @@ codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); @@ -880,7 +958,9 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) @@ -898,7 +978,9 @@ codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) @@ -917,7 +999,8 @@ codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_b_real); int src_size = IREG_GET_SIZE(uop->src_reg_b_real); host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); @@ -942,7 +1025,9 @@ codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); @@ -973,7 +1058,8 @@ codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); @@ -985,7 +1071,8 @@ codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); @@ -997,7 +1084,8 @@ codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); @@ -1010,7 +1098,9 @@ codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) @@ -1028,7 +1118,9 @@ codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) @@ -1047,8 +1139,10 @@ codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_MOV_REG(block, dest_reg, src_reg, 0); @@ -1105,8 +1199,10 @@ codegen_MOV_PTR(codeblock_t *block, uop_t *uop) static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); @@ -1128,8 +1224,10 @@ codegen_MOVSX(codeblock_t *block, uop_t *uop) static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_arm64_FMOV_D_Q(block, dest_reg, src_reg); @@ -1156,8 +1254,10 @@ codegen_MOVZX(codeblock_t *block, uop_t *uop) static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { host_arm64_SCVTF_D_W(block, dest_reg, src_reg); @@ -1175,8 +1275,10 @@ codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); @@ -1194,8 +1296,13 @@ codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); + int tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { uint32_t *branch_offset; @@ -1275,8 +1382,12 @@ codegen_NOP(codeblock_t *block, uop_t *uop) static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); @@ -1305,8 +1416,10 @@ codegen_OR(codeblock_t *block, uop_t *uop) static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -1325,8 +1438,10 @@ codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); @@ -1340,8 +1455,10 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); @@ -1371,8 +1488,12 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1384,8 +1505,12 @@ codegen_PADDB(codeblock_t *block, uop_t *uop) static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1397,8 +1522,12 @@ codegen_PADDW(codeblock_t *block, uop_t *uop) static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1410,8 +1539,12 @@ codegen_PADDD(codeblock_t *block, uop_t *uop) static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1423,8 +1556,12 @@ codegen_PADDSB(codeblock_t *block, uop_t *uop) static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1436,8 +1573,12 @@ codegen_PADDSW(codeblock_t *block, uop_t *uop) static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1449,8 +1590,12 @@ codegen_PADDUSB(codeblock_t *block, uop_t *uop) static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1463,8 +1608,12 @@ codegen_PADDUSW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1476,8 +1625,12 @@ codegen_PCMPEQB(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1489,8 +1642,12 @@ codegen_PCMPEQW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1502,8 +1659,12 @@ codegen_PCMPEQD(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1515,8 +1676,12 @@ codegen_PCMPGTB(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1528,8 +1693,12 @@ codegen_PCMPGTW(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1542,21 +1711,27 @@ codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); } else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + fatal("PF2ID %02x\n", uop->dest_reg_a_real); return 0; } static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1568,8 +1743,12 @@ codegen_PFADD(codeblock_t *block, uop_t *uop) static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1581,8 +1760,12 @@ codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1594,8 +1777,12 @@ codegen_PFCMPGE(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1607,8 +1794,12 @@ codegen_PFCMPGT(codeblock_t *block, uop_t *uop) static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1620,8 +1811,12 @@ codegen_PFMAX(codeblock_t *block, uop_t *uop) static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1633,8 +1828,12 @@ codegen_PFMIN(codeblock_t *block, uop_t *uop) static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1646,8 +1845,10 @@ codegen_PFMUL(codeblock_t *block, uop_t *uop) static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRECPE/VRECPS)*/ @@ -1655,15 +1856,17 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop) host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); } else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + fatal("PFRCP %02x\n", uop->dest_reg_a_real); return 0; } static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ @@ -1672,15 +1875,19 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop) host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); } else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + fatal("PFRSQRT %02x\n", uop->dest_reg_a_real); return 0; } static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1692,13 +1899,15 @@ codegen_PFSUB(codeblock_t *block, uop_t *uop) static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); } else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + fatal("PI2FD %02x\n", uop->dest_reg_a_real); return 0; } @@ -1706,8 +1915,12 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); @@ -1720,8 +1933,12 @@ codegen_PMADDWD(codeblock_t *block, uop_t *uop) static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1734,8 +1951,12 @@ codegen_PMULHW(codeblock_t *block, uop_t *uop) static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1748,8 +1969,10 @@ codegen_PMULLW(codeblock_t *block, uop_t *uop) static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1766,8 +1989,10 @@ codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1784,8 +2009,10 @@ codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1802,8 +2029,10 @@ codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1820,8 +2049,10 @@ codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1838,8 +2069,10 @@ codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1856,8 +2089,10 @@ codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1874,8 +2109,10 @@ codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1892,8 +2129,10 @@ codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1911,8 +2150,12 @@ codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1924,8 +2167,12 @@ codegen_PSUBB(codeblock_t *block, uop_t *uop) static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1937,8 +2184,12 @@ codegen_PSUBW(codeblock_t *block, uop_t *uop) static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -1950,8 +2201,12 @@ codegen_PSUBD(codeblock_t *block, uop_t *uop) static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1963,8 +2218,12 @@ codegen_PSUBSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -1976,8 +2235,12 @@ codegen_PSUBSW(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -1989,8 +2252,12 @@ codegen_PSUBUSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -2003,8 +2270,12 @@ codegen_PSUBUSW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -2016,8 +2287,12 @@ codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -2029,8 +2304,12 @@ codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -2042,8 +2321,12 @@ codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); @@ -2055,8 +2338,12 @@ codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); @@ -2068,8 +2355,12 @@ codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); @@ -2082,8 +2373,11 @@ codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_mov_imm(block, REG_TEMP2, 32); @@ -2121,8 +2415,10 @@ codegen_ROL(codeblock_t *block, uop_t *uop) static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (!(uop->imm_data & 31)) { @@ -2169,8 +2465,11 @@ codegen_ROL_IMM(codeblock_t *block, uop_t *uop) static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_ROR(block, dest_reg, src_reg, shift_reg); @@ -2200,8 +2499,10 @@ codegen_ROR(codeblock_t *block, uop_t *uop) static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (!(uop->imm_data & 31)) { @@ -2249,8 +2550,11 @@ codegen_ROR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_ASR(block, dest_reg, src_reg, shift_reg); @@ -2277,8 +2581,10 @@ codegen_SAR(codeblock_t *block, uop_t *uop) static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); @@ -2305,8 +2611,11 @@ codegen_SAR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_LSL(block, dest_reg, src_reg, shift_reg); @@ -2328,8 +2637,10 @@ codegen_SHL(codeblock_t *block, uop_t *uop) static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); @@ -2351,8 +2662,11 @@ codegen_SHL_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_LSR(block, dest_reg, src_reg, shift_reg); @@ -2376,8 +2690,10 @@ codegen_SHR(codeblock_t *block, uop_t *uop) static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); @@ -2427,8 +2743,12 @@ codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); @@ -2465,8 +2785,10 @@ codegen_SUB(codeblock_t *block, uop_t *uop) static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -2532,8 +2854,12 @@ codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); @@ -2562,8 +2888,10 @@ codegen_XOR(codeblock_t *block, uop_t *uop) static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); diff --git a/src/codegen_new/codegen_backend_arm_ops.c b/src/codegen_new/codegen_backend_arm_ops.c index e56b2f6e58..3331af4e08 100644 --- a/src/codegen_new/codegen_backend_arm_ops.c +++ b/src/codegen_new/codegen_backend_arm_ops.c @@ -4,6 +4,7 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" @@ -297,7 +298,9 @@ in_range(void *addr, void *base) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -// void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +# if 0 +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +# endif void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index d0b8b86c1c..338d3dd546 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -5,8 +5,11 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" @@ -87,8 +90,12 @@ host_arm_nop(codeblock_t *block) static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); @@ -119,11 +126,15 @@ codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { -// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); -// return 0; +# if 0 + host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +# endif - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -151,8 +162,12 @@ codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); @@ -199,8 +214,10 @@ codegen_AND(codeblock_t *block, uop_t *uop) static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -228,8 +245,12 @@ codegen_AND_IMM(codeblock_t *block, uop_t *uop) static int codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); @@ -326,8 +347,10 @@ codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -343,8 +366,10 @@ codegen_CMP_JB(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -361,8 +386,10 @@ codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -382,8 +409,10 @@ codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -403,8 +432,10 @@ codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -424,8 +455,10 @@ codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -445,8 +478,10 @@ codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -466,8 +501,10 @@ codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -487,8 +524,10 @@ codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -508,8 +547,10 @@ codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -529,8 +570,10 @@ codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -550,8 +593,10 @@ codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -571,8 +616,10 @@ codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -592,8 +639,10 @@ codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_CMP_REG(block, src_reg_a, src_reg_b); @@ -614,8 +663,10 @@ codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm_VABS_D(block, dest_reg, src_reg_a); @@ -627,8 +678,10 @@ codegen_FABS(codeblock_t *block, uop_t *uop) static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm_VNEG_D(block, dest_reg, src_reg_a); @@ -640,8 +693,10 @@ codegen_FCHS(codeblock_t *block, uop_t *uop) static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_arm_VSQRT_D(block, dest_reg, src_reg_a); @@ -653,8 +708,10 @@ codegen_FSQRT(codeblock_t *block, uop_t *uop) static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); @@ -673,8 +730,12 @@ codegen_FTST(codeblock_t *block, uop_t *uop) static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); @@ -686,8 +747,12 @@ codegen_FADD(codeblock_t *block, uop_t *uop) static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm_VCMP_D(block, src_reg_a, src_reg_b); @@ -704,8 +769,12 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); @@ -717,8 +786,12 @@ codegen_FDIV(codeblock_t *block, uop_t *uop) static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); @@ -730,8 +803,12 @@ codegen_FMUL(codeblock_t *block, uop_t *uop) static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); @@ -878,7 +955,8 @@ codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); @@ -908,7 +986,9 @@ codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); @@ -943,7 +1023,9 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) @@ -962,7 +1044,9 @@ codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) @@ -982,7 +1066,8 @@ codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_b_real); int src_size = IREG_GET_SIZE(uop->src_reg_b_real); host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); @@ -1006,7 +1091,9 @@ codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); @@ -1038,7 +1125,8 @@ codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); @@ -1051,7 +1139,8 @@ codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); @@ -1064,7 +1153,8 @@ codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); @@ -1077,7 +1167,9 @@ codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) @@ -1096,7 +1188,9 @@ codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) @@ -1116,8 +1210,10 @@ codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); @@ -1176,8 +1272,10 @@ codegen_MOV_PTR(codeblock_t *block, uop_t *uop) static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { host_arm_SXTB(block, dest_reg, src_reg, 0); @@ -1199,8 +1297,10 @@ codegen_MOVSX(codeblock_t *block, uop_t *uop) static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_IMM(block, REG_TEMP, 0); @@ -1237,8 +1337,10 @@ int64_to_double(int64_t a) static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); @@ -1261,8 +1363,10 @@ codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); @@ -1281,7 +1385,8 @@ codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) static int64_t x87_fround64(double b) { - int64_t a, c; + int64_t a; + int64_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -1306,8 +1411,13 @@ x87_fround64(double b) static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); + int tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { uint32_t *branch_offset; @@ -1390,8 +1500,12 @@ codegen_NOP(codeblock_t *block, uop_t *uop) static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); @@ -1420,8 +1534,10 @@ codegen_OR(codeblock_t *block, uop_t *uop) static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -1440,8 +1556,12 @@ codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); @@ -1457,8 +1577,12 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); @@ -1474,8 +1598,12 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); @@ -1492,8 +1620,12 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); @@ -1505,8 +1637,12 @@ codegen_PADDB(codeblock_t *block, uop_t *uop) static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); @@ -1518,8 +1654,12 @@ codegen_PADDW(codeblock_t *block, uop_t *uop) static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); @@ -1531,8 +1671,12 @@ codegen_PADDD(codeblock_t *block, uop_t *uop) static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); @@ -1544,8 +1688,12 @@ codegen_PADDSB(codeblock_t *block, uop_t *uop) static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); @@ -1557,8 +1705,12 @@ codegen_PADDSW(codeblock_t *block, uop_t *uop) static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); @@ -1570,8 +1722,12 @@ codegen_PADDUSB(codeblock_t *block, uop_t *uop) static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); @@ -1584,8 +1740,12 @@ codegen_PADDUSW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); @@ -1597,8 +1757,12 @@ codegen_PCMPEQB(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); @@ -1610,8 +1774,12 @@ codegen_PCMPEQW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); @@ -1623,8 +1791,12 @@ codegen_PCMPEQD(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); @@ -1636,8 +1808,12 @@ codegen_PCMPGTB(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); @@ -1649,8 +1825,12 @@ codegen_PCMPGTW(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); @@ -1663,8 +1843,10 @@ codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); @@ -1676,8 +1858,12 @@ codegen_PF2ID(codeblock_t *block, uop_t *uop) static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1689,8 +1875,12 @@ codegen_PFADD(codeblock_t *block, uop_t *uop) static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1702,8 +1892,12 @@ codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1715,8 +1909,12 @@ codegen_PFCMPGE(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1728,8 +1926,12 @@ codegen_PFCMPGT(codeblock_t *block, uop_t *uop) static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1741,8 +1943,12 @@ codegen_PFMAX(codeblock_t *block, uop_t *uop) static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1754,8 +1960,12 @@ codegen_PFMIN(codeblock_t *block, uop_t *uop) static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1767,8 +1977,10 @@ codegen_PFMUL(codeblock_t *block, uop_t *uop) static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRECPE/VRECPS)*/ @@ -1783,8 +1995,10 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop) static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ @@ -1800,8 +2014,12 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop) static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); @@ -1813,8 +2031,10 @@ codegen_PFSUB(codeblock_t *block, uop_t *uop) static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); @@ -1827,8 +2047,12 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); @@ -1842,8 +2066,12 @@ codegen_PMADDWD(codeblock_t *block, uop_t *uop) static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); @@ -1856,8 +2084,12 @@ codegen_PMULHW(codeblock_t *block, uop_t *uop) static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); @@ -1870,8 +2102,10 @@ codegen_PMULLW(codeblock_t *block, uop_t *uop) static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1888,8 +2122,10 @@ codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1906,8 +2142,10 @@ codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1924,8 +2162,10 @@ codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1942,8 +2182,10 @@ codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1960,8 +2202,10 @@ codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1978,8 +2222,10 @@ codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -1996,8 +2242,10 @@ codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -2014,8 +2262,10 @@ codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { if (uop->imm_data == 0) @@ -2033,8 +2283,12 @@ codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); @@ -2046,8 +2300,12 @@ codegen_PSUBB(codeblock_t *block, uop_t *uop) static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); @@ -2059,8 +2317,12 @@ codegen_PSUBW(codeblock_t *block, uop_t *uop) static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); @@ -2072,8 +2334,12 @@ codegen_PSUBD(codeblock_t *block, uop_t *uop) static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); @@ -2085,8 +2351,12 @@ codegen_PSUBSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); @@ -2098,8 +2368,12 @@ codegen_PSUBSW(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); @@ -2111,8 +2385,12 @@ codegen_PSUBUSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); @@ -2125,8 +2403,12 @@ codegen_PSUBUSW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2142,8 +2424,12 @@ codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2159,8 +2445,12 @@ codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2176,8 +2466,12 @@ codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2192,8 +2486,12 @@ codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2208,8 +2506,12 @@ codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); @@ -2225,8 +2527,11 @@ codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); @@ -2259,8 +2564,10 @@ codegen_ROL(codeblock_t *block, uop_t *uop) static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (!(uop->imm_data & 31)) { @@ -2307,8 +2614,11 @@ codegen_ROL_IMM(codeblock_t *block, uop_t *uop) static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); @@ -2338,8 +2648,10 @@ codegen_ROR(codeblock_t *block, uop_t *uop) static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (!(uop->imm_data & 31)) { @@ -2387,8 +2699,11 @@ codegen_ROR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); @@ -2415,8 +2730,10 @@ codegen_SAR(codeblock_t *block, uop_t *uop) static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); @@ -2443,8 +2760,11 @@ codegen_SAR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); @@ -2466,8 +2786,10 @@ codegen_SHL(codeblock_t *block, uop_t *uop) static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); @@ -2489,8 +2811,11 @@ codegen_SHL_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); @@ -2514,8 +2839,10 @@ codegen_SHR(codeblock_t *block, uop_t *uop) static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); @@ -2564,8 +2891,12 @@ codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); @@ -2597,14 +2928,18 @@ codegen_SUB(codeblock_t *block, uop_t *uop) return 0; -// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); -// return 0; +# if 0 + host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +# endif } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); @@ -2670,8 +3005,12 @@ codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); @@ -2700,8 +3039,10 @@ codegen_XOR(codeblock_t *block, uop_t *uop) static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index a57cb42827..3cbca28f88 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -14,6 +14,8 @@ # include "codegen_backend_x86-64_ops_sse.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # if defined(__linux__) || defined(__APPLE__) # include @@ -71,7 +73,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ESI = address Out - ECX = data, ESI = abrt*/ @@ -159,7 +161,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ECX = data, ESI = address Out - ESI = abrt diff --git a/src/codegen_new/codegen_backend_x86-64_ops.c b/src/codegen_new/codegen_backend_x86-64_ops.c index 33fb500dbc..236a86ce76 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops.c +++ b/src/codegen_new/codegen_backend_x86-64_ops.c @@ -1,9 +1,11 @@ #if defined __amd64__ || defined _M_X64 # include +# include # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" @@ -125,7 +127,7 @@ host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ } else - fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); + fatal("ADD64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data); } void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) @@ -584,7 +586,7 @@ host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ codegen_addlong(block, offset); @@ -604,7 +606,7 @@ host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ codegen_addlong(block, offset); @@ -689,11 +691,11 @@ host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ codegen_addlong(block, ram_offset); @@ -713,11 +715,11 @@ host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ codegen_addbyte(block, 0x24); @@ -743,11 +745,11 @@ host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ codegen_addlong(block, ram_offset); @@ -770,7 +772,7 @@ host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); @@ -1091,7 +1093,7 @@ host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x66); codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { codegen_alloc_bytes(block, 10); codegen_addbyte2(block, 0x66, 0x41); codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ @@ -1111,8 +1113,10 @@ host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; - // if (dst_reg & 8) - // fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); +#if 0 + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); +#endif if (offset >= -128 && offset < 127) { if (dst_reg & 8) { @@ -1123,7 +1127,7 @@ host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ } - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); @@ -1154,7 +1158,7 @@ host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + } else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { codegen_alloc_bytes(block, 9); codegen_addbyte(block, 0x41); codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ @@ -1614,7 +1618,7 @@ host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ } else - fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); + fatal("SUB64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data); } void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) diff --git a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h index 42c2d52597..b5d146439a 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h @@ -1,16 +1,18 @@ #define JMP_LEN_BYTES 5 static inline void -codegen_addbyte(codeblock_t *block, uint8_t val) +codegen_addbyte(UNUSED(codeblock_t *block), uint8_t val) { if (block_pos >= BLOCK_MAX) { fatal("codegen_addbyte over! %i\n", block_pos); - // CPU_BLOCK_END(); +#if 0 + CPU_BLOCK_END(); +#endif } block_write_data[block_pos++] = val; } static inline void -codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +codegen_addbyte2(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb) { if (block_pos > (BLOCK_MAX - 2)) { fatal("codegen_addbyte2 over! %i\n", block_pos); @@ -20,7 +22,7 @@ codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) block_write_data[block_pos++] = valb; } static inline void -codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +codegen_addbyte3(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc) { if (block_pos > (BLOCK_MAX - 3)) { fatal("codegen_addbyte3 over! %i\n", block_pos); @@ -31,7 +33,7 @@ codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) block_write_data[block_pos++] = valc; } static inline void -codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +codegen_addbyte4(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { if (block_pos > (BLOCK_MAX - 4)) { fatal("codegen_addbyte4 over! %i\n", block_pos); @@ -44,7 +46,7 @@ codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, u } static inline void -codegen_addword(codeblock_t *block, uint16_t val) +codegen_addword(UNUSED(codeblock_t *block), uint16_t val) { if (block_pos > (BLOCK_MAX - 2)) { fatal("codegen_addword over! %i\n", block_pos); @@ -55,7 +57,7 @@ codegen_addword(codeblock_t *block, uint16_t val) } static inline void -codegen_addlong(codeblock_t *block, uint32_t val) +codegen_addlong(UNUSED(codeblock_t *block), uint32_t val) { if (block_pos > (BLOCK_MAX - 4)) { fatal("codegen_addlong over! %i\n", block_pos); @@ -66,7 +68,7 @@ codegen_addlong(codeblock_t *block, uint32_t val) } static inline void -codegen_addquad(codeblock_t *block, uint64_t val) +codegen_addquad(UNUSED(codeblock_t *block), uint64_t val) { if (block_pos > (BLOCK_MAX - 8)) { fatal("codegen_addquad over! %i\n", block_pos); diff --git a/src/codegen_new/codegen_backend_x86-64_ops_sse.c b/src/codegen_new/codegen_backend_x86-64_ops_sse.c index f15b1aee48..caa925fc04 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86-64_ops_sse.c @@ -4,6 +4,7 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" @@ -127,7 +128,7 @@ host_x86_LDMXCSR(codeblock_t *block, void *p) if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } else if (offset < (1ull << 32)) { + } else if (offset < (1ULL << 32)) { codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ codegen_addlong(block, offset); diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index e9c08cbc8e..fcab0f3ce8 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -4,8 +4,11 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" @@ -32,8 +35,12 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) @@ -59,8 +66,10 @@ codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (dest_reg != src_reg) @@ -103,8 +112,12 @@ codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); @@ -131,8 +144,10 @@ codegen_AND(codeblock_t *block, uop_t *uop) static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (dest_reg != src_reg) @@ -157,8 +172,14 @@ codegen_AND_IMM(codeblock_t *block, uop_t *uop) static int codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); +#if 0 + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); +#endif + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); @@ -264,8 +285,10 @@ codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -283,8 +306,10 @@ codegen_CMP_JB(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { @@ -303,8 +328,10 @@ codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -324,8 +351,10 @@ codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -345,8 +374,10 @@ codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -366,8 +397,10 @@ codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -387,8 +420,10 @@ codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -408,8 +443,10 @@ codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -429,8 +466,10 @@ codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -450,8 +489,10 @@ codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -471,8 +512,10 @@ codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -492,8 +535,10 @@ codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -513,8 +558,10 @@ codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -534,8 +581,10 @@ codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); @@ -556,8 +605,10 @@ codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); @@ -573,8 +624,10 @@ codegen_FABS(codeblock_t *block, uop_t *uop) static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); @@ -590,8 +643,10 @@ codegen_FCHS(codeblock_t *block, uop_t *uop) static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); @@ -605,8 +660,10 @@ codegen_FSQRT(codeblock_t *block, uop_t *uop) static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); @@ -631,8 +688,12 @@ codegen_FTST(codeblock_t *block, uop_t *uop) static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); @@ -646,8 +707,12 @@ codegen_FADD(codeblock_t *block, uop_t *uop) static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { if (dest_reg != REG_EAX) @@ -670,8 +735,12 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); @@ -689,8 +758,12 @@ codegen_FDIV(codeblock_t *block, uop_t *uop) static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); @@ -704,8 +777,12 @@ codegen_FMUL(codeblock_t *block, uop_t *uop) static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); @@ -794,7 +871,7 @@ codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG1(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); @@ -802,7 +879,7 @@ codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG2(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); @@ -810,7 +887,7 @@ codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG3(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); @@ -839,7 +916,7 @@ codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG2_IMM(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); @@ -847,7 +924,7 @@ codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG3_IMM(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); @@ -882,7 +959,8 @@ codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); @@ -912,7 +990,9 @@ codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -948,7 +1028,9 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); # ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); @@ -968,7 +1050,9 @@ codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); # ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); @@ -989,7 +1073,8 @@ codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_b_real); int src_size = IREG_GET_SIZE(uop->src_reg_b_real); host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); @@ -1016,7 +1101,8 @@ codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); @@ -1029,7 +1115,8 @@ codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); @@ -1042,7 +1129,8 @@ codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); @@ -1056,7 +1144,9 @@ codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1088,7 +1178,9 @@ codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); # ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); @@ -1108,7 +1200,9 @@ codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); # ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); @@ -1129,8 +1223,10 @@ codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_x86_MOV32_REG_REG(block, dest_reg, src_reg); @@ -1222,8 +1318,10 @@ codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); @@ -1241,8 +1339,10 @@ codegen_MOVSX(codeblock_t *block, uop_t *uop) static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); @@ -1265,8 +1365,10 @@ codegen_MOVZX(codeblock_t *block, uop_t *uop) static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); @@ -1286,8 +1388,10 @@ codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { host_x86_LDMXCSR(block, &cpu_state.new_fp_control); @@ -1308,8 +1412,13 @@ codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); + int tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { uint32_t *branch_offset; @@ -1334,7 +1443,7 @@ codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) } static int -codegen_NOP(codeblock_t *block, uop_t *uop) +codegen_NOP(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { return 0; } @@ -1342,8 +1451,12 @@ codegen_NOP(codeblock_t *block, uop_t *uop) static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); @@ -1370,7 +1483,8 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); @@ -1389,8 +1503,10 @@ codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1404,8 +1520,10 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1419,8 +1537,10 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1435,8 +1555,10 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1450,8 +1572,10 @@ codegen_PADDB(codeblock_t *block, uop_t *uop) static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1465,8 +1589,10 @@ codegen_PADDW(codeblock_t *block, uop_t *uop) static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); @@ -1480,8 +1606,10 @@ codegen_PADDD(codeblock_t *block, uop_t *uop) static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1495,8 +1623,10 @@ codegen_PADDSB(codeblock_t *block, uop_t *uop) static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1510,8 +1640,10 @@ codegen_PADDSW(codeblock_t *block, uop_t *uop) static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1525,8 +1657,10 @@ codegen_PADDUSB(codeblock_t *block, uop_t *uop) static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1541,8 +1675,10 @@ codegen_PADDUSW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1556,8 +1692,10 @@ codegen_PCMPEQB(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1571,8 +1709,10 @@ codegen_PCMPEQW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); @@ -1586,8 +1726,10 @@ codegen_PCMPEQD(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); @@ -1601,8 +1743,10 @@ codegen_PCMPGTB(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1616,8 +1760,10 @@ codegen_PCMPGTW(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); @@ -1632,8 +1778,10 @@ codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); @@ -1649,8 +1797,10 @@ codegen_PF2ID(codeblock_t *block, uop_t *uop) static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); @@ -1664,8 +1814,10 @@ codegen_PFADD(codeblock_t *block, uop_t *uop) static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); @@ -1679,8 +1831,10 @@ codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); @@ -1694,8 +1848,10 @@ codegen_PFCMPGE(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); @@ -1709,8 +1865,10 @@ codegen_PFCMPGT(codeblock_t *block, uop_t *uop) static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); @@ -1724,8 +1882,10 @@ codegen_PFMAX(codeblock_t *block, uop_t *uop) static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); @@ -1739,8 +1899,10 @@ codegen_PFMIN(codeblock_t *block, uop_t *uop) static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); @@ -1754,8 +1916,10 @@ codegen_PFMUL(codeblock_t *block, uop_t *uop) static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use RCPSS + iteration)*/ @@ -1774,8 +1938,10 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop) static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use RSQRTSS + iteration)*/ @@ -1794,8 +1960,12 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop) static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); @@ -1813,8 +1983,10 @@ codegen_PFSUB(codeblock_t *block, uop_t *uop) static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); @@ -1829,8 +2001,10 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); @@ -1844,8 +2018,10 @@ codegen_PMADDWD(codeblock_t *block, uop_t *uop) static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); @@ -1859,8 +2035,10 @@ codegen_PMULHW(codeblock_t *block, uop_t *uop) static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2011,8 +2189,10 @@ codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); @@ -2026,8 +2206,10 @@ codegen_PSUBB(codeblock_t *block, uop_t *uop) static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2041,8 +2223,10 @@ codegen_PSUBW(codeblock_t *block, uop_t *uop) static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); @@ -2056,8 +2240,10 @@ codegen_PSUBD(codeblock_t *block, uop_t *uop) static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); @@ -2071,8 +2257,10 @@ codegen_PSUBSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2086,8 +2274,10 @@ codegen_PSUBSW(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); @@ -2101,8 +2291,10 @@ codegen_PSUBUSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2117,8 +2309,10 @@ codegen_PSUBUSW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2132,8 +2326,10 @@ codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); @@ -2147,8 +2343,10 @@ codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); @@ -2162,8 +2360,10 @@ codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); @@ -2177,8 +2377,10 @@ codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); @@ -2192,8 +2394,10 @@ codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); @@ -2208,8 +2412,11 @@ codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2234,8 +2441,10 @@ codegen_ROL(codeblock_t *block, uop_t *uop) static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2259,8 +2468,11 @@ codegen_ROL_IMM(codeblock_t *block, uop_t *uop) static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2285,8 +2497,10 @@ codegen_ROR(codeblock_t *block, uop_t *uop) static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2311,8 +2525,11 @@ codegen_ROR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2337,8 +2554,10 @@ codegen_SAR(codeblock_t *block, uop_t *uop) static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2362,8 +2581,11 @@ codegen_SAR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2388,8 +2610,10 @@ codegen_SHL(codeblock_t *block, uop_t *uop) static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2413,8 +2637,11 @@ codegen_SHL_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2439,8 +2666,10 @@ codegen_SHR(codeblock_t *block, uop_t *uop) static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2486,8 +2715,12 @@ codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) @@ -2511,8 +2744,10 @@ codegen_SUB(codeblock_t *block, uop_t *uop) static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (dest_reg != src_reg) @@ -2580,8 +2815,11 @@ codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); @@ -2602,7 +2840,8 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); @@ -3251,7 +3490,7 @@ codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host } void -codegen_set_jump_dest(codeblock_t *block, void *p) +codegen_set_jump_dest(UNUSED(codeblock_t *block), void *p) { *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c index f656e708f1..18235e2b22 100644 --- a/src/codegen_new/codegen_backend_x86.c +++ b/src/codegen_new/codegen_backend_x86.c @@ -15,6 +15,8 @@ # include "codegen_backend_x86_ops_sse.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # if defined(__linux__) || defined(__APPLE__) # include diff --git a/src/codegen_new/codegen_backend_x86_ops.c b/src/codegen_new/codegen_backend_x86_ops.c index 4807caacf2..90e59dcb0a 100644 --- a/src/codegen_new/codegen_backend_x86_ops.c +++ b/src/codegen_new/codegen_backend_x86_ops.c @@ -4,6 +4,7 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" diff --git a/src/codegen_new/codegen_backend_x86_ops_fpu.c b/src/codegen_new/codegen_backend_x86_ops_fpu.c index 13f90743a8..7f47351245 100644 --- a/src/codegen_new/codegen_backend_x86_ops_fpu.c +++ b/src/codegen_new/codegen_backend_x86_ops_fpu.c @@ -4,6 +4,7 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" diff --git a/src/codegen_new/codegen_backend_x86_ops_helpers.h b/src/codegen_new/codegen_backend_x86_ops_helpers.h index 0a6469a896..f0da3ff643 100644 --- a/src/codegen_new/codegen_backend_x86_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86_ops_helpers.h @@ -1,14 +1,14 @@ #define JMP_LEN_BYTES 5 static inline void -codegen_addbyte(codeblock_t *block, uint8_t val) +codegen_addbyte(UNUSED(codeblock_t *block), uint8_t val) { if (block_pos >= BLOCK_MAX) fatal("codegen_addbyte over! %i\n", block_pos); block_write_data[block_pos++] = val; } static inline void -codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +codegen_addbyte2(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb) { if (block_pos > (BLOCK_MAX - 2)) fatal("codegen_addbyte2 over! %i\n", block_pos); @@ -16,7 +16,7 @@ codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) block_write_data[block_pos++] = valb; } static inline void -codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +codegen_addbyte3(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc) { if (block_pos > (BLOCK_MAX - 3)) fatal("codegen_addbyte3 over! %i\n", block_pos); @@ -25,7 +25,7 @@ codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) block_write_data[block_pos++] = valc; } static inline void -codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +codegen_addbyte4(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { if (block_pos > (BLOCK_MAX - 4)) fatal("codegen_addbyte4 over! %i\n", block_pos); @@ -36,7 +36,7 @@ codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, u } static inline void -codegen_addword(codeblock_t *block, uint16_t val) +codegen_addword(UNUSED(codeblock_t *block), uint16_t val) { if (block_pos > (BLOCK_MAX - 2)) fatal("codegen_addword over! %i\n", block_pos); @@ -45,7 +45,7 @@ codegen_addword(codeblock_t *block, uint16_t val) } static inline void -codegen_addlong(codeblock_t *block, uint32_t val) +codegen_addlong(UNUSED(codeblock_t *block), uint32_t val) { if (block_pos > (BLOCK_MAX - 4)) fatal("codegen_addlong over! %i\n", block_pos); @@ -54,7 +54,7 @@ codegen_addlong(codeblock_t *block, uint32_t val) } static inline void -codegen_addquad(codeblock_t *block, uint64_t val) +codegen_addquad(UNUSED(codeblock_t *block), uint64_t val) { if (block_pos > (BLOCK_MAX - 8)) fatal("codegen_addquad over! %i\n", block_pos); diff --git a/src/codegen_new/codegen_backend_x86_ops_sse.c b/src/codegen_new/codegen_backend_x86_ops_sse.c index a1e04db305..084e04a87f 100644 --- a/src/codegen_new/codegen_backend_x86_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86_ops_sse.c @@ -4,6 +4,7 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "codegen.h" # include "codegen_allocator.h" diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 00ae453c3e..5ef2d97b8a 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -4,9 +4,12 @@ # include <86box/86box.h> # include "cpu.h" # include <86box/mem.h> +# include <86box/plat_unused.h> # include "x86.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "386_common.h" # include "codegen.h" # include "codegen_allocator.h" @@ -34,10 +37,10 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -65,10 +68,10 @@ codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -111,10 +114,10 @@ codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -143,10 +146,10 @@ codegen_AND(codeblock_t *block, uop_t *uop) static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -172,11 +175,11 @@ static int codegen_ANDN(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -#if 0 +# if 0 int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); -#endif - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +# endif + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -220,7 +223,9 @@ codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); host_x86_JNZ(block, codegen_exit_rout); - // host_x86_CALL(block, codegen_debug); +# if 0 + host_x86_CALL(block, codegen_debug); +# endif return 0; } @@ -285,8 +290,8 @@ codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; @@ -306,8 +311,8 @@ codegen_CMP_JB(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); uint32_t *jump_p; @@ -328,8 +333,8 @@ codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -351,8 +356,8 @@ codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -374,8 +379,8 @@ codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -397,8 +402,8 @@ codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -420,8 +425,8 @@ codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -443,8 +448,8 @@ codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -466,8 +471,8 @@ codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -489,8 +494,8 @@ codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -512,8 +517,8 @@ codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -535,8 +540,8 @@ codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -558,8 +563,8 @@ codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -581,8 +586,8 @@ codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -605,9 +610,9 @@ codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { @@ -624,9 +629,9 @@ codegen_FABS(codeblock_t *block, uop_t *uop) static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { @@ -643,9 +648,9 @@ codegen_FCHS(codeblock_t *block, uop_t *uop) static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { @@ -660,9 +665,9 @@ codegen_FSQRT(codeblock_t *block, uop_t *uop) static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { @@ -688,10 +693,10 @@ codegen_FTST(codeblock_t *block, uop_t *uop) static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -707,10 +712,10 @@ codegen_FADD(codeblock_t *block, uop_t *uop) static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -735,10 +740,10 @@ codegen_FCOM(codeblock_t *block, uop_t *uop) static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -758,10 +763,10 @@ codegen_FDIV(codeblock_t *block, uop_t *uop) static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -777,10 +782,10 @@ codegen_FMUL(codeblock_t *block, uop_t *uop) static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -867,7 +872,7 @@ codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG1(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); @@ -875,7 +880,7 @@ codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG2(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); @@ -883,7 +888,7 @@ codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) return 0; } static int -codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +codegen_LOAD_FUNC_ARG3(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { # ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); @@ -938,8 +943,8 @@ codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); @@ -969,9 +974,9 @@ codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1008,7 +1013,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); # ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); @@ -1031,7 +1036,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); # ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); @@ -1053,8 +1058,8 @@ codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_b_real); int src_size = IREG_GET_SIZE(uop->src_reg_b_real); host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); @@ -1081,9 +1086,9 @@ codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1115,7 +1120,7 @@ codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1129,7 +1134,7 @@ codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1143,7 +1148,7 @@ codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); @@ -1158,9 +1163,9 @@ codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); # ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); @@ -1180,9 +1185,9 @@ codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real); int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_reg = HOST_REG_GET(uop->src_reg_c_real); # ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); @@ -1203,10 +1208,10 @@ codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { host_x86_MOV32_REG_REG(block, dest_reg, src_reg); @@ -1298,10 +1303,10 @@ codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); @@ -1319,10 +1324,10 @@ codegen_MOVSX(codeblock_t *block, uop_t *uop) static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); @@ -1345,10 +1350,10 @@ codegen_MOVZX(codeblock_t *block, uop_t *uop) static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); @@ -1372,10 +1377,10 @@ codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { host_x86_LDMXCSR(block, &cpu_state.new_fp_control); @@ -1397,12 +1402,12 @@ codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); - int tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); + int tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); int src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { @@ -1432,7 +1437,7 @@ codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) } static int -codegen_NOP(codeblock_t *block, uop_t *uop) +codegen_NOP(UNUSED(codeblock_t *block), UNUSED(uop_t *uop)) { return 0; } @@ -1440,10 +1445,10 @@ codegen_NOP(codeblock_t *block, uop_t *uop) static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -1471,8 +1476,8 @@ codegen_OR(codeblock_t *block, uop_t *uop) static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (REG_IS_L(dest_size) && dest_reg == src_reg) { @@ -1492,9 +1497,9 @@ codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1509,9 +1514,9 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1526,9 +1531,9 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1544,9 +1549,9 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1561,9 +1566,9 @@ codegen_PADDB(codeblock_t *block, uop_t *uop) static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1578,9 +1583,9 @@ codegen_PADDW(codeblock_t *block, uop_t *uop) static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1595,9 +1600,9 @@ codegen_PADDD(codeblock_t *block, uop_t *uop) static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1612,9 +1617,9 @@ codegen_PADDSB(codeblock_t *block, uop_t *uop) static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1629,9 +1634,9 @@ codegen_PADDSW(codeblock_t *block, uop_t *uop) static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1646,9 +1651,9 @@ codegen_PADDUSB(codeblock_t *block, uop_t *uop) static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1664,9 +1669,9 @@ codegen_PADDUSW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1681,9 +1686,9 @@ codegen_PCMPEQB(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1698,9 +1703,9 @@ codegen_PCMPEQW(codeblock_t *block, uop_t *uop) static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1715,9 +1720,9 @@ codegen_PCMPEQD(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1732,9 +1737,9 @@ codegen_PCMPGTB(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1749,9 +1754,9 @@ codegen_PCMPGTW(codeblock_t *block, uop_t *uop) static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1767,9 +1772,9 @@ codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { @@ -1786,9 +1791,9 @@ codegen_PF2ID(codeblock_t *block, uop_t *uop) static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1803,9 +1808,9 @@ codegen_PFADD(codeblock_t *block, uop_t *uop) static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1820,9 +1825,9 @@ codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1837,9 +1842,9 @@ codegen_PFCMPGE(codeblock_t *block, uop_t *uop) static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1854,9 +1859,9 @@ codegen_PFCMPGT(codeblock_t *block, uop_t *uop) static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1871,9 +1876,9 @@ codegen_PFMAX(codeblock_t *block, uop_t *uop) static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1888,9 +1893,9 @@ codegen_PFMIN(codeblock_t *block, uop_t *uop) static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -1905,9 +1910,9 @@ codegen_PFMUL(codeblock_t *block, uop_t *uop) static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { @@ -1927,9 +1932,9 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop) static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { @@ -1949,10 +1954,10 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop) static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -1972,9 +1977,9 @@ codegen_PFSUB(codeblock_t *block, uop_t *uop) static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { @@ -1990,9 +1995,9 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2007,9 +2012,9 @@ codegen_PMADDWD(codeblock_t *block, uop_t *uop) static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2024,9 +2029,9 @@ codegen_PMULHW(codeblock_t *block, uop_t *uop) static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2178,9 +2183,9 @@ codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2195,9 +2200,9 @@ codegen_PSUBB(codeblock_t *block, uop_t *uop) static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2212,9 +2217,9 @@ codegen_PSUBW(codeblock_t *block, uop_t *uop) static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2229,9 +2234,9 @@ codegen_PSUBD(codeblock_t *block, uop_t *uop) static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2246,9 +2251,9 @@ codegen_PSUBSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2263,9 +2268,9 @@ codegen_PSUBSW(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2280,9 +2285,9 @@ codegen_PSUBUSB(codeblock_t *block, uop_t *uop) static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2298,9 +2303,9 @@ codegen_PSUBUSW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2316,9 +2321,9 @@ codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2334,9 +2339,9 @@ codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2352,9 +2357,9 @@ codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2369,9 +2374,9 @@ codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2386,9 +2391,9 @@ codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { @@ -2404,11 +2409,11 @@ codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int shift_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2433,10 +2438,10 @@ codegen_ROL(codeblock_t *block, uop_t *uop) static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2460,11 +2465,11 @@ codegen_ROL_IMM(codeblock_t *block, uop_t *uop) static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int shift_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2489,10 +2494,10 @@ codegen_ROR(codeblock_t *block, uop_t *uop) static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2517,11 +2522,11 @@ codegen_ROR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int shift_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2546,10 +2551,10 @@ codegen_SAR(codeblock_t *block, uop_t *uop) static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2573,11 +2578,11 @@ codegen_SAR_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int shift_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2602,10 +2607,10 @@ codegen_SHL(codeblock_t *block, uop_t *uop) static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2629,11 +2634,11 @@ codegen_SHL_IMM(codeblock_t *block, uop_t *uop) static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int shift_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { @@ -2658,10 +2663,10 @@ codegen_SHR(codeblock_t *block, uop_t *uop) static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) @@ -2705,10 +2710,10 @@ codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -2734,10 +2739,10 @@ codegen_SUB(codeblock_t *block, uop_t *uop) static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { if (dest_reg != src_reg) @@ -2805,9 +2810,9 @@ codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -2831,7 +2836,7 @@ codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); @@ -3493,7 +3498,7 @@ codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host } void -codegen_set_jump_dest(codeblock_t *block, void *p) +codegen_set_jump_dest(UNUSED(codeblock_t *block), void *p) { *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index 3a1a5e1ab7..ee0a030ba9 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -1,13 +1,17 @@ +#include #include #include #include #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "386_common.h" @@ -225,33 +229,6 @@ codegen_init(void) #endif } -void -codegen_close(void) -{ -#ifdef DEBUG_EXTRA - pclog("Instruction counts :\n"); - while (1) { - int c; - uint32_t highest_num = 0, highest_idx = 0; - - for (c = 0; c < 256 * 256; c++) { - if (instr_counts[c] > highest_num) { - highest_num = instr_counts[c]; - highest_idx = c; - } - } - if (!highest_num) - break; - - instr_counts[highest_idx] = 0; - if (highest_idx > 256) - pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); - else - pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); - } -#endif -} - void codegen_reset(void) { @@ -281,20 +258,24 @@ codegen_reset(void) void dump_block(void) { - /* codeblock_t *block = pages[0x119000 >> 12].block; +#if 0 + codeblock_t *block = pages[0x119000 >> 12].block; - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); + pclog("dump_block:\n"); + while (block) { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - block = block->next; - } - pclog("dump_block done\n");*/ + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); + + if (!block->pc) + fatal("Dead PC=0\n"); + + block = block->next; + } + + pclog("dump_block done\n");*/ +#endif } static void @@ -305,7 +286,7 @@ add_to_block_list(codeblock_t *block) #ifndef RELEASE_BUILD if (!block->page_mask) - fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2); + fatal("add_to_block_list - mask = 0 %" PRIx64 " %" PRIx64 "\n", block->page_mask, block->page_mask2); #endif if (block_prev_nr) { @@ -341,7 +322,7 @@ add_to_block_list(codeblock_t *block) } static void -remove_from_block_list(codeblock_t *block, uint32_t pc) +remove_from_block_list(codeblock_t *block, UNUSED(uint32_t pc)) { if (!block->page_mask) return; @@ -468,7 +449,7 @@ codegen_delete_random_block(int required_mem_block) } void -codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +codegen_check_flush(page_t *page, UNUSED(uint64_t mask), UNUSED(uint32_t phys_addr)) { uint16_t block_nr = page->block; int remove_from_evict_list = 0; diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index 44689a5d19..6345bbe865 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -189,6 +189,8 @@ codegen_ir_compile(ir_data_t *ir, codeblock_t *block) codegen_backend_epilogue(block); block_write_data = NULL; - // if (has_ea) - // fatal("IR compilation complete\n"); +#if 0 + if (has_ea) + fatal("IR compilation complete\n"); +#endif } diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 698a7899b8..59e1486593 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -144,6 +144,54 @@ RecompOpFn recomp_opcodes_0f[512] = { // clang-format on }; +RecompOpFn recomp_opcodes_0f_no_mmx[512] = { + // clang-format off + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on +}; + RecompOpFn recomp_opcodes_3DNOW[256] = { // clang-format off #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 @@ -556,4 +604,3 @@ RecompOpFn recomp_opcodes_df[512] = { /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // clang-format on }; - diff --git a/src/codegen_new/codegen_ops.h b/src/codegen_new/codegen_ops.h index 9cef07e152..a91382c2fe 100644 --- a/src/codegen_new/codegen_ops.h +++ b/src/codegen_new/codegen_ops.h @@ -9,6 +9,7 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; +extern RecompOpFn recomp_opcodes_0f_no_mmx[512]; extern RecompOpFn recomp_opcodes_3DNOW[256]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; @@ -18,8 +19,10 @@ extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; -/*extern RecompOpFn recomp_opcodes_REPE[512]; -extern RecompOpFn recomp_opcodes_REPNE[512];*/ +#if 0 +extern RecompOpFn recomp_opcodes_REPE[512]; +extern RecompOpFn recomp_opcodes_REPNE[512]; +#endif #define REG_EAX 0 #define REG_ECX 1 diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index c2b04584cf..8b4d471ba0 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -46,9 +49,9 @@ ropParith(PFMAX) ropParith(PFMIN) ropParith(PFMUL) ropParith(PFSUB) -// clang-format on + // clang-format on -uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -72,7 +75,7 @@ uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe } uint32_t -ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPFSUBR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -96,7 +99,7 @@ ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPI2FD(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -120,7 +123,7 @@ ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPFRCPIT(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -142,7 +145,7 @@ ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 2; } uint32_t -ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPFRCP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -165,7 +168,7 @@ ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 2; } uint32_t -ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPFRSQRT(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -189,7 +192,7 @@ ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MMX_ENTER(ir); diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 5325b282b2..9e136ace57 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -19,7 +22,7 @@ get_cf(ir_data_t *ir, int dest_reg) } uint32_t -ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -36,7 +39,7 @@ ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -53,7 +56,7 @@ ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -70,7 +73,7 @@ ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -102,7 +105,7 @@ ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -137,7 +140,7 @@ ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -169,7 +172,7 @@ ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -204,7 +207,7 @@ ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -235,7 +238,7 @@ ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -271,7 +274,7 @@ ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -286,7 +289,7 @@ ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -301,7 +304,7 @@ ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV(ir, IREG_flags_op1, IREG_EAX); @@ -322,7 +325,7 @@ ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -352,7 +355,7 @@ ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -384,7 +387,7 @@ ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -414,7 +417,7 @@ ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -446,7 +449,7 @@ ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -475,7 +478,7 @@ ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -508,7 +511,7 @@ ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -523,7 +526,7 @@ ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -538,7 +541,7 @@ ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -552,7 +555,7 @@ ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -582,7 +585,7 @@ ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -612,7 +615,7 @@ ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -642,7 +645,7 @@ ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -672,7 +675,7 @@ ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -701,7 +704,7 @@ ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -731,7 +734,7 @@ ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -748,7 +751,7 @@ ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -765,7 +768,7 @@ ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -782,7 +785,7 @@ ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -814,7 +817,7 @@ ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -849,7 +852,7 @@ ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -881,7 +884,7 @@ ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -917,7 +920,7 @@ ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -948,7 +951,7 @@ ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -985,7 +988,7 @@ ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -1000,7 +1003,7 @@ ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -1015,7 +1018,7 @@ ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV(ir, IREG_flags_op1, IREG_EAX); @@ -1037,7 +1040,7 @@ ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -1067,7 +1070,7 @@ ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -1099,7 +1102,7 @@ ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -1129,7 +1132,7 @@ ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -1162,7 +1165,7 @@ ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -1191,7 +1194,7 @@ ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -1225,7 +1228,7 @@ ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +rop80(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int skip_immediate = 0; @@ -1433,7 +1436,7 @@ rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint return op_pc + 2; } uint32_t -rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +rop81_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int skip_immediate = 0; @@ -1683,7 +1686,7 @@ rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 3; } uint32_t -rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +rop81_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int skip_immediate = 0; @@ -1933,7 +1936,7 @@ rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +rop83_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { codegen_mark_code_present(block, cs + op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { @@ -2099,7 +2102,7 @@ rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 2; } uint32_t -rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +rop83_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { codegen_mark_code_present(block, cs + op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { @@ -2278,6 +2281,9 @@ rebuild_c(ir_data_t *ir) case FLAGS_DEC32: needs_rebuild = 0; break; + + default: + break; } } @@ -2287,7 +2293,7 @@ rebuild_c(ir_data_t *ir) } uint32_t -ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropINC_r16(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2301,7 +2307,7 @@ ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropINC_r32(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2316,7 +2322,7 @@ ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropDEC_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2330,7 +2336,7 @@ ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropDEC_r32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2345,7 +2351,7 @@ ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropINCDEC(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { codegen_mark_code_present(block, cs + op_pc, 1); rebuild_c(ir); diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index 9a6722342b..cedb54177e 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x86_flags.h" #include "codegen.h" @@ -25,7 +28,7 @@ VF_SET_01(void) } static int -ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +ropJO_common(UNUSED(codeblock_t *block), ir_data_t *ir, uint32_t dest_addr, UNUSED(uint32_t next_pc)) { int jump_uop; @@ -63,7 +66,7 @@ ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t nex return 0; } static int -ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +ropJNO_common(UNUSED(codeblock_t *block), ir_data_t *ir, uint32_t dest_addr, UNUSED(uint32_t next_pc)) { int jump_uop; @@ -526,7 +529,7 @@ ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t ne } static int -ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +ropJP_common(UNUSED(codeblock_t *block), ir_data_t *ir, uint32_t dest_addr, UNUSED(uint32_t next_pc)) { int jump_uop; @@ -538,7 +541,7 @@ ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t nex return 0; } static int -ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +ropJNP_common(UNUSED(codeblock_t *block), ir_data_t *ir, uint32_t dest_addr, UNUSED(uint32_t next_pc)) { int jump_uop; @@ -850,23 +853,24 @@ ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t n } ropJ(O) - ropJ(NO) - ropJ(B) - ropJ(NB) - ropJ(E) - ropJ(NE) - ropJ(BE) - ropJ(NBE) - ropJ(S) - ropJ(NS) - ropJ(P) - ropJ(NP) - ropJ(L) - ropJ(NL) - ropJ(LE) - ropJ(NLE) - - uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJ(NO) +ropJ(B) +ropJ(NB) +ropJ(E) +ropJ(NE) +ropJ(BE) +ropJ(NBE) +ropJ(S) +ropJ(NS) +ropJ(P) +ropJ(NP) +ropJ(L) +ropJ(NL) +ropJ(LE) +ropJ(NLE) + +uint32_t +ropJCXZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -888,7 +892,7 @@ ropJ(O) } uint32_t -ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -928,7 +932,7 @@ ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOPE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -961,7 +965,7 @@ ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOPNE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 98d77250cd..3ab7be8ac9 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" @@ -15,7 +18,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFADD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -26,7 +29,7 @@ ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFADDr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -37,7 +40,7 @@ ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFADDP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -50,7 +53,7 @@ ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -62,7 +65,7 @@ ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -75,7 +78,7 @@ ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); @@ -87,7 +90,7 @@ ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIV(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -98,7 +101,7 @@ ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIVR(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -109,7 +112,7 @@ ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIVr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -120,7 +123,7 @@ ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIVRr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -131,7 +134,7 @@ ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIVP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -143,7 +146,7 @@ ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFDIVRP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -156,7 +159,7 @@ ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFMUL(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -167,7 +170,7 @@ ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFMULr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -178,7 +181,7 @@ ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFMULP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -191,7 +194,7 @@ ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUB(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -202,7 +205,7 @@ ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUBR(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -213,7 +216,7 @@ ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUBr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -224,7 +227,7 @@ ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUBRr(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -235,7 +238,7 @@ ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUBP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -247,7 +250,7 @@ ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSUBRP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -260,7 +263,7 @@ ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFUCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -272,7 +275,7 @@ ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFUCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -285,7 +288,7 @@ ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); @@ -561,10 +564,11 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) return op_pc + 1; \ } - ropFI_arith_mem(l, IREG_temp0) - ropFI_arith_mem(w, IREG_temp0_W) +ropFI_arith_mem(l, IREG_temp0) +ropFI_arith_mem(w, IREG_temp0_W) - uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFABS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FABS(ir, IREG_ST(0), IREG_ST(0)); @@ -574,7 +578,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) } uint32_t -ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFCHS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); @@ -583,7 +587,7 @@ ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSQRT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); @@ -592,7 +596,7 @@ ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index 89c1386373..8628458687 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" @@ -15,7 +18,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFLD1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV_IMM(ir, IREG_temp0, 1); @@ -26,7 +29,7 @@ ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc; } uint32_t -ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFLDZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV_IMM(ir, IREG_temp0, 0); diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 06709913d1..7635063e86 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" @@ -15,7 +18,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFLDs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -31,7 +34,7 @@ ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFLDd(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -48,7 +51,7 @@ ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -62,7 +65,7 @@ ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTPs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -78,7 +81,7 @@ ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTd(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -93,7 +96,7 @@ ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTPd(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -111,7 +114,7 @@ ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFILDw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -128,7 +131,7 @@ ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t UNUSED(opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -145,7 +148,7 @@ ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFILDq(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -163,7 +166,7 @@ ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFISTw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -179,7 +182,7 @@ ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFISTPw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -196,7 +199,7 @@ ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFISTl(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -212,7 +215,7 @@ ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFISTPl(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -229,7 +232,7 @@ ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFISTPq(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index cca9f4e4fb..7865e05730 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" @@ -15,7 +18,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFFREE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -26,7 +29,7 @@ ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u } uint32_t -ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFLD(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -40,7 +43,7 @@ ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uin } uint32_t -ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -52,7 +55,7 @@ ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uin return op_pc; } uint32_t -ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -66,7 +69,7 @@ ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTCW(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -80,7 +83,7 @@ ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTSW(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; @@ -94,7 +97,7 @@ ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFSTSW_AX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV(ir, IREG_AX, IREG_NPXS); @@ -103,7 +106,7 @@ ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFXCH(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int dest_reg = fetchdat & 7; diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index 242cbb8188..f2a4ce41a1 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -12,7 +15,7 @@ #include "codegen_ops_helpers.h" void -LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +LOAD_IMMEDIATE_FROM_RAM_16_unaligned(UNUSED(codeblock_t *block), ir_data_t *ir, int dest_reg, uint32_t addr) { /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); @@ -22,7 +25,7 @@ LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest } void -LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +LOAD_IMMEDIATE_FROM_RAM_32_unaligned(UNUSED(codeblock_t *block), ir_data_t *ir, int dest_reg, uint32_t addr) { /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); @@ -36,7 +39,7 @@ LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest #define UNROLL_MAX_UOPS 1000 #define UNROLL_MAX_COUNT 10 int -codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, UNUSED(uint32_t next_pc), uint32_t dest_addr) { int start; int max_unroll; diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index 0bd4db24af..fb2f1e5bab 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -12,7 +15,7 @@ #include "codegen_ops_mov.h" uint32_t -ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_r8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -26,7 +29,7 @@ ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return dest_addr; } uint32_t -ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); uint32_t dest_addr = op_pc + 2 + offset; @@ -39,7 +42,7 @@ ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return dest_addr; } uint32_t -ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); uint32_t dest_addr = op_pc + 4 + offset; @@ -51,7 +54,7 @@ ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_far_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t new_pc = fastreadw(cs + op_pc); uint16_t new_cs = fastreadw(cs + op_pc + 2); @@ -66,7 +69,7 @@ ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return -1; } uint32_t -ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_far_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t new_pc = fastreadl(cs + op_pc); uint16_t new_cs = fastreadw(cs + op_pc + 4); @@ -82,7 +85,7 @@ ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd } uint32_t -ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCALL_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); uint16_t ret_addr = op_pc + 2; @@ -101,7 +104,7 @@ ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return -1; } uint32_t -ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCALL_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); uint32_t ret_addr = op_pc + 4; @@ -119,7 +122,7 @@ ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRET_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -135,7 +138,7 @@ ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return -1; } uint32_t -ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRET_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -151,7 +154,7 @@ ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRET_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset = fastreadw(cs + op_pc); @@ -170,7 +173,7 @@ ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return -1; } uint32_t -ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRET_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset = fastreadw(cs + op_pc); @@ -189,7 +192,7 @@ ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd } uint32_t -ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRETF_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) return 0; @@ -212,7 +215,7 @@ ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return -1; } uint32_t -ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRETF_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) return 0; @@ -236,7 +239,7 @@ ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset; @@ -263,7 +266,7 @@ ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return -1; } uint32_t -ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset; diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index 6db452a450..684052fea3 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -13,7 +16,7 @@ #include "codegen_ops_logic.h" uint32_t -ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -26,7 +29,7 @@ ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -39,7 +42,7 @@ ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (block->flags & CODEBLOCK_NO_IMMEDIATES) { LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); @@ -57,7 +60,7 @@ ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -83,7 +86,7 @@ ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -112,7 +115,7 @@ ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -138,7 +141,7 @@ ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -167,7 +170,7 @@ ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -193,7 +196,7 @@ ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -223,7 +226,7 @@ ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -236,7 +239,7 @@ ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -249,7 +252,7 @@ ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 2; } uint32_t -ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (block->flags & CODEBLOCK_NO_IMMEDIATES) { LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); @@ -268,7 +271,7 @@ ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 4; } uint32_t -ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -294,7 +297,7 @@ ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -323,7 +326,7 @@ ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -349,7 +352,7 @@ ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -378,7 +381,7 @@ ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -404,7 +407,7 @@ ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -434,7 +437,7 @@ ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -446,7 +449,7 @@ ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 1; } uint32_t -ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -458,7 +461,7 @@ ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 2; } uint32_t -ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (block->flags & CODEBLOCK_NO_IMMEDIATES) { LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); @@ -476,7 +479,7 @@ ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc return op_pc + 4; } uint32_t -ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -502,7 +505,7 @@ ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -528,7 +531,7 @@ ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -554,7 +557,7 @@ ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -567,7 +570,7 @@ ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -580,7 +583,7 @@ ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (block->flags & CODEBLOCK_NO_IMMEDIATES) { LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); @@ -599,7 +602,7 @@ ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 4; } uint32_t -ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -625,7 +628,7 @@ ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -654,7 +657,7 @@ ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -680,7 +683,7 @@ ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -709,7 +712,7 @@ ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -735,7 +738,7 @@ ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index 9a23536ed5..545634672b 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -13,7 +16,7 @@ #include "codegen_ops_misc.h" uint32_t -ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLEA_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -27,7 +30,7 @@ ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLEA_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -42,7 +45,7 @@ ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropF6(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; uint8_t imm_data; @@ -105,11 +108,14 @@ ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint codegen_flags_changed = 1; return op_pc + 1; + + default: + break; } return 0; } uint32_t -ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropF7_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; uint16_t imm_data; @@ -172,11 +178,14 @@ ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u codegen_flags_changed = 1; return op_pc + 1; + + default: + break; } return 0; } uint32_t -ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropF7_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; uint32_t imm_data; @@ -238,6 +247,9 @@ ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u codegen_flags_changed = 1; return op_pc + 1; + + default: + break; } return 0; } @@ -257,6 +269,9 @@ rebuild_c(ir_data_t *ir) case FLAGS_DEC32: needs_rebuild = 0; break; + + default: + break; } } @@ -266,7 +281,7 @@ rebuild_c(ir_data_t *ir) } uint32_t -ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFF_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg; @@ -360,12 +375,15 @@ ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); SUB_SP(ir, 2); return op_pc + 1; + + default: + break; } return 0; } uint32_t -ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropFF_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg; @@ -459,39 +477,42 @@ ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); SUB_SP(ir, 4); return op_pc + 1; + + default: + break; } return 0; } uint32_t -ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropNOP(UNUSED(codeblock_t *block), UNUSED(ir_data_t *ir), UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { return op_pc; } uint32_t -ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCBW(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOVSX(ir, IREG_AX, IREG_AL); return op_pc; } uint32_t -ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCDQ(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); return op_pc; } uint32_t -ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCWD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); return op_pc; } uint32_t -ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOVSX(ir, IREG_EAX, IREG_AX); @@ -545,26 +566,27 @@ ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } ropLxS(LDS, &cpu_state.seg_ds) - ropLxS(LES, &cpu_state.seg_es) - ropLxS(LFS, &cpu_state.seg_fs) - ropLxS(LGS, &cpu_state.seg_gs) - ropLxS(LSS, &cpu_state.seg_ss) +ropLxS(LES, &cpu_state.seg_es) +ropLxS(LFS, &cpu_state.seg_fs) +ropLxS(LGS, &cpu_state.seg_gs) +ropLxS(LSS, &cpu_state.seg_ss) - uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCLC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); return op_pc; } uint32_t -ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCMC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); return op_pc; } uint32_t -ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSTC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); @@ -572,20 +594,20 @@ ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uin } uint32_t -ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCLD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); return op_pc; } uint32_t -ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSTD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); return op_pc; } uint32_t -ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropCLI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; @@ -594,7 +616,7 @@ ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uin return op_pc; } uint32_t -ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSTI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index b352c402a0..e99b4c56d5 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -56,4 +58,4 @@ ropParith(PSUBUSW) ropParith(PMADDWD) ropParith(PMULHW) ropParith(PMULLW) -// clang-format on + // clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index c8d4909f96..6f38cba670 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -43,4 +45,4 @@ ropPcmp(PCMPEQD) ropPcmp(PCMPGTB) ropPcmp(PCMPGTW) ropPcmp(PCMPGTD) -// clang-format on + // clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index a20e18e68c..9d37228ec2 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -14,7 +17,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -36,7 +39,7 @@ ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc + 1; } uint32_t -ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -63,7 +66,7 @@ ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -85,7 +88,7 @@ ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 664bfd14ca..dd50b486e6 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -14,7 +17,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -36,7 +39,7 @@ ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPANDN(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -58,7 +61,7 @@ ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -80,7 +83,7 @@ ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uin return op_pc + 1; } uint32_t -ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPXOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 99016352e8..d25edd52ea 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -46,4 +48,4 @@ ropPpack(PUNPCKLDQ) ropPpack(PUNPCKHBW) ropPpack(PUNPCKHWD) ropPpack(PUNPCKHDQ) -// clang-format on + // clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index 32449d188d..b812a9bb25 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -2,9 +2,12 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" @@ -14,7 +17,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int reg = fetchdat & 7; int op = fetchdat & 0x38; @@ -40,7 +43,7 @@ ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 2; } uint32_t -ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int reg = fetchdat & 7; int op = fetchdat & 0x38; @@ -66,7 +69,7 @@ ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 2; } uint32_t -ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int reg = fetchdat & 7; int op = fetchdat & 0x38; diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index 68e8fb0116..eae7045a87 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -12,7 +15,7 @@ #include "codegen_ops_mov.h" uint32_t -ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm = fastreadb(cs + op_pc); @@ -22,7 +25,7 @@ ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = fastreadw(cs + op_pc); @@ -32,7 +35,7 @@ ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 2; } uint32_t -ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { if (block->flags & CODEBLOCK_NO_IMMEDIATES) { LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); @@ -45,7 +48,7 @@ ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd } uint32_t -ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_b_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -66,7 +69,7 @@ ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_w_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -87,7 +90,7 @@ ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_l_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; @@ -108,7 +111,7 @@ ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_r_b(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -128,7 +131,7 @@ ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_r_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -148,7 +151,7 @@ ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_r_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -169,7 +172,7 @@ ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -186,7 +189,7 @@ ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -203,7 +206,7 @@ ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr = 0; @@ -230,7 +233,7 @@ ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t -ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -247,7 +250,7 @@ ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -264,7 +267,7 @@ ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -282,7 +285,7 @@ ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t -ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; uint8_t imm; @@ -305,7 +308,7 @@ ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 2; } uint32_t -ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; uint16_t imm; @@ -328,7 +331,7 @@ ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 3; } uint32_t -ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg; uint32_t imm; @@ -352,7 +355,7 @@ ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg; @@ -396,7 +399,7 @@ ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda return op_pc + 1; } uint32_t -ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg; @@ -440,7 +443,7 @@ ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg; x86seg *rseg; @@ -483,7 +486,7 @@ ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchda } uint32_t -ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -504,7 +507,7 @@ ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -525,7 +528,7 @@ ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -547,7 +550,7 @@ ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t -ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -568,7 +571,7 @@ ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -589,7 +592,7 @@ ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; @@ -611,7 +614,7 @@ ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t -ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXCHG_AX(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int reg2 = IREG_16(opcode & 7); @@ -622,7 +625,7 @@ ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXCHG_EAX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int reg2 = IREG_32(opcode & 7); @@ -634,7 +637,7 @@ ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXCHG_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int reg1 = IREG_8((fetchdat >> 3) & 7); @@ -660,7 +663,7 @@ ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXCHG_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int reg1 = IREG_16((fetchdat >> 3) & 7); @@ -686,7 +689,7 @@ ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc + 1; } uint32_t -ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXCHG_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int reg1 = IREG_32((fetchdat >> 3) & 7); @@ -713,7 +716,7 @@ ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXLAT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); diff --git a/src/codegen_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c index 8ccf7d9e72..0daebff670 100644 --- a/src/codegen_new/codegen_ops_shift.c +++ b/src/codegen_new/codegen_ops_shift.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x86_flags.h" #include "386_common.h" #include "codegen.h" @@ -429,7 +432,7 @@ shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86se } uint32_t -ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropC0(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; uint8_t imm; @@ -452,7 +455,7 @@ ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint return op_pc + 1; } uint32_t -ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropC1_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; uint8_t imm; @@ -475,7 +478,7 @@ ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropC1_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; @@ -512,7 +515,7 @@ ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD0(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; @@ -530,7 +533,7 @@ ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); } uint32_t -ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD1_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; @@ -548,7 +551,7 @@ ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); } uint32_t -ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD1_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; @@ -567,7 +570,7 @@ ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD2(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; @@ -687,7 +690,7 @@ ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint return op_pc + 1; } uint32_t -ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD3_w(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; @@ -807,7 +810,7 @@ ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui return op_pc + 1; } uint32_t -ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropD3_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; @@ -928,7 +931,7 @@ ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, ui } uint32_t -ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg = (fetchdat >> 3) & 7; @@ -973,7 +976,7 @@ ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 2; } uint32_t -ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg = (fetchdat >> 3) & 7; @@ -1018,7 +1021,7 @@ ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 2; } uint32_t -ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg = (fetchdat >> 3) & 7; @@ -1063,7 +1066,7 @@ ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 2; } uint32_t -ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; int src_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index b7afdce251..92ad9509de 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -2,8 +2,11 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x86_flags.h" #include "386_common.h" #include "codegen.h" @@ -13,7 +16,7 @@ #include "codegen_ops_misc.h" uint32_t -ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -25,7 +28,7 @@ ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc; } uint32_t -ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -38,7 +41,7 @@ ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOP_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -54,7 +57,7 @@ ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOP_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -71,7 +74,7 @@ ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = fastreadw(cs + op_pc); int sp_reg; @@ -85,7 +88,7 @@ ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return op_pc + 2; } uint32_t -ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t imm = fastreadl(cs + op_pc); int sp_reg; @@ -100,7 +103,7 @@ ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t -ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc); int sp_reg; @@ -114,7 +117,7 @@ ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return op_pc + 1; } uint32_t -ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc); int sp_reg; @@ -129,7 +132,7 @@ ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t -ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOP_W(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -161,7 +164,7 @@ ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc + 1; } uint32_t -ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOP_L(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -262,7 +265,7 @@ ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) uint32_t -ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLEAVE_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -278,7 +281,7 @@ ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc; } uint32_t -ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLEAVE_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -295,7 +298,7 @@ ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSHA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -314,7 +317,7 @@ ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat return op_pc; } uint32_t -ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSHA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -334,7 +337,7 @@ ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat } uint32_t -ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOPA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -352,7 +355,7 @@ ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, return op_pc; } uint32_t -ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPOPA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -371,7 +374,7 @@ ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, } uint32_t -ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -387,7 +390,7 @@ ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, u return op_pc; } uint32_t -ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index 63277690f9..a3f000826c 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "codegen.h" #include "codegen_backend.h" @@ -561,7 +562,7 @@ alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) last valid version*/ int prev_version = ir_reg.version - 1; while (prev_version >= 0) { - reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + const reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) { reg_set->locked |= (1 << c); @@ -733,7 +734,7 @@ codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) int codegen_reg_is_loaded(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); + const host_reg_set_t *reg_set = get_reg_set(ir_reg); /*Search for previous version in host register*/ for (int c = 0; c < reg_set->nr_regs; c++) { @@ -758,7 +759,10 @@ codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) int c; int target; - // pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); +#if 0 + pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); +#endif + /*Search for required register*/ for (c = 0; c < reg_set->nr_regs; c++) { if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) @@ -773,7 +777,9 @@ codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) codegen_reg_writeback(reg_set, block, target, 0); reg_set->regs[target] = dst; reg_set->dirty[target] = 1; - // pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); +#if 0 + pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); +#endif /*Invalidate any stale copies of the dest register*/ for (c = 0; c < reg_set->nr_regs; c++) { @@ -787,7 +793,7 @@ codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) } void -codegen_reg_flush(ir_data_t *ir, codeblock_t *block) +codegen_reg_flush(UNUSED(ir_data_t *ir), codeblock_t *block) { host_reg_set_t *reg_set; int c; @@ -816,7 +822,7 @@ codegen_reg_flush(ir_data_t *ir, codeblock_t *block) } void -codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) +codegen_reg_flush_invalidate(UNUSED(ir_data_t *ir), codeblock_t *block) { host_reg_set_t *reg_set; int c; diff --git a/src/codegen_new/codegen_reg.h b/src/codegen_new/codegen_reg.h index c106349f53..ebb90b42f0 100644 --- a/src/codegen_new/codegen_reg.h +++ b/src/codegen_new/codegen_reg.h @@ -283,8 +283,7 @@ extern uint8_t reg_last_version[IREG_COUNT]; /*This register and the parent uOP have been optimised out.*/ #define REG_FLAGS_DEAD (1 << 1) -typedef struct -{ +typedef struct { /*Refcount of pending reads on this register version*/ uint8_t refcount; /*Flags*/ @@ -308,8 +307,7 @@ add_to_dead_list(reg_version_t *regv, int reg, int version) reg_dead_list = version | (reg << 8); } -typedef struct -{ +typedef struct { uint16_t reg; uint16_t version; } ir_reg_t; @@ -347,7 +345,9 @@ codegen_reg_read(int reg) CPU_BLOCK_END(); if (version->refcount > max_version_refcount) max_version_refcount = version->refcount; - // pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); +#if 0 + pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); +#endif return ireg; } @@ -387,7 +387,9 @@ codegen_reg_write(int reg, int uop_nr) version->refcount = 0; version->flags = 0; version->parent_uop = uop_nr; - // pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); +#if 0 + pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); +#endif return ireg; } diff --git a/src/config.c b/src/config.c index 3a66bc01d1..3e4fd72221 100644 --- a/src/config.c +++ b/src/config.c @@ -84,11 +84,6 @@ static int cw; static int ch; static ini_t config; -/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ -static int backwards_compat = 0; -static int backwards_compat2 = 0; - -#define ENABLE_CONFIG_LOG 1 #ifdef ENABLE_CONFIG_LOG int config_do_log = ENABLE_CONFIG_LOG; @@ -145,14 +140,9 @@ load_general(void) update_icons = ini_section_get_int(cat, "update_icons", 1); window_remember = ini_section_get_int(cat, "window_remember", 0); - if (window_remember || (vid_resize & 2)) { - if (!window_remember) - ini_section_delete_var(cat, "window_remember"); - } else { - ini_section_delete_var(cat, "window_remember"); + if (!window_remember && !(vid_resize & 2)) window_w = window_h = window_x = window_y = 0; - } if (vid_resize & 2) { p = ini_section_get_string(cat, "window_fixed_res", NULL); @@ -213,41 +203,37 @@ load_general(void) if (p == NULL) p = "0, 0, 0, 0"; sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy); - } else { + } else cw = ch = cx = cy = 0; - ini_section_delete_var(cat, "window_remember"); - } ini_section_delete_var(cat, "window_coordinates"); + + do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0); } /* Load monitor section. */ static void load_monitor(int monitor_index) { - ini_section_t cat; - char name[512]; - char temp[512]; - char *p = NULL; + ini_section_t cat; + char name[512]; + char temp[512]; + const char * p = NULL; + monitor_settings_t *ms = &monitor_settings[monitor_index]; sprintf(name, "Monitor #%i", monitor_index + 1); sprintf(temp, "%i, %i, %i, %i", cx, cy, cw, ch); cat = ini_find_section(config, name); - p = ini_section_get_string(cat, "window_coordinates", NULL); - - if (p == NULL) - p = temp; + p = ini_section_get_string(cat, "window_coordinates", temp); if (window_remember) { - sscanf(p, "%i, %i, %i, %i", - &monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y, - &monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h); - monitor_settings[monitor_index].mon_window_maximized = !!ini_section_get_int(cat, "window_maximized", 0); - } else { - monitor_settings[monitor_index].mon_window_maximized = 0; - } + sscanf(p, "%i, %i, %i, %i", &ms->mon_window_x, &ms->mon_window_y, + &ms->mon_window_w, &ms->mon_window_h); + ms->mon_window_maximized = !!ini_section_get_int(cat, "window_maximized", 0); + } else + ms->mon_window_maximized = 0; } /* Load "Machine" section. */ @@ -255,112 +241,29 @@ static void load_machine(void) { ini_section_t cat = ini_find_section(config, "Machine"); - char *p; - char *migrate_from = NULL; + const char *p; + const char *migrate_from = NULL; int c; int i; int j; int speed; - int legacy_mfg; - int legacy_cpu; double multi; p = ini_section_get_string(cat, "machine", NULL); if (p != NULL) { migrate_from = p; - if (!strcmp(p, "8500ttc")) /* migrate typo... */ - machine = machine_get_machine_from_internal_name("8600ttc"); - else if (!strcmp(p, "eagle_pcspirit")) /* ...legacy names... */ - machine = machine_get_machine_from_internal_name("pcspirit"); - else if (!strcmp(p, "multitech_pc700")) - machine = machine_get_machine_from_internal_name("pc700"); - else if (!strcmp(p, "ncr_pc4i")) - machine = machine_get_machine_from_internal_name("pc4i"); - else if (!strcmp(p, "olivetti_m19")) - machine = machine_get_machine_from_internal_name("m19"); - else if (!strcmp(p, "open_xt")) - machine = machine_get_machine_from_internal_name("openxt"); - else if (!strcmp(p, "open_at")) - machine = machine_get_machine_from_internal_name("openat"); - else if (!strcmp(p, "philips_p3105")) - machine = machine_get_machine_from_internal_name("p3105"); - else if (!strcmp(p, "philips_p3120")) - machine = machine_get_machine_from_internal_name("p3120"); - else if (!strcmp(p, "olivetti_m24")) - machine = machine_get_machine_from_internal_name("m24"); - else if (!strcmp(p, "olivetti_m240")) - machine = machine_get_machine_from_internal_name("m240"); - else if (!strcmp(p, "ncr_pc8")) - machine = machine_get_machine_from_internal_name("pc8"); - else if (!strcmp(p, "olivetti_m290")) - machine = machine_get_machine_from_internal_name("m290"); - else if (!strcmp(p, "ncr_3302")) - machine = machine_get_machine_from_internal_name("3302"); - else if (!strcmp(p, "ncr_pc916sx")) - machine = machine_get_machine_from_internal_name("pc916sx"); - else if (!strcmp(p, "cbm_sl386sx16")) - machine = machine_get_machine_from_internal_name("cmdsl386sx16"); - else if (!strcmp(p, "cbm_sl386sx25")) - machine = machine_get_machine_from_internal_name("cmdsl386sx25"); - else if (!strcmp(p, "mr586")) - machine = machine_get_machine_from_internal_name("p54tp4xe_mr"); - else if (!strcmp(p, "pcv240")) - machine = machine_get_machine_from_internal_name("pcv90"); - else if (!strcmp(p, "v60n")) - machine = machine_get_machine_from_internal_name("acerv60n"); - else if (!strcmp(p, "tsunamiatx")) - machine = machine_get_machine_from_internal_name("s1846"); - else if (!strcmp(p, "trinity371")) - machine = machine_get_machine_from_internal_name("s1857"); - else if (!strcmp(p, "63a")) - machine = machine_get_machine_from_internal_name("63a1"); - else if (!strcmp(p, "4sa2")) - machine = machine_get_machine_from_internal_name("4saw2"); - else if (!strcmp(p, "award386dx")) /* ...merged machines... */ - machine = machine_get_machine_from_internal_name("award495"); - else if (!strcmp(p, "ami386dx")) - machine = machine_get_machine_from_internal_name("ami495"); - else if (!strcmp(p, "mr386dx")) - machine = machine_get_machine_from_internal_name("mr495"); - else if (!strcmp(p, "award486")) - machine = machine_get_machine_from_internal_name("award495"); - else if (!strcmp(p, "ami486")) - machine = machine_get_machine_from_internal_name("ami495"); - else if (!strcmp(p, "mr486")) - machine = machine_get_machine_from_internal_name("mr495"); - else if (!strcmp(p, "ibmps1_2121_isa")) - machine = machine_get_machine_from_internal_name("ibmps1_2121"); - else if (!strcmp(p, "fw6400gx_s1")) - machine = machine_get_machine_from_internal_name("fw6400gx"); - else if (!strcmp(p, "p54vl")) - machine = machine_get_machine_from_internal_name("p5vl"); - else if (!strcmp(p, "chariot")) - machine = machine_get_machine_from_internal_name("fmb"); - else if (!strcmp(p, "president")) { /* ...and removed machines */ - machine = machine_get_machine_from_internal_name("mb500n"); - migrate_from = NULL; - } else if (!strcmp(p, "j656vxd")) { - machine = machine_get_machine_from_internal_name("p55va"); - migrate_from = NULL; - } else { + /* Migrate renamed machines. */ + if (!strcmp(p, "430nx")) + machine = machine_get_machine_from_internal_name("586ip"); + else if (!strcmp(p, "586mc1")) + machine = machine_get_machine_from_internal_name("586is"); + else { machine = machine_get_machine_from_internal_name(p); migrate_from = NULL; } } else machine = 0; - /* This is for backwards compatibility. */ - p = ini_section_get_string(cat, "model", NULL); - if (p != NULL) { - migrate_from = p; - if (!strcmp(p, "p55r2p4")) /* migrate typo */ - machine = machine_get_machine_from_internal_name("p55t2p4"); - else { - machine = machine_get_machine_from_internal_name(p); - migrate_from = NULL; - } - ini_section_delete_var(cat, "model"); - } if (machine >= machine_count()) machine = machine_count() - 1; @@ -408,52 +311,15 @@ load_machine(void) cpu_f = NULL; p = ini_section_get_string(cat, "cpu_family", NULL); if (p) { - if (!strcmp(p, "enh_am486dx2")) /* migrate modified names */ - cpu_f = cpu_get_family("am486dx2_slenh"); - else if (!strcmp(p, "enh_am486dx4")) - cpu_f = cpu_get_family("am486dx4_slenh"); + /* Migrate CPU family changes. */ + if ((!strcmp(machines[machine].internal_name, "deskpro386") || + !strcmp(machines[machine].internal_name, "deskpro386_05_1988"))) + cpu_f = cpu_get_family("i386dx_deskpro386"); else cpu_f = cpu_get_family(p); if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */ cpu_f = NULL; - } else { - /* Backwards compatibility with the previous CPU model system. */ - legacy_mfg = ini_section_get_int(cat, "cpu_manufacturer", 0); - legacy_cpu = ini_section_get_int(cat, "cpu", 0); - - /* Check if either legacy ID is present, and if they are within bounds. */ - if (((legacy_mfg > 0) || (legacy_cpu > 0)) && (legacy_mfg >= 0) && (legacy_mfg < 4) && (legacy_cpu >= 0)) { - /* Look for a machine entry on the legacy table. */ - p = machine_get_internal_name(); - c = 0; - while (cpu_legacy_table[c].machine) { - if (!strcmp(p, cpu_legacy_table[c].machine)) - break; - c++; - } - if (cpu_legacy_table[c].machine) { - /* Determine the amount of CPU entries on the table. */ - i = -1; - while (cpu_legacy_table[c].tables[legacy_mfg][++i].family) - ; - - /* If the CPU ID is out of bounds, reset to the last known ID. */ - if (legacy_cpu >= i) - legacy_cpu = i - 1; - - const cpu_legacy_table_t *legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][legacy_cpu]; - - /* Check if the referenced family exists. */ - cpu_f = cpu_get_family(legacy_table_entry->family); - if (cpu_f) { - /* Save the new values. */ - ini_section_set_string(cat, "cpu_family", (char *) legacy_table_entry->family); - ini_section_set_int(cat, "cpu_speed", legacy_table_entry->rspeed); - ini_section_set_double(cat, "cpu_multi", legacy_table_entry->multi); - } - } - } } if (cpu_f) { @@ -465,22 +331,27 @@ load_machine(void) c = 0; i = 256; while (cpu_f->cpus[cpu].cpu_type) { - if (cpu_is_eligible(cpu_f, cpu, machine)) { /* skip ineligible CPUs */ - if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi)) /* exact speed/multiplier match */ + if (cpu_is_eligible(cpu_f, cpu, machine)) { + /* Skip ineligible CPUs. */ + if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi)) + /* Exact speed/multiplier match. */ break; - else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256)) /* closest speed match */ + else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256)) + /* Closest speed match. */ i = cpu; c = cpu; /* store fastest eligible CPU */ } cpu++; } - if (!cpu_f->cpus[cpu].cpu_type) /* if no exact match was found, use closest matching faster CPU, or fastest eligible CPU */ + if (!cpu_f->cpus[cpu].cpu_type) + /* if no exact match was found, use closest matching faster CPU or fastest eligible CPU. */ cpu = MIN(i, c); - } else { /* default */ - /* Find first eligible family. */ + } else { + /* Default, find first eligible family. */ c = 0; while (!cpu_family_is_eligible(&cpu_families[c], machine)) { - if (cpu_families[c++].package == 0) { /* end of list */ + if (cpu_families[c++].package == 0) { + /* End of list. */ fatal("No eligible CPU families for the selected machine\n"); return; } @@ -490,7 +361,8 @@ load_machine(void) /* Find first eligible CPU in that family. */ cpu = 0; while (!cpu_is_eligible(cpu_f, cpu, machine)) { - if (cpu_f->cpus[cpu++].cpu_type == 0) { /* end of list */ + if (cpu_f->cpus[cpu++].cpu_type == 0) { + /* End of list. */ cpu = 0; break; } @@ -500,28 +372,18 @@ load_machine(void) cpu_waitstates = ini_section_get_int(cat, "cpu_waitstates", 0); - p = (char *) ini_section_get_string(cat, "fpu_type", "none"); + p = ini_section_get_string(cat, "fpu_type", "none"); fpu_type = fpu_get_type(cpu_f, cpu, p); mem_size = ini_section_get_int(cat, "mem_size", 64); -#if 0 - if (mem_size < ((machine_has_bus(machine, MACHINE_AT) && - (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) - mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); -#endif if (mem_size > machine_get_max_ram(machine)) mem_size = machine_get_max_ram(machine); cpu_use_dynarec = !!ini_section_get_int(cat, "cpu_use_dynarec", 0); fpu_softfloat = !!ini_section_get_int(cat, "fpu_softfloat", 0); - /*The IBM PS/2 model 70 type 4 BIOS does heavy tests to the FPU in 80-bit precision mode, requiring softfloat - otherwise it would always throw error 12903 on POST, so always disable dynarec and enable softfloat for this - machine only.*/ - if (!strcmp(machines[machine].internal_name, "ibmps2_m70_type4")) { - cpu_use_dynarec = 0; + if ((fpu_type != FPU_NONE) && machine_has_flags(machine, MACHINE_SOFTFLOAT_ONLY)) fpu_softfloat = 1; - } p = ini_section_get_string(cat, "time_sync", NULL); if (p != NULL) { @@ -537,10 +399,6 @@ load_machine(void) time_sync = !!ini_section_get_int(cat, "enable_sync", 1); pit_mode = ini_section_get_int(cat, "pit_mode", -1); - - /* Remove this after a while.. */ - ini_section_delete_var(cat, "nvr_path"); - ini_section_delete_var(cat, "enable_sync"); } /* Load "Video" section. */ @@ -566,17 +424,23 @@ load_video(void) } free_p = 1; } - if (!strcmp(p, "virge375_vbe20_pci")) /* migrate renamed cards */ - gfxcard[0] = video_get_video_from_internal_name("virge385_pci"); - else - gfxcard[0] = video_get_video_from_internal_name(p); + gfxcard[0] = video_get_video_from_internal_name(p); if (free_p) free(p); } + if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) || + video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514) + ini_section_delete_var(cat, "8514a"); + if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_XGA)) || + video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_XGA) + ini_section_delete_var(cat, "xga"); + voodoo_enabled = !!ini_section_get_int(cat, "voodoo", 0); - ibm8514_enabled = !!ini_section_get_int(cat, "8514a", 0); - xga_enabled = !!ini_section_get_int(cat, "xga", 0); + ibm8514_standalone_enabled = !!ini_section_get_int(cat, "8514a", 0); + ibm8514_active = ibm8514_standalone_enabled; + xga_standalone_enabled = !!ini_section_get_int(cat, "xga", 0); + xga_active = xga_standalone_enabled; show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1); video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0); @@ -604,55 +468,45 @@ load_input_devices(void) p = ini_section_get_string(cat, "joystick_type", NULL); if (p != NULL) { - if (!strcmp(p, "standard_2button")) /* migrate renamed types */ - joystick_type = joystick_get_from_internal_name("2axis_2button"); - else if (!strcmp(p, "standard_4button")) - joystick_type = joystick_get_from_internal_name("2axis_4button"); - else if (!strcmp(p, "standard_6button")) - joystick_type = joystick_get_from_internal_name("2axis_6button"); - else if (!strcmp(p, "standard_8button")) - joystick_type = joystick_get_from_internal_name("2axis_8button"); - else if (!strcmp(p, "ch_flighstick_pro")) /* fix typo */ - joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); - else - joystick_type = joystick_get_from_internal_name(p); + joystick_type = joystick_get_from_internal_name(p); if (!joystick_type) { /* Try to read an integer for backwards compatibility with old configs */ - if (!strcmp(p, "0")) /* workaround for ini_section_get_int returning 0 on non-integer data */ + if (!strcmp(p, "0")) + /* Workaround for ini_section_get_int returning 0 on non-integer data */ joystick_type = joystick_get_from_internal_name("2axis_2button"); else { c = ini_section_get_int(cat, "joystick_type", 8); switch (c) { - case 1: + case JS_TYPE_2AXIS_4BUTTON: joystick_type = joystick_get_from_internal_name("2axis_4button"); break; - case 2: + case JS_TYPE_2AXIS_6BUTTON: joystick_type = joystick_get_from_internal_name("2axis_6button"); break; - case 3: + case JS_TYPE_2AXIS_8BUTTON: joystick_type = joystick_get_from_internal_name("2axis_8button"); break; - case 4: + case JS_TYPE_4AXIS_4BUTTON: joystick_type = joystick_get_from_internal_name("4axis_4button"); break; - case 5: + case JS_TYPE_CH_FLIGHTSTICK_PRO: joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); break; - case 6: + case JS_TYPE_SIDEWINDER_PAD: joystick_type = joystick_get_from_internal_name("sidewinder_pad"); break; - case 7: + case JS_TYPE_THRUSTMASTER_FCS: joystick_type = joystick_get_from_internal_name("thrustmaster_fcs"); break; default: - joystick_type = 0; + joystick_type = JS_TYPE_NONE; break; } } } } else - joystick_type = 0; + joystick_type = JS_TYPE_NONE; for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { sprintf(temp, "joystick_%i_nr", c); @@ -671,7 +525,8 @@ load_input_devices(void) sprintf(temp, "joystick_%i_pov_%i", c, d); p = ini_section_get_string(cat, temp, "0, 0"); joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0; - sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], &joystick_state[c].pov_mapping[d][1]); + sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], + &joystick_state[c].pov_mapping[d][1]); } } } @@ -778,50 +633,46 @@ load_sound(void) static void load_network(void) { - ini_section_t cat = ini_find_section(config, "Network"); - char *p; - char temp[512]; - uint16_t c = 0; - uint16_t min = 0; + ini_section_t cat = ini_find_section(config, "Network"); + char * p; + char temp[512]; + uint16_t c = 0; + uint16_t min = 0; + netcard_conf_t *nc = &net_cards_conf[c]; /* Handle legacy configuration which supported only one NIC */ p = ini_section_get_string(cat, "net_card", NULL); if (p != NULL) { - net_cards_conf[c].device_num = network_card_get_from_internal_name(p); + nc->device_num = network_card_get_from_internal_name(p); p = ini_section_get_string(cat, "net_type", NULL); if (p != NULL) { if (!strcmp(p, "pcap") || !strcmp(p, "1")) - net_cards_conf[c].net_type = NET_TYPE_PCAP; + nc->net_type = NET_TYPE_PCAP; else if (!strcmp(p, "slirp") || !strcmp(p, "2")) - net_cards_conf[c].net_type = NET_TYPE_SLIRP; + nc->net_type = NET_TYPE_SLIRP; else if (!strcmp(p, "vde") || !strcmp(p, "2")) - net_cards_conf[c].net_type = NET_TYPE_VDE; + nc->net_type = NET_TYPE_VDE; else - net_cards_conf[c].net_type = NET_TYPE_NONE; - } else { - net_cards_conf[c].net_type = NET_TYPE_NONE; - } + nc->net_type = NET_TYPE_NONE; + } else + nc->net_type = NET_TYPE_NONE; p = ini_section_get_string(cat, "net_host_device", NULL); if (p != NULL) { - if (net_cards_conf[c].net_type == NET_TYPE_PCAP) { + if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if (network_ndev == 1) { + if (network_ndev == 1) ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); - } else if (network_dev_to_id(p) == -1) { + else if (network_dev_to_id(p) == -1) ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); - } - strcpy(net_cards_conf[c].host_dev_name, "none"); - } else { - strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1); - } - } else { - strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1); - } - } else { - strcpy(net_cards_conf[c].host_dev_name, "none"); - } + strcpy(nc->host_dev_name, "none"); + } else + strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); + } else + strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); + } else + strcpy(nc->host_dev_name, "none"); min++; } @@ -831,54 +682,50 @@ load_network(void) ini_section_delete_var(cat, "net_host_device"); for (c = min; c < NET_CARD_MAX; c++) { + nc = &net_cards_conf[c]; sprintf(temp, "net_%02i_card", c + 1); p = ini_section_get_string(cat, temp, NULL); - if (p != NULL) { - net_cards_conf[c].device_num = network_card_get_from_internal_name(p); - } else { - net_cards_conf[c].device_num = 0; - } + if (p != NULL) + nc->device_num = network_card_get_from_internal_name(p); + else + nc->device_num = 0; sprintf(temp, "net_%02i_net_type", c + 1); p = ini_section_get_string(cat, temp, NULL); if (p != NULL) { - if (!strcmp(p, "pcap") || !strcmp(p, "1")) { - net_cards_conf[c].net_type = NET_TYPE_PCAP; - } else if (!strcmp(p, "slirp") || !strcmp(p, "2")) { - net_cards_conf[c].net_type = NET_TYPE_SLIRP; - } else if (!strcmp(p, "vde") || !strcmp(p, "2")) { - net_cards_conf[c].net_type = NET_TYPE_VDE; - } else { - net_cards_conf[c].net_type = NET_TYPE_NONE; - } - } else { - net_cards_conf[c].net_type = NET_TYPE_NONE; - } + if (!strcmp(p, "pcap") || !strcmp(p, "1")) + nc->net_type = NET_TYPE_PCAP; + else if (!strcmp(p, "slirp") || !strcmp(p, "2")) + nc->net_type = NET_TYPE_SLIRP; + else if (!strcmp(p, "vde") || !strcmp(p, "2")) + nc->net_type = NET_TYPE_VDE; + else + nc->net_type = NET_TYPE_NONE; + } else + nc->net_type = NET_TYPE_NONE; sprintf(temp, "net_%02i_host_device", c + 1); p = ini_section_get_string(cat, temp, NULL); if (p != NULL) { - if (net_cards_conf[c].net_type == NET_TYPE_PCAP) { + if (nc->net_type == NET_TYPE_PCAP) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if (network_ndev == 1) { + if (network_ndev == 1) ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130); - } else if (network_dev_to_id(p) == -1) { + else if (network_dev_to_id(p) == -1) ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130); - } - strcpy(net_cards_conf[c].host_dev_name, "none"); - } else { - strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1); - } - } else { - strncpy(net_cards_conf[c].host_dev_name, p, sizeof(net_cards_conf[c].host_dev_name) - 1); - } - } else { - strcpy(net_cards_conf[c].host_dev_name, "none"); - } + strcpy(nc->host_dev_name, "none"); + } else + strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); + } else + strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1); + } else + strcpy(nc->host_dev_name, "none"); sprintf(temp, "net_%02i_link", c + 1); - net_cards_conf[c].link_state = ini_section_get_int(cat, temp, - (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)); + nc->link_state = ini_section_get_int(cat, temp, + (NET_LINK_10_HD | NET_LINK_10_FD | + NET_LINK_100_HD | NET_LINK_100_FD | + NET_LINK_1000_HD | NET_LINK_1000_FD)); } } @@ -898,12 +745,6 @@ load_ports(void) sprintf(temp, "serial%d_enabled", c + 1); com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1); - /* - sprintf(temp, "serial%d_device", c + 1); - p = (char *) ini_section_get_string(cat, temp, "none"); - com_ports[c].device = com_device_get_from_internal_name(p); - */ - sprintf(temp, "serial%d_passthrough_enabled", c + 1); serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0); @@ -916,7 +757,7 @@ load_ports(void) lpt_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0); sprintf(temp, "lpt%d_device", c + 1); - p = (char *) ini_section_get_string(cat, temp, "none"); + p = ini_section_get_string(cat, temp, "none"); lpt_ports[c].device = lpt_device_get_from_internal_name(p); } @@ -934,23 +775,13 @@ static void load_storage_controllers(void) { ini_section_t cat = ini_find_section(config, "Storage controllers"); + ini_section_t migration_cat; char *p; char temp[512]; int c; int min = 0; int free_p = 0; - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - backwards_compat2 = (cat == NULL); - - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - p = ini_section_get_string(cat, "scsicard", NULL); - if (p != NULL) { - scsi_card_current[0] = scsi_card_get_from_internal_name(p); - min++; - } - ini_section_delete_var(cat, "scsi_card"); - for (c = min; c < SCSI_BUS_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); @@ -978,17 +809,16 @@ load_storage_controllers(void) } free_p = 1; } - if (!strcmp(p, "mfm_xt")) - hdc_current = hdc_get_from_internal_name("st506_xt"); - else if (!strcmp(p, "mfm_xt_dtc5150x")) - hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); - else if (!strcmp(p, "mfm_at")) - hdc_current = hdc_get_from_internal_name("st506_at"); - else if (!strcmp(p, "vlb_isa")) - hdc_current = hdc_get_from_internal_name("ide_vlb"); - else if (!strcmp(p, "vlb_isa_2ch")) - hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); - else + /* Migrate renamed and merged cards. */ + if (!strcmp(p, "xtide_plus")) { + hdc_current = hdc_get_from_internal_name("xtide"); + migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE"); + ini_section_set_string(migration_cat, "bios", "xt_plus"); + } else if (!strcmp(p, "xtide_at_386")) { + hdc_current = hdc_get_from_internal_name("xtide_at"); + migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE"); + ini_section_set_string(migration_cat, "bios", "at_386"); + } else hdc_current = hdc_get_from_internal_name(p); if (free_p) { @@ -1008,9 +838,11 @@ load_storage_controllers(void) ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0); ide_qua_enabled = !!ini_section_get_int(cat, "ide_qua", 0); - /* TODO: Re-enable by default after we actually have a proper machine flag for this. */ - cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0); - p = ini_section_get_string(cat, "cassette_file", ""); + if (machine_has_bus(machine, MACHINE_BUS_CASSETTE)) + cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0); + else + cassette_enable = 0; + p = ini_section_get_string(cat, "cassette_file", ""); if (strlen(p) > 511) fatal("load_storage_controllers(): strlen(p) > 511\n"); else @@ -1030,27 +862,19 @@ load_storage_controllers(void) sprintf(temp, "cartridge_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c])); - } else -#endif - if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); - else - strncpy(cart_fns[c], p, 511); + if (!strcmp(p, usr_path)) + p[0] = 0x00; + + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c); + else + strncpy(cart_fns[c], p, 511); + } else + path_append_filename(cart_fns[c], usr_path, p); + path_normalize(cart_fns[c]); + } } } @@ -1078,8 +902,8 @@ load_hard_disks(void) hdd[c].bus = hdd_string_to_bus(s, 0); switch (hdd[c].bus) { - case HDD_BUS_DISABLED: default: + case HDD_BUS_DISABLED: max_spt = max_hpc = max_tracks = 0; break; @@ -1108,6 +932,7 @@ load_hard_disks(void) break; case HDD_BUS_SCSI: + case HDD_BUS_ATAPI: max_spt = 255; max_hpc = 255; max_tracks = 266305; @@ -1125,6 +950,8 @@ load_hard_disks(void) switch (hdd[c].bus) { case HDD_BUS_IDE: case HDD_BUS_ESDI: + case HDD_BUS_ATAPI: + case HDD_BUS_SCSI: sprintf(tmp2, "1997_5400rpm"); break; default: @@ -1157,7 +984,7 @@ load_hard_disks(void) /* IDE */ sprintf(temp, "hdd_%02i_ide_channel", c + 1); - if (hdd[c].bus == HDD_BUS_IDE) { + if ((hdd[c].bus == HDD_BUS_IDE) || (hdd[c].bus == HDD_BUS_ATAPI)) { sprintf(tmp2, "%01u:%01u", c >> 1, c & 1); p = ini_section_get_string(cat, temp, tmp2); sscanf(p, "%01u:%01u", &board, &dev); @@ -1201,34 +1028,24 @@ load_hard_disks(void) sprintf(temp, "hdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - /* - * ANOTHER NOTE: - * When loading differencing VHDs, the absolute path is required. - * So we should not convert absolute paths to relative. -sards - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { /* - * Yep, its absolute and prefixed - * with the CFG path. Just strip - * that off for now... + * NOTE: + * When loading differencing VHDs, the absolute path is required. + * So we should not convert absolute paths to relative. -sards */ - wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); - } else -#endif - if (path_abs(p)) { - strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1); - } else { - path_append_filename(hdd[c].fn, usr_path, p); + if (!strcmp(p, usr_path)) + p[0] = 0x00; + + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c); + else + strncpy(hdd[c].fn, p, 511); + } else + path_append_filename(hdd[c].fn, usr_path, p); + path_normalize(hdd[c].fn); } - path_normalize(hdd[c].fn); sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1); hdd[c].vhd_blocksize = ini_section_get_int(cat, temp, 0); @@ -1263,68 +1080,6 @@ load_hard_disks(void) } } -/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ -/* Load "Floppy Drives" section. */ -static void -load_floppy_drives(void) -{ - ini_section_t cat = ini_find_section(config, "Floppy drives"); - char temp[512]; - char *p; - - if (!backwards_compat) - return; - - for (uint8_t c = 0; c < FDD_NUM; c++) { - sprintf(temp, "fdd_%02i_type", c + 1); - p = ini_section_get_string(cat, temp, (c < 2) ? "525_2dd" : "none"); - fdd_set_type(c, fdd_get_from_internal_name(p)); - if (fdd_get_type(c) > 13) - fdd_set_type(c, 13); - ini_section_delete_var(cat, temp); - - sprintf(temp, "fdd_%02i_fn", c + 1); - p = ini_section_get_string(cat, temp, ""); - ini_section_delete_var(cat, temp); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else -#endif - if (strlen(p) > 511) - fatal("load_floppy_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, 511); - - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ - sprintf(temp, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); - ini_section_delete_var(cat, temp); - sprintf(temp, "fdd_%02i_turbo", c + 1); - fdd_set_turbo(c, !!ini_section_get_int(cat, temp, 0)); - ini_section_delete_var(cat, temp); - sprintf(temp, "fdd_%02i_check_bpb", c + 1); - fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1)); - ini_section_delete_var(cat, temp); - } - - ini_delete_section_if_empty(config, cat); -} - /* Load "Floppy and CD-ROM Drives" section. */ static void load_floppy_and_cdrom_drives(void) @@ -1339,9 +1094,6 @@ load_floppy_and_cdrom_drives(void) int c; int d = 0; - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - backwards_compat = (cat == NULL); - memset(temp, 0x00, sizeof(temp)); for (c = 0; c < FDD_NUM; c++) { sprintf(temp, "fdd_%02i_type", c + 1); @@ -1353,30 +1105,24 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else -#endif - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, 511); + if (!strcmp(p, usr_path)) + p[0] = 0x00; - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c); + else + strncpy(floppyfns[c], p, 511); + } else + path_append_filename(floppyfns[c], usr_path, p); + path_normalize(floppyfns[c]); + } + +#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) + if (*p != '\0') + config_log("Floppy%d: %ls\n", c, floppyfns[c]); +#endif sprintf(temp, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); sprintf(temp, "fdd_%02i_turbo", c + 1); @@ -1384,7 +1130,8 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_check_bpb", c + 1); fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1)); - /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ + /* Check whether each value is default, if yes, delete it so that only + non-default values will later be saved. */ if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) { sprintf(temp, "fdd_%02i_type", c + 1); ini_section_delete_var(cat, temp); @@ -1406,11 +1153,20 @@ load_floppy_and_cdrom_drives(void) ini_section_delete_var(cat, temp); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { - fdd_image_history[c][i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); + fdd_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - sprintf(fdd_image_history[c][i], "%s", p); + if (path_abs(p)) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " + "(fdd_image_history[%i][%i])\n", c, i); + else + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); + } else + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(fdd_image_history[c][i]); } } } @@ -1492,24 +1248,19 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); - } else -#endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); + if (!strcmp(p, usr_path)) + p[0] = 0x00; + + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c); + else + strncpy(cdrom[c].image_path, p, 511); + } else + path_append_filename(cdrom[c].image_path, usr_path, p); + path_normalize(cdrom[c].image_path); + } if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) cdrom[c].host_drive = 0; @@ -1517,6 +1268,24 @@ load_floppy_and_cdrom_drives(void) if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) cdrom[c].host_drive = 0; + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + cdrom[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " + "(cdrom[%i].image_history[%i])\n", c, i); + else + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); + } else + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(cdrom[c].image_history[i]); + } + } + /* If the CD-ROM is disabled, delete all its variables. */ if (cdrom[c].bus_type == CDROM_BUS_DISABLED) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); @@ -1533,19 +1302,15 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } } sprintf(temp, "cdrom_%02i_iso_path", c + 1); ini_section_delete_var(cat, temp); - - for (int i = 0; i < MAX_PREV_IMAGES; i++) { - cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); - sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); - p = ini_section_get_string(cat, temp, NULL); - if (p) { - sprintf(cdrom[c].image_history[i], "%s", p); - } - } } } @@ -1561,89 +1326,6 @@ load_other_removable_devices(void) unsigned int board = 0; unsigned int dev = 0; int c; - int d = 0; - - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - if (backwards_compat) { - memset(temp, 0x00, sizeof(temp)); - for (c = 0; c < CDROM_NUM; c++) { - sprintf(temp, "cdrom_%02i_host_drive", c + 1); - cdrom[c].host_drive = ini_section_get_int(cat, temp, 0); - cdrom[c].prev_host_drive = cdrom[c].host_drive; - ini_section_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_parameters", c + 1); - p = ini_section_get_string(cat, temp, NULL); - if (p != NULL) - sscanf(p, "%01u, %s", &d, s); - else - sscanf("0, none", "%01u, %s", &d, s); - cdrom[c].sound_on = d; - cdrom[c].bus_type = hdd_string_to_bus(s, 1); - ini_section_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_speed", c + 1); - cdrom[c].speed = ini_section_get_int(cat, temp, 8); - ini_section_delete_var(cat, temp); - - /* Default values, needed for proper operation of the Settings dialog. */ - cdrom[c].ide_channel = cdrom[c].scsi_device_id = c + 2; - ini_section_delete_var(cat, temp); - - if (cdrom[c].bus_type == CDROM_BUS_ATAPI) { - sprintf(temp, "cdrom_%02i_ide_channel", c + 1); - sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); - p = ini_section_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - cdrom[c].ide_channel = (board << 1) + dev; - - if (cdrom[c].ide_channel > 7) - cdrom[c].ide_channel = 7; - - ini_section_delete_var(cat, temp); - } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { - sprintf(temp, "cdrom_%02i_scsi_id", c + 1); - cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2); - - if (cdrom[c].scsi_device_id > 15) - cdrom[c].scsi_device_id = 15; - - ini_section_delete_var(cat, temp); - } - - sprintf(temp, "cdrom_%02i_image_path", c + 1); - p = ini_section_get_string(cat, temp, ""); - ini_section_delete_var(cat, temp); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); - } else -#endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); - - if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) - cdrom[c].host_drive = 0; - - if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) - cdrom[c].host_drive = 0; - } - } - backwards_compat = 0; memset(temp, 0x00, sizeof(temp)); for (c = 0; c < ZIP_NUM; c++) { @@ -1704,26 +1386,40 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); - } else -#endif - strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1); + if (!strcmp(p, usr_path)) + p[0] = 0x00; - /* If the CD-ROM is disabled, delete all its variables. */ + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n", + c); + else + strncpy(zip_drives[c].image_path, p, 511); + } else + path_append_filename(zip_drives[c].image_path, usr_path, p); + path_normalize(zip_drives[c].image_path); + } + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + zip_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " + "(zip_drives[%i].image_history[%i])\n", c, i); + else + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); + } else + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(zip_drives[c].image_history[i]); + } + } + + /* If the ZIP drive is disabled, delete all its variables. */ if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { sprintf(temp, "zip_%02i_host_drive", c + 1); ini_section_delete_var(cat, temp); @@ -1739,10 +1435,12 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); - } - sprintf(temp, "zip_%02i_iso_path", c + 1); - ini_section_delete_var(cat, temp); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } + } } memset(temp, 0x00, sizeof(temp)); @@ -1804,9 +1502,40 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); - strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1); + if (!strcmp(p, usr_path)) + p[0] = 0x00; - /* If the CD-ROM is disabled, delete all its variables. */ + if (p[0] != 0x00) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n", + c); + else + strncpy(mo_drives[c].image_path, p, 511); + } else + path_append_filename(mo_drives[c].image_path, usr_path, p); + path_normalize(mo_drives[c].image_path); + } + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + mo_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " + "(mo_drives[%i].image_history[%i])\n", c, i); + else + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); + } else + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(mo_drives[c].image_history[i]); + } + } + + /* If the MO drive is disabled, delete all its variables. */ if (mo_drives[c].bus_type == MO_BUS_DISABLED) { sprintf(temp, "mo_%02i_host_drive", c + 1); ini_section_delete_var(cat, temp); @@ -1822,10 +1551,12 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); - } - sprintf(temp, "mo_%02i_iso_path", c + 1); - ini_section_delete_var(cat, temp); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } + } } } @@ -1836,62 +1567,10 @@ load_other_peripherals(void) ini_section_t cat = ini_find_section(config, "Other peripherals"); char *p; char temp[512]; - int free_p = 0; - - if (backwards_compat2) { - p = ini_section_get_string(cat, "scsicard", NULL); - if (p != NULL) - scsi_card_current[0] = scsi_card_get_from_internal_name(p); - else - scsi_card_current[0] = 0; - ini_section_delete_var(cat, "scsicard"); - - p = ini_section_get_string(cat, "fdc", NULL); - if (p != NULL) - fdc_type = fdc_card_get_from_internal_name(p); - else - fdc_type = FDC_INTERNAL; - ini_section_delete_var(cat, "fdc"); - - p = ini_section_get_string(cat, "hdc", NULL); - if (p == NULL) { - if (machine_has_flags(machine, MACHINE_HDC)) { - p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *) malloc((strlen("none") + 1) * sizeof(char)); - strcpy(p, "none"); - } - free_p = 1; - } - if (!strcmp(p, "mfm_xt")) - hdc_current = hdc_get_from_internal_name("st506_xt"); - else if (!strcmp(p, "mfm_xt_dtc5150x")) - hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); - else if (!strcmp(p, "mfm_at")) - hdc_current = hdc_get_from_internal_name("st506_at"); - else if (!strcmp(p, "vlb_isa")) - hdc_current = hdc_get_from_internal_name("ide_vlb"); - else if (!strcmp(p, "vlb_isa_2ch")) - hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); - else - hdc_current = hdc_get_from_internal_name(p); - ini_section_delete_var(cat, "hdc"); - - if (free_p) { - free(p); - p = NULL; - } - - ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0); - ini_section_delete_var(cat, "ide_ter"); - ide_qua_enabled = !!ini_section_get_int(cat, "ide_qua", 0); - ini_section_delete_var(cat, "ide_qua"); - } - backwards_compat2 = 0; - bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); - postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0); + postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0); + unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -1908,7 +1587,8 @@ load_other_peripherals(void) void config_load(void) { - int i; + int i; + ini_section_t c; config_log("Loading config file '%s'..\n", cfg_path); @@ -1934,6 +1614,7 @@ config_load(void) scale = 1; machine = machine_get_machine_from_internal_name("ibmpc"); dpi_scale = 1; + do_auto_pause = 0; fpu_type = fpu_get_type(cpu_f, cpu, "none"); gfxcard[0] = video_get_video_from_internal_name("cga"); @@ -1971,8 +1652,7 @@ config_load(void) for (i = 0; i < ISAMEM_MAX; i++) isamem_type[i] = 0; - /* TODO: Re-enable by default when we have a proper machine flag for this. */ - cassette_enable = 0; + cassette_enable = 1; memset(cassette_fname, 0x00, sizeof(cassette_fname)); memcpy(cassette_mode, "load", strlen("load") + 1); cassette_pos = 0; @@ -1983,9 +1663,9 @@ config_load(void) config_log("Config file not present or invalid!\n"); } else { - load_general(); /* General */ + load_general(); /* General */ for (i = 0; i < MONITORS_NUM; i++) - load_monitor(i); + load_monitor(i); /* Monitors */ load_machine(); /* Machine */ load_video(); /* Video */ load_input_devices(); /* Input devices */ @@ -1995,11 +1675,26 @@ config_load(void) load_storage_controllers(); /* Storage controllers */ load_hard_disks(); /* Hard disks */ load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - load_floppy_drives(); /* Floppy drives */ load_other_removable_devices(); /* Other removable devices */ load_other_peripherals(); /* Other peripherals */ + /* Migrate renamed device configurations. */ + c = ini_find_section(config, "MDA"); + if (c != NULL) + ini_rename_section(c, "IBM MDA"); + c = ini_find_section(config, "CGA"); + if (c != NULL) + ini_rename_section(c, "IBM CGA"); + c = ini_find_section(config, "EGA"); + if (c != NULL) + ini_rename_section(c, "IBM EGA"); + c = ini_find_section(config, "3DFX Voodoo Graphics"); + if (c != NULL) + ini_rename_section(c, "3Dfx Voodoo Graphics"); + c = ini_find_section(config, "3dfx Voodoo Banshee"); + if (c != NULL) + ini_rename_section(c, "3Dfx Voodoo Banshee"); + /* Mark the configuration as changed. */ config_changed = 1; @@ -2017,7 +1712,7 @@ save_general(void) char temp[512]; char buffer[512] = { 0 }; - char *va_name; + const char *va_name = NULL; ini_section_set_int(cat, "vid_resize", vid_resize); if (vid_resize == 0) @@ -2089,12 +1784,9 @@ save_general(void) else ini_section_set_int(cat, "update_icons", update_icons); - if (window_remember || (vid_resize & 2)) { - if (window_remember) - ini_section_set_int(cat, "window_remember", window_remember); - else - ini_section_delete_var(cat, "window_remember"); - } else + if (window_remember) + ini_section_set_int(cat, "window_remember", window_remember); + else ini_section_delete_var(cat, "window_remember"); if (vid_resize & 2) { @@ -2178,6 +1870,11 @@ save_general(void) else ini_section_delete_var(cat, "video_gl_shader"); + if (do_auto_pause) + ini_section_set_int(cat, "do_auto_pause", do_auto_pause); + else + ini_section_delete_var(cat, "do_auto_pause"); + ini_delete_section_if_empty(config, cat); } @@ -2185,24 +1882,23 @@ save_general(void) static void save_monitor(int monitor_index) { - ini_section_t cat; - char name[sizeof("Monitor #") + 12] = { [0] = 0 }; - char temp[512]; + ini_section_t cat; + char name[sizeof("Monitor #") + 12] = { [0] = 0 }; + char temp[512]; + monitor_settings_t *ms = &monitor_settings[monitor_index]; snprintf(name, sizeof(name), "Monitor #%i", monitor_index + 1); cat = ini_find_or_create_section(config, name); if (window_remember) { - sprintf(temp, "%i, %i, %i, %i", - monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h); + sprintf(temp, "%i, %i, %i, %i", ms->mon_window_x, ms->mon_window_y, + ms->mon_window_w, ms->mon_window_h); ini_section_set_string(cat, "window_coordinates", temp); - if (monitor_settings[monitor_index].mon_window_maximized != 0) { - ini_section_set_int(cat, "window_maximized", monitor_settings[monitor_index].mon_window_maximized); - } else { + if (ms->mon_window_maximized != 0) + ini_section_set_int(cat, "window_maximized", ms->mon_window_maximized); + else ini_section_delete_var(cat, "window_maximized"); - } } else { ini_section_delete_var(cat, "window_coordinates"); ini_section_delete_var(cat, "window_maximized"); @@ -2216,18 +1912,13 @@ static void save_machine(void) { ini_section_t cat = ini_find_or_create_section(config, "Machine"); - char *p; - int c; - int i = 0; - int legacy_mfg; - int legacy_cpu = -1; - int closest_legacy_cpu = -1; + const char *p; p = machine_get_internal_name(); ini_section_set_string(cat, "machine", p); - ini_section_set_string(cat, "cpu_family", (char *) cpu_f->internal_name); - ini_section_set_int(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed); + ini_section_set_string(cat, "cpu_family", cpu_f->internal_name); + ini_section_set_uint(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed); ini_section_set_double(cat, "cpu_multi", cpu_f->cpus[cpu].multi); if (cpu_override) ini_section_set_int(cat, "cpu_override", cpu_override); @@ -2238,54 +1929,6 @@ save_machine(void) ini_section_delete_var(cat, "cpu_manufacturer"); ini_section_delete_var(cat, "cpu"); - /* Look for a machine entry on the legacy table. */ - c = 0; - while (cpu_legacy_table[c].machine) { - if (!strcmp(p, cpu_legacy_table[c].machine)) - break; - c++; - } - if (cpu_legacy_table[c].machine) { - /* Look for a corresponding CPU entry. */ - cpu_legacy_table_t *legacy_table_entry; - for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) { - if (!cpu_legacy_table[c].tables[legacy_mfg]) - continue; - - i = 0; - while (cpu_legacy_table[c].tables[legacy_mfg][i].family) { - legacy_table_entry = (cpu_legacy_table_t *) &cpu_legacy_table[c].tables[legacy_mfg][i]; - - /* Match the family name, speed and multiplier. */ - if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) { - if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) && (legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) { /* exact speed/multiplier match */ - legacy_cpu = i; - break; - } else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) && (closest_legacy_cpu == -1)) { /* closest speed match */ - closest_legacy_cpu = i; - } - } - - i++; - } - - /* Use the closest speed match if no exact match was found. */ - if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) { - legacy_cpu = closest_legacy_cpu; - break; - } else if (legacy_cpu > -1) /* exact match found */ - break; - } - - /* Set legacy values if a match was found. */ - if (legacy_cpu > -1) { - if (legacy_mfg) - ini_section_set_int(cat, "cpu_manufacturer", legacy_mfg); - if (legacy_cpu) - ini_section_set_int(cat, "cpu", legacy_cpu); - } - } - if (cpu_waitstates == 0) ini_section_delete_var(cat, "cpu_waitstates"); else @@ -2294,9 +1937,10 @@ save_machine(void) if (fpu_type == 0) ini_section_delete_var(cat, "fpu_type"); else - ini_section_set_string(cat, "fpu_type", (char *) fpu_get_internal_name(cpu_f, cpu, fpu_type)); + ini_section_set_string(cat, "fpu_type", fpu_get_internal_name(cpu_f, cpu, fpu_type)); - // Write the mem_size explicitly to the setttings in order to help managers to display it without having the actual machine table + /* Write the mem_size explicitly to the setttings in order to help managers + to display it without having the actual machine table. */ ini_section_delete_var(cat, "mem_size"); ini_section_set_int(cat, "mem_size", mem_size); @@ -2333,15 +1977,15 @@ save_video(void) else ini_section_set_int(cat, "voodoo", voodoo_enabled); - if (ibm8514_enabled == 0) + if (ibm8514_standalone_enabled == 0) ini_section_delete_var(cat, "8514a"); else - ini_section_set_int(cat, "8514a", ibm8514_enabled); + ini_section_set_int(cat, "8514a", ibm8514_standalone_enabled); - if (xga_enabled == 0) + if (xga_standalone_enabled == 0) ini_section_delete_var(cat, "xga"); else - ini_section_set_int(cat, "xga", xga_enabled); + ini_section_set_int(cat, "xga", xga_standalone_enabled); if (gfxcard[1] == 0) ini_section_delete_var(cat, "gfxcard_2"); @@ -2503,23 +2147,25 @@ save_sound(void) static void save_network(void) { - char temp[512]; - ini_section_t cat = ini_find_or_create_section(config, "Network"); + char temp[512]; + ini_section_t cat = ini_find_or_create_section(config, "Network"); + netcard_conf_t *nc; ini_section_delete_var(cat, "net_type"); ini_section_delete_var(cat, "net_host_device"); ini_section_delete_var(cat, "net_card"); for (uint8_t c = 0; c < NET_CARD_MAX; c++) { + nc = &net_cards_conf[c]; + sprintf(temp, "net_%02i_card", c + 1); - if (net_cards_conf[c].device_num == 0) { + if (nc->device_num == 0) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, network_card_get_internal_name(net_cards_conf[c].device_num)); - } + else + ini_section_set_string(cat, temp, network_card_get_internal_name(nc->device_num)); sprintf(temp, "net_%02i_net_type", c + 1); - switch(net_cards_conf[c].net_type) { + switch(nc->net_type) { case NET_TYPE_NONE: ini_section_delete_var(cat, temp); break; @@ -2532,25 +2178,27 @@ save_network(void) case NET_TYPE_VDE: ini_section_set_string(cat, temp, "vde"); break; + + default: + break; } sprintf(temp, "net_%02i_host_device", c + 1); - if (net_cards_conf[c].host_dev_name[0] != '\0') { - if (!strcmp(net_cards_conf[c].host_dev_name, "none")) + if (nc->host_dev_name[0] != '\0') { + if (!strcmp(nc->host_dev_name, "none")) ini_section_delete_var(cat, temp); else - ini_section_set_string(cat, temp, net_cards_conf[c].host_dev_name); - } else { - /* ini_section_set_string(cat, temp, "none"); */ + ini_section_set_string(cat, temp, nc->host_dev_name); + } else ini_section_delete_var(cat, temp); - } sprintf(temp, "net_%02i_link", c + 1); - if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)) { + if (nc->link_state == (NET_LINK_10_HD | NET_LINK_10_FD | + NET_LINK_100_HD | NET_LINK_100_FD | + NET_LINK_1000_HD | NET_LINK_1000_FD)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_int(cat, temp, net_cards_conf[c].link_state); - } + else + ini_section_set_int(cat, temp, nc->link_state); } ini_delete_section_if_empty(config, cat); @@ -2572,21 +2220,6 @@ save_ports(void) else ini_section_set_int(cat, temp, com_ports[c].enabled); - /* - sprintf(temp, "serial%d_type", c + 1); - if (!com_ports[c].enabled)) - ini_section_delete_var(cat, temp); - // else - // ini_section_set_string(cat, temp, (char *) serial_type[c]) - - sprintf(temp, "serial%d_device", c + 1); - if (com_ports[c].device == 0) - ini_section_delete_var(cat, temp); - else - ini_section_set_string(cat, temp, - (char *) com_device_get_internal_name(com_ports[c].device)); - */ - sprintf(temp, "serial%d_passthrough_enabled", c + 1); if (serial_passthrough_enabled[c]) { ini_section_set_int(cat, temp, 1); @@ -2608,7 +2241,7 @@ save_ports(void) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, - (char *) lpt_device_get_internal_name(lpt_ports[c].device)); + lpt_device_get_internal_name(lpt_ports[c].device)); } ini_delete_section_if_empty(config, cat); @@ -2727,13 +2360,18 @@ save_other_peripherals(void) else ini_section_set_int(cat, "postcard_enabled", postcard_enabled); + if (unittester_enabled == 0) + ini_section_delete_var(cat, "unittester_enabled"); + else + ini_section_set_int(cat, "unittester_enabled", unittester_enabled); + for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, - (char *) isamem_get_internal_name(isamem_type[c])); + isamem_get_internal_name(isamem_type[c])); } if (isartc_type == 0) @@ -2785,9 +2423,9 @@ save_hard_disks(void) ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_ide_channel", c + 1); - if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE)) { + if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE) && (hdd[c].bus != HDD_BUS_ATAPI))) ini_section_delete_var(cat, temp); - } else { + else { sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1); ini_section_set_string(cat, temp, tmp2); } @@ -2828,10 +2466,11 @@ save_hard_disks(void) ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_speed", c + 1); - if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE && hdd[c].bus != HDD_BUS_ESDI)) + if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_ESDI) && (hdd[c].bus != HDD_BUS_IDE) && + (hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_ATAPI))) ini_section_delete_var(cat, temp); else - ini_section_set_string(cat, temp, (char *) hdd_preset_get_internal_name(hdd[c].speed_preset)); + ini_section_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset)); } ini_delete_section_if_empty(config, cat); @@ -2863,7 +2502,11 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_writeprot", c + 1); ini_section_delete_var(cat, temp); } else { - ini_section_set_string(cat, temp, floppyfns[c]); + path_normalize(floppyfns[c]); + if (!strnicmp(floppyfns[c], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &floppyfns[c][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, floppyfns[c]); } sprintf(temp, "fdd_%02i_writeprot", c + 1); @@ -2886,48 +2529,47 @@ save_floppy_and_cdrom_drives(void) for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); - if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) { + if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, fdd_image_history[c][i]); + else { + path_normalize(fdd_image_history[c][i]); + if (!strnicmp(fdd_image_history[c][i], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &fdd_image_history[c][i][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, fdd_image_history[c][i]); } } } for (c = 0; c < CDROM_NUM; c++) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); - if ((cdrom[c].bus_type == 0) || (cdrom[c].host_drive != 200)) { + if ((cdrom[c].bus_type == 0) || (cdrom[c].host_drive != 200)) ini_section_delete_var(cat, temp); - } else { + else ini_section_set_int(cat, temp, cdrom[c].host_drive); - } sprintf(temp, "cdrom_%02i_speed", c + 1); - if ((cdrom[c].bus_type == 0) || (cdrom[c].speed == 8)) { + if ((cdrom[c].bus_type == 0) || (cdrom[c].speed == 8)) ini_section_delete_var(cat, temp); - } else { + else ini_section_set_int(cat, temp, cdrom[c].speed); - } sprintf(temp, "cdrom_%02i_type", c + 1); - if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI)) { + if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI)) ini_section_delete_var(cat, temp); - } else { + else ini_section_set_string(cat, temp, cdrom_get_internal_name(cdrom_get_type(c))); - } sprintf(temp, "cdrom_%02i_parameters", c + 1); - if (cdrom[c].bus_type == 0) { - ini_section_delete_var(cat, temp); - } else { /*In case one wants an ATAPI drive on SCSI and vice-versa.*/ - if (cdrom[c].bus_type == CDROM_BUS_ATAPI) { - if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_SCSI) - cdrom[c].bus_type = CDROM_BUS_SCSI; - } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { - if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_IDE) - cdrom[c].bus_type = CDROM_BUS_ATAPI; - } + if (cdrom[c].bus_type == 0) + ini_section_delete_var(cat, temp); + else { + /* In case one wants an ATAPI drive on SCSI and vice-versa. */ + if ((cdrom_drive_types[cdrom_get_type(c)].bus_type != BUS_TYPE_BOTH) && + (cdrom_drive_types[cdrom_get_type(c)].bus_type != cdrom[c].bus_type)) + cdrom[c].bus_type = cdrom_drive_types[cdrom_get_type(c)].bus_type; + sprintf(tmp2, "%u, %s", cdrom[c].sound_on, hdd_bus_to_string(cdrom[c].bus_type, 1)); ini_section_set_string(cat, temp, tmp2); @@ -2955,18 +2597,26 @@ save_floppy_and_cdrom_drives(void) } sprintf(temp, "cdrom_%02i_image_path", c + 1); - if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) { + if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, cdrom[c].image_path); + else { + path_normalize(cdrom[c].image_path); + if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cdrom[c].image_path); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); - if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) { + if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, cdrom[c].image_history[i]); + else { + path_normalize(cdrom[c].image_history[i]); + if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cdrom[c].image_history[i]); } } } @@ -3015,10 +2665,14 @@ save_other_removable_devices(void) } sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) { + if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, zip_drives[c].image_path); + else { + path_normalize(zip_drives[c].image_path); + if (!strnicmp(zip_drives[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &zip_drives[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, zip_drives[c].image_path); } } @@ -3054,10 +2708,14 @@ save_other_removable_devices(void) } sprintf(temp, "mo_%02i_image_path", c + 1); - if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) { + if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, mo_drives[c].image_path); + else { + path_normalize(mo_drives[c].image_path); + if (!strnicmp(mo_drives[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &mo_drives[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, mo_drives[c].image_path); } } @@ -3067,9 +2725,9 @@ save_other_removable_devices(void) void config_save(void) { - save_general(); /* General */ + save_general(); /* General */ for (uint8_t i = 0; i < MONITORS_NUM; i++) - save_monitor(i); + save_monitor(i); /* Monitors */ save_machine(); /* Machine */ save_video(); /* Video */ save_input_devices(); /* Input devices */ diff --git a/src/cpu/386.c b/src/cpu/386.c index 87d481e1f9..5379dccf9b 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -12,17 +12,25 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" -#include <86box/timer.h> #include "x86.h" +#include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" +#include <86box/io.h> #include <86box/nmi.h> #include <86box/mem.h> #include <86box/pic.h> +#include <86box/timer.h> #include <86box/pit.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> +#include <86box/plat_fallthrough.h> #include <86box/gdbstub.h> +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.h" #include "386_common.h" #ifdef USE_NEW_DYNAREC # include "codegen.h" @@ -33,55 +41,6 @@ extern int codegen_flags_changed; -int tempc, oldcpl, optype, inttype, oddeven = 0; -int timetolive; - -uint16_t oldcs; - -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t oxpc; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg _oldds; - -#if 1 -int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ - 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ - 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ - 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ - 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ - 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ -#else -int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ - 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x2x */ - 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x3x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ - 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ - 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ - 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ - 3, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ -#endif - #ifdef ENABLE_386_LOG int x386_do_log = ENABLE_386_LOG; @@ -103,9 +62,6 @@ x386_log(const char *fmt, ...) #undef CPU_BLOCK_END #define CPU_BLOCK_END() -#include "x86_flags.h" - -/* #define getbytef() \ ((uint8_t) (fetchdat)); \ cpu_state.pc++ @@ -118,40 +74,162 @@ x386_log(const char *fmt, ...) #define getword2f() \ ((uint16_t) (fetchdat >> 8)); \ cpu_state.pc += 2 -*/ - -#define OP_TABLE(name) ops_##name - -#if 0 -# define CLOCK_CYCLES(c) \ - { \ - if (fpu_cycles > 0) { \ - fpu_cycles -= (c); \ - if (fpu_cycles < 0) { \ - cycles += fpu_cycles; \ - } \ - } else { \ - cycles -= (c); \ - } \ + +static __inline void +fetch_ea_32_long(uint32_t rmdat) +{ + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } +} -# define CLOCK_CYCLES_FPU(c) cycles -= (c) -# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) -#else -# define CLOCK_CYCLES(c) cycles -= (c) -# define CLOCK_CYCLES_FPU(c) cycles -= (c) -# define CONCURRENCY_CYCLES(c) +static __inline void +fetch_ea_16_long(uint32_t rmdat) +{ + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } +} + +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 1; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 1 + +#include "x86_flags.h" + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \ + } while (0) + +#define PREFETCH_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + +#ifndef FPU_CYCLES +# define FPU_CYCLES #endif +#define OP_TABLE(name) ops_2386_##name +#define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } + +#define CLOCK_CYCLES_FPU(c) cycles -= (c) +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) + #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) -#include "x86_ops.h" +#define CHECK_READ_CS(size) \ + if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \ + ((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \ + x86gpf("Limit check (READ)", 0); \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \ + x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \ + +#include "386_ops.h" void -exec386(int cycs) +exec386_2386(int32_t cycs) { - int vector, tempi, cycdiff, oldcyc; - int cycle_period, ins_cycles; + int ol; + + int vector; + int tempi; + int32_t cycdiff; + int32_t oldcyc; + int32_t cycle_period; + int32_t ins_cycles; uint32_t addr; cycles += cycs; @@ -163,6 +241,7 @@ exec386(int cycs) cycdiff = 0; oldcyc = cycles; while (cycdiff < cycle_period) { + int ins_fetch_fault = 0; ins_cycles = cycles; #ifndef USE_NEW_DYNAREC @@ -180,18 +259,31 @@ exec386(int cycs) cpu_state.ssegs = 0; fetchdat = fastreadl_fetch(cs + cpu_state.pc); + ol = opcode_length[fetchdat & 0xff]; + CHECK_READ_CS(MIN(ol, 4)); + ins_fetch_fault = cpu_386_check_instruction_fault(); + + /* Breakpoint fault has priority over other faults. */ + if (ins_fetch_fault) { + ins_fetch_fault = 0; + cpu_state.abrt = 1; + } if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG if (in_smm) - x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); + x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + cpu_state.eflags &= ~(RF_FLAG); + if (opcode == 0xf0) + in_lock = 1; + x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + in_lock = 0; if (x86_was_reset) break; } @@ -212,7 +304,7 @@ exec386(int cycs) flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; cpu_state.abrt = 0; - x86_doabrt(tempi); + x86_doabrt_2386(tempi); if (cpu_state.abrt) { cpu_state.abrt = 0; #ifndef USE_NEW_DYNAREC @@ -220,7 +312,7 @@ exec386(int cycs) #endif cpu_state.pc = cpu_state.oldpc; x386_log("Double fault\n"); - pmodeint(8, 0); + pmodeint_2386(8, 0); if (cpu_state.abrt) { cpu_state.abrt = 0; softresetx86(); @@ -232,12 +324,13 @@ exec386(int cycs) } } else if (trap) { flags_rebuild(); + if (trap & 2) dr[6] |= 0x8000; + if (trap & 1) dr[6] |= 0x4000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } @@ -263,7 +356,7 @@ exec386(int cycs) if (vector != -1) { flags_rebuild(); if (msw & 1) - pmodeint(vector, 0); + pmodeint_2386(vector, 0); else { writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); writememw(ss, (SP - 4) & 0xFFFF, CS); @@ -273,7 +366,7 @@ exec386(int cycs) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + loadcs_2386(readmemw(0, addr + 2)); } } } @@ -290,7 +383,7 @@ exec386(int cycs) } if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); #ifdef USE_GDBSTUB if (gdbstub_instruction()) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 760e41eaac..5c1b95e0f0 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -13,6 +13,7 @@ #include "cpu.h" #include <86box/timer.h> #include "x86.h" +#include "x86seg_common.h" #include "x87.h" #include <86box/nmi.h> #include <86box/mem.h> @@ -23,9 +24,11 @@ #include <86box/fdc.h> #include <86box/keyboard.h> #include <86box/timer.h> + +#include "x86seg.h" #include "386_common.h" #include "x86_flags.h" -#include "x86seg.h" +#include <86box/plat_unused.h> #ifdef USE_DYNAREC # include "codegen.h" @@ -34,19 +37,26 @@ # define CPU_BLOCK_END() #endif -x86seg gdt, ldt, idt, tr; +x86seg gdt; +x86seg ldt; +x86seg idt; +x86seg tr; -uint32_t cr2, cr3, cr4; +uint32_t cr2; +uint32_t cr3; +uint32_t cr4; uint32_t dr[8]; uint32_t use32; int stack32; -uint32_t *eal_r, *eal_w; +uint32_t *eal_r; +uint32_t *eal_w; int nmi_enable = 1; -int alt_access, cpl_override = 0; +int alt_access; +int cpl_override = 0; #ifdef USE_NEW_DYNAREC uint16_t cpu_cur_status = 0; @@ -59,23 +69,115 @@ extern uint8_t *pccache2; extern int optype; extern uint32_t pccache; -int in_sys = 0, unmask_a20_in_smm = 0; -uint32_t old_rammask = 0xffffffff; +int in_sys = 0; +int unmask_a20_in_smm = 0; +uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; int smi_latched = 0; -int smm_in_hlt = 0, smi_block = 0; - -uint32_t addr64, addr64_2; -uint32_t addr64a[8], addr64a_2[8]; +int smm_in_hlt = 0; +int smi_block = 0; + +int prefetch_prefixes = 0; +int rf_flag_no_clear = 0; + +int tempc; +int oldcpl; +int optype; +int inttype; +int oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds; +uint32_t oldss; +uint32_t olddslimit; +uint32_t oldsslimit; +uint32_t olddslimitw; +uint32_t oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + +int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ + 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ + 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ + 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ + 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ + 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ + +/* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */ +int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */ + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */ + 1, 1, 1, 1, 1, 1, 4, 0, 1, 1, 1, 1, 1, 1, 4, 0, /* 0x2x */ + 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3 }; /* 0xfx */ + +int lock_legal_0f[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0xax */ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, /* 0xbx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* 0xfx */ + +/* (modrm >> 3) & 0x07 */ +int lock_legal_ba[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; + +/* Also applies to 81, 82, and 83 */ +int lock_legal_80[8] = { 1, 1, 1, 1, 1, 1, 1, 0 }; + +/* Also applies to F7 */ +int lock_legal_f6[8] = { 0, 0, 1, 1, 0, 0, 0, 0 }; + +/* Also applies to FF */ +int lock_legal_fe[8] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + +uint32_t addr64; +uint32_t addr64_2; +uint32_t addr64a[8]; +uint32_t addr64a_2[8]; static pc_timer_t *cpu_fast_off_timer = NULL; static double cpu_fast_off_period = 0.0; -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +#define AMD_SYSCALL_EIP (msr.amd_star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.amd_star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.amd_star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ @@ -321,6 +423,121 @@ x386_common_log(const char *fmt, ...) # define x386_common_log(fmt, ...) #endif +int +is_lock_legal(uint32_t fetchdat) +{ + int legal; + fetch_dat_t fetch_dat; + + fetch_dat.fd = fetchdat; + + legal = lock_legal[fetch_dat.b[0]]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + else if (legal == 2) { + legal = lock_legal_0f[fetch_dat.b[1]]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */ + else if (legal == 3) { + legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */ + } + } else if (legal == 3) switch(fetch_dat.b[0]) { + case 0x80 ... 0x83: + legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xf6 ... 0xf7: + legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + case 0xfe ... 0xff: + legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07]; + if (legal == 1) + legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */ + break; + default: + legal = 0; + break; + } + + return legal; +} + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; + +void +prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) { + if (ea32) { + if ((modrm & 7) == 4) { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } else { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } else { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +void +prefetch_flush(void) +{ + prefetch_bytes = 0; +} + static __inline void set_stack32(int s) { @@ -391,12 +608,10 @@ smm_seg_load(x86seg *s) static void smram_save_state_p5(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -485,9 +700,7 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) static void smram_restore_state_p5(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff) @@ -598,12 +811,10 @@ smram_restore_state_p5(uint32_t *saved_state) static void smram_save_state_p6(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -684,9 +895,7 @@ smram_save_state_p6(uint32_t *saved_state, int in_hlt) static void smram_restore_state_p6(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff) @@ -791,12 +1000,10 @@ smram_restore_state_p6(uint32_t *saved_state) static void smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -876,9 +1083,7 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) static void smram_restore_state_amd_k(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff) @@ -977,7 +1182,7 @@ smram_restore_state_amd_k(uint32_t *saved_state) } static void -smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) +smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt)) { saved_state[0] = dr[7]; saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16); @@ -1001,7 +1206,7 @@ smram_restore_state_cyrix(uint32_t *saved_state) void enter_smm(int in_hlt) { - uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n; + uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE]; uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported, do nothing. */ @@ -1053,13 +1258,13 @@ enter_smm(int in_hlt) memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_save_state_cyrix(saved_state, in_hlt); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; @@ -1073,7 +1278,10 @@ enter_smm(int in_hlt) if (is_cxsmm) { cpu_state.pc = 0x0000; cpl_override = 1; - cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + if (is486) + cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + else + cyrix_write_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs); cpl_override = 0; cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); cpu_state.seg_cs.base = cyrix.arr[3].base; @@ -1128,7 +1336,7 @@ enter_smm(int in_hlt) writememl(0, smram_state - 0x18, saved_state[5]); writememl(0, smram_state - 0x24, saved_state[6]); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { smram_state -= 4; writememl(0, smram_state, saved_state[n]); } @@ -1188,7 +1396,7 @@ enter_smm_check(int in_hlt) void leave_smm(void) { - uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n; + uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE]; uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ @@ -1206,10 +1414,13 @@ leave_smm(void) saved_state[3] = readmeml(0, smram_state - 0x10); saved_state[4] = readmeml(0, smram_state - 0x14); saved_state[5] = readmeml(0, smram_state - 0x18); - cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + if (is486) + cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + else + cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs); saved_state[6] = readmeml(0, smram_state - 0x24); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { smram_state -= 4; saved_state[n] = readmeml(0, smram_state); x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); @@ -1224,13 +1435,13 @@ leave_smm(void) } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_restore_state_cyrix(saved_state); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_restore_state_p6(saved_state); in_smm = 0; @@ -1292,7 +1503,7 @@ x86_int(int num) cpu_state.pc = cpu_state.oldpc; if (msw & 1) - pmodeint(num, 0); + cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0); else { addr = (num << 2) + idt.base; @@ -1325,7 +1536,7 @@ x86_int(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); } } @@ -1342,7 +1553,7 @@ x86_int_sw(int num) cycles -= timing_int; if (msw & 1) - pmodeint(num, 1); + cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1); else { addr = (num << 2) + idt.base; @@ -1367,12 +1578,15 @@ x86_int_sw(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cycles -= timing_int_rm; } } - trap = 0; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); } @@ -1380,7 +1594,8 @@ int x86_int_sw_rm(int num) { uint32_t addr; - uint16_t new_pc, new_cs; + uint16_t new_pc; + uint16_t new_cs; flags_rebuild(); cycles -= timing_int; @@ -1408,13 +1623,16 @@ x86_int_sw_rm(int num) cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; - loadcs(new_cs); + cpu_use_exec ? loadcs(new_cs) : loadcs_2386(new_cs); #ifndef USE_NEW_DYNAREC oxpc = cpu_state.pc; #endif cycles -= timing_int_rm; - trap = 0; + if (cpu_use_exec) + trap = 0; + else + trap &= ~1; CPU_BLOCK_END(); return 0; @@ -1431,6 +1649,13 @@ checkio(uint32_t port, int mask) { uint32_t t; + if (!(tr.access & 0x08)) { + if ((CPL) > (IOPL)) + return 1; + + return 0; + } + cpl_override = 1; t = readmemw(tr.base, 0x66); @@ -1468,8 +1693,10 @@ checkio(uint32_t port, int mask) int divl(uint32_t val) { - uint64_t num, quo; - uint32_t rem, quo32; + uint64_t num; + uint64_t quo; + uint32_t rem; + uint32_t quo32; if (val == 0) { divexcp(); @@ -1495,8 +1722,10 @@ divl(uint32_t val) int idivl(int32_t val) { - int64_t num, quo; - int32_t rem, quo32; + int64_t num; + int64_t quo; + int32_t rem; + int32_t quo32; if (val == 0) { divexcp(); @@ -1531,6 +1760,37 @@ cpu_386_flags_rebuild(void) flags_rebuild(); } +extern uint64_t mmutranslate_noabrt_2386(uint32_t addr, int rw); +int +cpu_386_check_instruction_fault(void) +{ + int i = 0; + int fault = 0; + /* Report no fault if RF is set. */ + if (cpu_state.eflags & RF_FLAG) + return 0; + + /* Make sure breakpoints are enabled. */ + if (!(dr[7] & 0xFF)) + return 0; + + for (i = 0; i < 4; i++) { + int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))) && !(dr[7] & (0x30000 << (4 * i))); + uint32_t translated_addr = 0xffffffff; + if (!breakpoint_enabled) + continue; + + translated_addr = dr[i]; + + if ((cs + cpu_state.pc) == (uint32_t)translated_addr) { + dr[6] |= (1 << i); + fault = 1; + } + } + + return fault; +} + int sysenter(uint32_t fetchdat) { diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 8cad28ae7e..a98a3e9305 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -20,83 +20,112 @@ #define _386_COMMON_H_ #include - #include - -#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) - -#define writememb_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl_no_mmut((s) + (a), b, v); \ - else \ - *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememw_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl_no_mmut((s) + (a), b, v); \ - else \ - *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememl_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll_no_mmut((s) + (a), b, v); \ - else \ - *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememb(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl((s) + (a), v); \ - else \ - *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememw(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl((s) + (a), v); \ - else \ - *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememl(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll((s) + (a), v); \ - else \ - *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememq(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ - writememql((s) + (a), v); \ - else \ - *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v - -#define do_mmut_rb(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 0) -#define do_mmut_rw(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 0) -#define do_mmut_rl(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 0) -#define do_mmut_rb2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 0) -#define do_mmut_rw2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 0) -#define do_mmut_rl2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 0) - -#define do_mmut_wb(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 1) -#define do_mmut_ww(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 1) -#define do_mmut_wl(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 1) +#include + +#ifdef OPS_286_386 +# define readmemb_n(s, a, b) readmembl_no_mmut_2386((s) + (a), b) +# define readmemw_n(s, a, b) readmemwl_no_mmut_2386((s) + (a), b) +# define readmeml_n(s, a, b) readmemll_no_mmut_2386((s) + (a), b) +# define readmemb(s, a) readmembl_2386((s) + (a)) +# define readmemw(s, a) readmemwl_2386((s) + (a)) +# define readmeml(s, a) readmemll_2386((s) + (a)) +# define readmemq(s, a) readmemql_2386((s) + (a)) + +# define writememb_n(s, a, b, v) writemembl_no_mmut_2386((s) + (a), b, v) +# define writememw_n(s, a, b, v) writememwl_no_mmut_2386((s) + (a), b, v) +# define writememl_n(s, a, b, v) writememll_no_mmut_2386((s) + (a), b, v) +# define writememb(s, a, v) writemembl_2386((s) + (a), v) +# define writememw(s, a, v) writememwl_2386((s) + (a), v) +# define writememl(s, a, v) writememll_2386((s) + (a), v) +# define writememq(s, a, v) writememql_2386((s) + (a), v) + +# define do_mmut_rb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0) +# define do_mmut_rw(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0) +# define do_mmut_rl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0) +# define do_mmut_rb2(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0) +# define do_mmut_rw2(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0) +# define do_mmut_rl2(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0) + +# define do_mmut_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1) +# define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1) +# define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1) +#else +# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) + +# define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v + +# define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +# define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) + +# define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 1) +# define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 1) +# define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 1) +#endif int checkio(uint32_t port, int mask); @@ -191,27 +220,65 @@ int checkio(uint32_t port, int mask); return 1; \ } +#ifdef OPS_286_386 +/* TODO: Introduce functions to read exec. */ +static __inline uint8_t +fastreadb(uint32_t a) +{ + uint8_t ret; + read_type = 1; + ret = readmembl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; +} + +static __inline uint16_t +fastreadw(uint32_t a) +{ + uint16_t ret; + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; +} + +static __inline uint32_t +fastreadl(uint32_t a) +{ + uint32_t ret; + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; + if (cpu_state.abrt) + return 0; + return ret; +} +#else static __inline uint8_t fastreadb(uint32_t a) { uint8_t *t; if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint8_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint8_t *) &pccache2[a]); -#endif +# endif } static __inline uint16_t @@ -225,22 +292,22 @@ fastreadw(uint32_t a) return val; } if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif } static __inline uint32_t @@ -256,16 +323,17 @@ fastreadl(uint32_t a) pccache2 = t; pccache = a >> 12; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint32_t *) &pccache2[a]); -#endif +# endif } val = fastreadw(a); val |= (fastreadw(a + 2) << 16); return val; } +#endif static __inline void * get_ram_ptr(uint32_t a) @@ -288,6 +356,47 @@ get_ram_ptr(uint32_t a) extern int opcode_length[256]; +#ifdef OPS_286_386 +static __inline uint16_t +fastreadw_fetch(uint32_t a) +{ + uint16_t ret; + + if ((a & 0xFFF) > 0xFFE) { + ret = fastreadb(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1)) + ret |= ((uint16_t) fastreadb(a + 1) << 8); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemwl_2386(a); + read_type = 4; + } + + return ret; +} + +static __inline uint32_t +fastreadl_fetch(uint32_t a) +{ + uint32_t ret; + + if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { + ret = fastreadw_fetch(a); + if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2)) + ret |= ((uint32_t) fastreadw(a + 2) << 16); + } else if (cpu_state.abrt) + ret = 0; + else { + read_type = 1; + ret = readmemll_2386(a); + read_type = 4; + } + + return ret; +} +#else static __inline uint16_t fastreadw_fetch(uint32_t a) { @@ -300,22 +409,22 @@ fastreadw_fetch(uint32_t a) return val; } if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif } static __inline uint32_t @@ -331,17 +440,18 @@ fastreadl_fetch(uint32_t a) pccache2 = t; pccache = a >> 12; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint32_t *) &pccache2[a]); -#endif +# endif } val = fastreadw_fetch(a); if (opcode_length[val & 0xff] > 2) val |= (fastreadw(a + 2) << 16); return val; } +#endif static __inline uint8_t getbyte(void) @@ -371,6 +481,93 @@ getquad(void) return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); } +#ifdef OPS_286_386 +static __inline uint8_t +geteab(void) +{ + if (cpu_mod == 3) + return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + return readmemb(easeg, cpu_state.eaaddr); +} + +static __inline uint16_t +geteaw(void) +{ + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + return readmemw(easeg, cpu_state.eaaddr); +} + +static __inline uint32_t +geteal(void) +{ + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + return readmeml(easeg, cpu_state.eaaddr); +} + +static __inline uint64_t +geteaq(void) +{ + return readmemq(easeg, cpu_state.eaaddr); +} + +static __inline uint8_t +geteab_mem(void) +{ + return readmemb(easeg, cpu_state.eaaddr); +} +static __inline uint16_t +geteaw_mem(void) +{ + return readmemw(easeg, cpu_state.eaaddr); +} +static __inline uint32_t +geteal_mem(void) +{ + return readmeml(easeg, cpu_state.eaaddr); +} + +static __inline int +seteaq_cwc(void) +{ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; +} + +static __inline void +seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} + +# define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + writemembl_2386(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +# define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + writememwl_2386(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +# define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + writememll_2386(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v + +# define seteab_mem(v) writemembl_2386(easeg + cpu_state.eaaddr, v); +# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v); +# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v); +#else static __inline uint8_t geteab(void) { @@ -444,51 +641,52 @@ seteaq(uint64_t v) writememql(easeg + cpu_state.eaaddr, v); } -#define seteab(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ - if (eal_w) \ - *(uint8_t *) eal_w = v; \ - else \ - writemembl(easeg + cpu_state.eaaddr, v); \ - } else if (cpu_rm & 4) \ - cpu_state.regs[cpu_rm & 3].b.h = v; \ - else \ - cpu_state.regs[cpu_rm].b.l = v -#define seteaw(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - if (eal_w) \ - *(uint16_t *) eal_w = v; \ +# define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ else \ - writememwl(easeg + cpu_state.eaaddr, v); \ - } else \ - cpu_state.regs[cpu_rm].w = v -#define seteal(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - if (eal_w) \ - *eal_w = v; \ - else \ - writememll(easeg + cpu_state.eaaddr, v); \ - } else \ - cpu_state.regs[cpu_rm].l = v - -#define seteab_mem(v) \ - if (eal_w) \ - *(uint8_t *) eal_w = v; \ - else \ - writemembl(easeg + cpu_state.eaaddr, v); -#define seteaw_mem(v) \ - if (eal_w) \ - *(uint16_t *) eal_w = v; \ - else \ - writememwl(easeg + cpu_state.eaaddr, v); -#define seteal_mem(v) \ - if (eal_w) \ - *eal_w = v; \ - else \ - writememll(easeg + cpu_state.eaaddr, v); + cpu_state.regs[cpu_rm].b.l = v +# define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +# define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v + +# define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +# define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +# define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); +#endif #define getbytef() \ ((uint8_t) (fetchdat)); \ @@ -504,3 +702,8 @@ seteaq(uint64_t v) cpu_state.pc += 2 #endif + +/* Resume Flag handling. */ +extern int rf_flag_no_clear; + +int cpu_386_check_instruction_fault(void); \ No newline at end of file diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index daeef5568e..c96e3420d4 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -17,6 +17,8 @@ #include "cpu.h" #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include <86box/io.h> #include <86box/mem.h> @@ -46,7 +48,9 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -int inrecomp = 0, cpu_block_end = 0; +int cpu_override_dynarec = 0; +int inrecomp = 0; +int cpu_block_end = 0; int cpu_end_block_after_ins = 0; #ifdef ENABLE_386_DYNAREC_LOG @@ -183,78 +187,6 @@ fetch_ea_16_long(uint32_t rmdat) #include "x86_flags.h" -/*Prefetch emulation is a fairly simplistic model: - - All instruction bytes must be fetched before it starts. - - Cycles used for non-instruction memory accesses are counted and subtracted - from the total cycles taken - - Any remaining cycles are used to refill the prefetch queue. - - Note that this is only used for 286 / 386 systems. It is disabled when the - internal cache on 486+ CPUs is enabled. -*/ -static int prefetch_bytes = 0; -static int prefetch_prefixes = 0; - -static void -prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) -{ - int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; - - if (instr_cycles < mem_cycles) - instr_cycles = mem_cycles; - - prefetch_bytes -= prefetch_prefixes; - prefetch_bytes -= bytes; - if (modrm != -1) { - if (ea32) { - if ((modrm & 7) == 4) { - if ((modrm & 0x700) == 0x500) - prefetch_bytes -= 5; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 5; - } else { - if ((modrm & 0xc7) == 0x05) - prefetch_bytes -= 4; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes--; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 4; - } - } else { - if ((modrm & 0xc7) == 0x06) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) != 0xc0) - prefetch_bytes -= ((modrm & 0xc0) >> 6); - } - } - - /* Fill up prefetch queue */ - while (prefetch_bytes < 0) { - prefetch_bytes += cpu_prefetch_width; - cycles -= cpu_prefetch_cycles; - } - - /* Subtract cycles used for memory access by instruction */ - instr_cycles -= mem_cycles; - - while (instr_cycles >= cpu_prefetch_cycles) { - prefetch_bytes += cpu_prefetch_width; - instr_cycles -= cpu_prefetch_cycles; - } - - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; -} - -static void -prefetch_flush(void) -{ - prefetch_bytes = 0; -} - #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ do { \ if (cpu_prefetch_cycles) \ @@ -295,12 +227,12 @@ prefetch_flush(void) #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -int cycles_main = 0; -static int cycles_old = 0; +int32_t cycles_main = 0; +static int32_t cycles_old = 0; static uint64_t tsc_old = 0; # ifdef USE_ACYCS -int acycs = 0; +int32_t acycs = 0; # endif void @@ -327,7 +259,7 @@ update_tsc(void) if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); } } @@ -337,6 +269,12 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; + if (trap == 2) { + /* Handle the T bit in the new TSS first. */ + CPU_BLOCK_END(); + goto block_ended; + } + while (!cpu_block_end) { # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -390,13 +328,14 @@ exec386_dynarec_int(void) CPU_BLOCK_END(); } +block_ended: if (!cpu_state.abrt && trap) { + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; # endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } @@ -406,8 +345,9 @@ exec386_dynarec_int(void) static __inline void exec386_dynarec_dyn(void) { - uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); + uint32_t start_pc = 0; + uint32_t phys_addr = get_phys(cs + cpu_state.pc); + int hash = HASH(phys_addr); # ifdef USE_NEW_DYNAREC codeblock_t *block = &codeblock[codeblock_hash[hash]]; # else @@ -431,7 +371,7 @@ exec386_dynarec_dyn(void) uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); # ifdef USE_NEW_DYNAREC int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f); if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) # else @@ -556,7 +496,9 @@ exec386_dynarec_dyn(void) x86_was_reset = 0; # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(0); + } # endif codegen_block_start_recompile(block); codegen_in_recompile = 1; @@ -608,7 +550,7 @@ exec386_dynarec_dyn(void) # endif CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) + if ((cpu_state.flags & T_FLAG) || (trap == 2)) CPU_BLOCK_END(); if (smi_line) CPU_BLOCK_END(); @@ -640,7 +582,9 @@ exec386_dynarec_dyn(void) codegen_in_recompile = 0; # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(1); + } # endif } else if (!cpu_state.abrt) { /* Mark block but do not recompile */ @@ -740,21 +684,24 @@ exec386_dynarec_dyn(void) } void -exec386_dynarec(int cycs) +exec386_dynarec(int32_t cycs) { - int vector, tempi; - int cycdiff; - int oldcyc, oldcyc2; - uint64_t oldtsc, delta; + int vector; + int tempi; + int32_t cycdiff; + int32_t oldcyc; + int32_t oldcyc2; + uint64_t oldtsc; + uint64_t delta; - int cyc_period = cycs / 2000; /*5us*/ + int32_t cyc_period = cycs / 2000; /*5us*/ # ifdef USE_ACYCS acycs = 0; # endif cycles_main += cycs; while (cycles_main > 0) { - int cycles_start; + int32_t cycles_start; cycles += cyc_period; cycles_start = cycles; @@ -772,7 +719,7 @@ exec386_dynarec(int cycs) cycles_old = cycles; oldtsc = tsc; tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ + if ((!CACHE_ON()) || cpu_override_dynarec) /*Interpret block*/ { exec386_dynarec_int(); } else { @@ -845,7 +792,7 @@ exec386_dynarec(int cycs) if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); } # ifdef USE_GDBSTUB @@ -858,3 +805,160 @@ exec386_dynarec(int cycs) } } #endif + +void +exec386(int32_t cycs) +{ + int vector; + int tempi; + int32_t cycdiff; + int32_t oldcyc; + int32_t cycle_period; + int32_t ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t) tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl_fetch(cs + cpu_state.pc); + + if (!cpu_state.abrt) { +#ifdef ENABLE_386_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); +#endif + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } +#ifdef ENABLE_386_LOG + else if (in_smm) + x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc); +#endif + +#ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +#endif + + if (cpu_end_block_after_ins) + cpu_end_block_after_ins--; + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_dynarec_log("Double fault\n"); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } else if (trap) { + flags_rebuild(); + trap = 0; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); + } + + if (smi_line) + enter_smm_check(0); + else if (nmi && nmi_enable && nmi_mask) { +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; +#ifdef OLD_NMI_BEHAVIOR + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } +#else + nmi = 0; +#endif + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); + +#ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +#endif + } + } +} diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index f3e2f6e6e7..77b72ef599 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -13,6 +13,8 @@ #include <86box/timer.h> #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "x86_flags.h" #include <86box/io.h> @@ -21,6 +23,7 @@ #include <86box/pic.h> #include <86box/gdbstub.h> #include "codegen.h" +#include <86box/plat_unused.h> #define CPU_BLOCK_END() cpu_block_end = 1 @@ -31,7 +34,7 @@ #include "386_common.h" static __inline void -fetch_ea_32_long(uint32_t rmdat) +fetch_ea_32_long(UNUSED(uint32_t rmdat)) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -45,7 +48,7 @@ fetch_ea_32_long(uint32_t rmdat) } static __inline void -fetch_ea_16_long(uint32_t rmdat) +fetch_ea_16_long(UNUSED(uint32_t rmdat)) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index e345ee8d88..3e0d191f20 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -173,60 +173,97 @@ extern void x386_dynarec_log(const char *fmt, ...); # endif #endif -#include "x86seg.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_cyrix.h" -#include "x86_ops_flag.h" -#include "x86_ops_fpu.h" +#ifndef OPS_286_386 +# include "x86_ops_cyrix.h" +#endif +#ifdef OPS_286_386 +# include "x86_ops_flag_2386.h" +#else +# include "x86_ops_flag.h" +#endif +#ifdef OPS_286_386 +# include "x86_ops_fpu_2386.h" +#else +# include "x86_ops_fpu.h" +#endif #include "x86_ops_inc_dec.h" #include "x86_ops_int.h" #include "x86_ops_io.h" #include "x86_ops_jump.h" #include "x86_ops_misc.h" #include "x87_ops.h" -#include "x86_ops_i686.h" -#include "x86_ops_mmx.h" -#include "x86_ops_mmx_arith.h" -#include "x86_ops_mmx_cmp.h" -#include "x86_ops_mmx_logic.h" -#include "x86_ops_mmx_mov.h" -#include "x86_ops_mmx_pack.h" -#include "x86_ops_mmx_shift.h" +#ifndef OPS_286_386 +# include "x86_ops_i686.h" +# include "x86_ops_mmx.h" +# include "x86_ops_mmx_arith.h" +# include "x86_ops_mmx_cmp.h" +# include "x86_ops_mmx_logic.h" +# include "x86_ops_mmx_mov.h" +# include "x86_ops_mmx_pack.h" +# include "x86_ops_mmx_shift.h" +#endif #include "x86_ops_mov.h" -#include "x86_ops_mov_ctrl.h" +#ifdef OPS_286_386 +# include "x86_ops_mov_ctrl_2386.h" +#else +# include "x86_ops_mov_ctrl.h" +#endif #include "x86_ops_mov_seg.h" #include "x86_ops_movx.h" -#include "x86_ops_msr.h" +#ifndef OPS_286_386 +# include "x86_ops_msr.h" +#endif #include "x86_ops_mul.h" #include "x86_ops_pmode.h" -#include "x86_ops_prefix.h" +#ifdef OPS_286_386 +# include "x86_ops_prefix_2386.h" +#else +# include "x86_ops_prefix.h" +#endif #ifdef IS_DYNAREC # include "x86_ops_rep_dyn.h" #else -# include "x86_ops_rep.h" +# ifdef OPS_286_386 +# include "x86_ops_rep_2386.h" +# else +# include "x86_ops_rep.h" +# endif +#endif +#ifdef OPS_286_386 +# include "x86_ops_ret_2386.h" +#else +# include "x86_ops_ret.h" #endif -#include "x86_ops_ret.h" #include "x86_ops_set.h" #include "x86_ops_stack.h" -#include "x86_ops_string.h" +#ifdef OPS_286_386 +# include "x86_ops_string_2386.h" +#else +# include "x86_ops_string.h" +#endif #include "x86_ops_xchg.h" #include "x86_ops_call.h" #include "x86_ops_shift.h" -#include "x86_ops_amd.h" -#include "x86_ops_3dnow.h" +#ifndef OPS_286_386 +# include "x86_ops_amd.h" +# include "x86_ops_3dnow.h" +#endif #include +#ifndef OPS_286_386 static int opVPCEXT(uint32_t fetchdat) { - uint8_t b1, b2; + uint8_t b1; + uint8_t b2; uint16_t cent; time_t now; - struct tm *tm; + struct tm *tm = NULL; if (!is_vpc) /* only emulate this on Virtual PC machines */ return ILLEGAL(fetchdat); @@ -330,7 +367,54 @@ opVPCEXT(uint32_t fetchdat) return 1; } +#endif + +#ifdef OPS_286_386 +static int +op0F_w_a16(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode](fetchdat >> 8); +} +static int +op0F_l_a16(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode | 0x100](fetchdat >> 8); +} +static int +op0F_w_a32(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + return x86_2386_opcodes_0f[opcode | 0x200](fetchdat >> 8); +} +static int +op0F_l_a32(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode | 0x300](fetchdat >> 8); +} +#else static int op0F_w_a16(uint32_t fetchdat) { @@ -375,6 +459,7 @@ op0F_l_a32(uint32_t fetchdat) return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } +#endif const OpFn OP_TABLE(186_0f)[1024] = { // clang-format off @@ -564,7 +649,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -579,14 +664,14 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -601,14 +686,14 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -623,14 +708,14 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -645,7 +730,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -744,6 +829,7 @@ const OpFn OP_TABLE(486_0f)[1024] = { // clang-format on }; +#ifndef OPS_286_386 const OpFn OP_TABLE(c486_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -927,6 +1013,7 @@ const OpFn OP_TABLE(stpc_0f)[1024] = { /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, // clang-format on }; +#endif const OpFn OP_TABLE(ibm486_0f)[1024] = { // clang-format off @@ -1020,6 +1107,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = { // clang-format on }; +#ifndef OPS_286_386 const OpFn OP_TABLE(winchip_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1296,7 +1384,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1388,7 +1476,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = { /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, // clang-format on }; -#endif +# endif const OpFn OP_TABLE(pentiummmx_0f)[1024] = { // clang-format off @@ -1666,7 +1754,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1758,7 +1846,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, // clang-format on }; -#endif +# endif const OpFn OP_TABLE(pentiumpro_0f)[1024] = { // clang-format off @@ -2035,6 +2123,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = { /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, // clang-format on }; +#endif const OpFn OP_TABLE(186)[1024] = { // clang-format off diff --git a/src/cpu/8080.c b/src/cpu/8080.c index 6f3dd42674..7a7e7b96c2 100644 --- a/src/cpu/8080.c +++ b/src/cpu/8080.c @@ -19,15 +19,21 @@ #include <86box/timer.h> #include <86box/i8080.h> #include <86box/mem.h> +#include <86box/plat_unused.h> -static int completed = 1; -static int in_rep = 0, repeating = 0, rep_c_flag = 0; -static int oldc, cycdiff; +static int completed = 1; +static int in_rep = 0; +static int repeating = 0; +static int rep_c_flag = 0; +static int oldc; +static int cycdiff; #ifdef UNUSED_8080_VARS static int prefetching = 1; -static int refresh = 0, clear_lock = 0; +static int refresh = 0; +static int clear_lock = 0; -static uint32_t cpu_src = 0, cpu_dest = 0; +static uint32_t cpu_src = 0; +static uint32_t cpu_dest = 0; static uint32_t cpu_data = 0; #endif @@ -43,7 +49,7 @@ clock_end(void) int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + tsc += (uint64_t) diff * (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, (uint32_t) tsc)) timer_process(); } @@ -237,7 +243,7 @@ setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val) } void -interpret_exec8080(i8080 *cpu, uint8_t opcode) +interpret_exec8080(UNUSED(i8080 *cpu), uint8_t opcode) { switch (opcode) { case 0x00: diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 925594a118..caff0fa600 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -56,7 +56,6 @@ static uint32_t *opseg[4]; static x86seg *_opseg[4]; static int noint = 0; -static int in_lock = 0; static int cpu_alu_op, pfq_size; static uint32_t cpu_src = 0, cpu_dest = 0; @@ -426,13 +425,13 @@ pfq_write(void) free in the queue. */ tempw = readmemwf(pfq_ip); *(uint16_t *) &(pfq[pfq_pos]) = tempw; - pfq_ip = (pfq_ip + 2) & 0xffff; + pfq_ip += 2; pfq_pos += 2; } else if (!is8086 && (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. */ pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip = (pfq_ip + 1) & 0xffff; + pfq_ip++; pfq_pos++; } } @@ -440,10 +439,10 @@ pfq_write(void) static uint8_t pfq_read(void) { - uint8_t temp; + uint8_t temp, i; temp = pfq[0]; - for (int i = 0; i < (pfq_size - 1); i++) + for (i = 0; i < (pfq_size - 1); i++) pfq[i] = pfq[i + 1]; pfq_pos--; cpu_state.pc = (cpu_state.pc + 1) & 0xffff; @@ -545,7 +544,6 @@ reset_808x(int hard) { biu_cycles = 0; in_rep = 0; - in_lock = 0; completed = 1; repeating = 0; clear_lock = 0; @@ -563,9 +561,10 @@ reset_808x(int hard) _opseg[3] = &cpu_state.seg_ds; pfq_size = (is8086) ? 6 : 4; - pfq_clear(); } + pfq_clear(); + load_cs(0xFFFF); cpu_state.pc = 0; if (is_nec) @@ -1222,34 +1221,48 @@ static void add(int bits) { int size_mask = (1 << bits) - 1; + int special_case = 0; + uint32_t temp_src = cpu_src; + + if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + special_case = 1; cpu_data = cpu_dest + cpu_src; + if ((cpu_alu_op == 2) && (cpu_state.flags & C_FLAG)) + 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)) + if (special_case) cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_data & size_mask)); + set_cf((temp_src & size_mask) > (cpu_data & size_mask)); } static void sub(int bits) { int size_mask = (1 << bits) - 1; + int special_case = 0; + uint32_t temp_src = cpu_src; + + if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + special_case = 1; cpu_data = cpu_dest - cpu_src; + if ((cpu_alu_op == 3) && (cpu_state.flags & C_FLAG)) + 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)) + if (special_case) cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_dest & size_mask)); + set_cf((temp_src & size_mask) > (cpu_dest & size_mask)); } static void @@ -2248,7 +2261,7 @@ execx86(int cycs) default: opcode = orig_opcode; - cpu_state.pc = (cpu_state.pc - 1) & 0xffff; + cpu_state.pc--; break; } } else @@ -3131,11 +3144,15 @@ execx86(int cycs) case 0xD4: /*AAM*/ wait(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)) set_pzs(16); break; @@ -3178,63 +3195,33 @@ execx86(int cycs) tempw = cpu_state.pc; if (!hasfpu) geteaw(); - else { - if (fpu_softfloat) { - switch (opcode) { - case 0xD8: - ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xD9: - ops_sf_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDA: - ops_sf_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDB: - ops_sf_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDC: - ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xDD: - ops_sf_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDE: - ops_sf_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDF: - ops_sf_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); - break; - } - } else { - switch (opcode) { - case 0xD8: - ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xD9: - ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDA: - ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDB: - ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDC: - ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xDD: - ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDE: - ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDF: - ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); - break; - } + else + switch (opcode) { + case 0xD8: + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + break; + case 0xD9: + ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDA: + ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDB: + ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDC: + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + break; + case 0xDD: + ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDE: + ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDF: + ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); + break; } - } cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on the 286+ core, but not here. */ wait(1, 0); diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 18aa060236..bd03a5558f 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -14,7 +14,8 @@ # add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c - 386_dynarec.c x86seg.c x87.c x87_timings.c 8080.c) + 386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c + x87_timings.c 8080.c) if(AMD_K5) target_compile_definitions(cpu PRIVATE USE_AMD_K5) diff --git a/src/cpu/codegen_public.h b/src/cpu/codegen_public.h index 36393296ed..cb7ec57a7a 100644 --- a/src/cpu/codegen_public.h +++ b/src/cpu/codegen_public.h @@ -50,9 +50,6 @@ #endif extern void codegen_init(void); -#ifdef USE_NEW_DYNAREC -extern void codegen_close(void); -#endif extern void codegen_flush(void); /*Current physical page of block being recompiled. -1 if no recompilation taking place */ diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 2fe5ce4175..e862b123e7 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -3,8 +3,10 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -12,11 +14,11 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) +#define CYCLES(c) (int *) c +#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = -{ +static int *opcode_timings[256] = { + // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -36,10 +38,11 @@ static int *opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_mod3[256] = -{ +static int *opcode_timings_mod3[256] = { + // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_0f[256] = -{ +static int *opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] = /*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, + // clang-format on }; -static int *opcode_timings_0f_mod3[256] = -{ +static int *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -104,60 +109,69 @@ static int *opcode_timings_0f_mod3[256] = /*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, + // clang-format on }; -static int *opcode_timings_shift[8] = -{ +static int *opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) }; -static int *opcode_timings_shift_mod3[8] = -{ +static int *opcode_timings_shift_mod3[8] = { +// clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static int *opcode_timings_f6[8] = -{ +static int *opcode_timings_f6[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f6_mod3[8] = -{ +static int *opcode_timings_f6_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f7[8] = -{ +static int *opcode_timings_f7[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_f7_mod3[8] = -{ +static int *opcode_timings_f7_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) }; -static int *opcode_timings_ff[8] = -{ +static int *opcode_timings_ff[8] = { +// clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL }; -static int *opcode_timings_ff_mod3[8] = -{ +static int *opcode_timings_ff_mod3[8] = { +// clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_d8[8] = -{ +static int *opcode_timings_d8[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_d8_mod3[8] = -{ +static int *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_d9[8] = -{ +static int *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) + // clang-format on }; -static int *opcode_timings_d9_mod3[64] = -{ +static int *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), /*FXCH*/ @@ -174,26 +188,29 @@ static int *opcode_timings_d9_mod3[64] = CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3), /* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257) + // clang-format on }; -static int *opcode_timings_da[8] = -{ +static int *opcode_timings_da[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_da_mod3[8] = -{ +static int *opcode_timings_da_mod3[8] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL + // clang-format on }; - -static int *opcode_timings_db[8] = -{ +static int *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6) + // clang-format on }; -static int *opcode_timings_db_mod3[64] = -{ +static int *opcode_timings_db_mod3[64] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -203,219 +220,242 @@ static int *opcode_timings_db_mod3[64] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -static int *opcode_timings_dc[8] = -{ +static int *opcode_timings_dc[8] = { + // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_dc_mod3[8] = -{ +static int *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_dd[8] = -{ +static int *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3) + // clang-format on }; -static int *opcode_timings_dd_mod3[8] = -{ +static int *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL + // clang-format on }; -static int *opcode_timings_de[8] = -{ +static int *opcode_timings_de[8] = { + // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_de_mod3[8] = -{ +static int *opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_df[8] = -{ +static int *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28) + // clang-format on }; -static int *opcode_timings_df_mod3[8] = -{ +static int *opcode_timings_df_mod3[8] = { + // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL + // clang-format on }; -static int *opcode_timings_8x[8] = -{ +static int *opcode_timings_8x[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_8x_mod3[8] = -{ +static int *opcode_timings_8x_mod3[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_81[8] = -{ +static int *opcode_timings_81[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_81_mod3[8] = -{ +static int *opcode_timings_81_mod3[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static inline int COUNT(int *c, int op_32) -{ - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; +static inline int +COUNT(int *c, int op_32) +{ + if ((uintptr_t) c <= 10000) + return (int) (uintptr_t) c; + if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + return *c; } -void codegen_timing_486_block_start(void) +void +codegen_timing_486_block_start(void) { - regmask_modified = 0; + regmask_modified = 0; } -void codegen_timing_486_start(void) +void +codegen_timing_486_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) { - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } -void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; +void +codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +{ + int **timings; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ + codegen_block_cycles += timing_count; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_486_block_end(void) +void +codegen_timing_486_block_end(void) { + // } -codegen_timing_t codegen_timing_486 = -{ - codegen_timing_486_start, - codegen_timing_486_prefix, - codegen_timing_486_opcode, - codegen_timing_486_block_start, - codegen_timing_486_block_end, - NULL +codegen_timing_t codegen_timing_486 = { + codegen_timing_486_start, + codegen_timing_486_prefix, + codegen_timing_486_opcode, + codegen_timing_486_block_start, + codegen_timing_486_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index 7d7f4042d5..a6800c5b22 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -13,8 +13,10 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -22,7 +24,7 @@ #include "codegen_timing_common.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 31) +#define CYCLES_HAS_MULTI (1 << 31) #define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) @@ -31,39 +33,39 @@ /*Instruction follows either register timing, read-modify, or read-modify-write. May be pairable*/ -#define CYCLES_REG (1 << 0) -#define CYCLES_RM (1 << 0) -#define CYCLES_RMW (1 << 0) +#define CYCLES_REG (1 << 0) +#define CYCLES_RM (1 << 0) +#define CYCLES_RMW (1 << 0) #define CYCLES_BRANCH (1 << 0) -#define CYCLES_MASK ((1 << 7) - 1) +#define CYCLES_MASK ((1 << 7) - 1) /*Instruction does not pair*/ #define PAIR_NP (0 << 29) /*Instruction pairs in X pipe only*/ -#define PAIR_X (1 << 29) +#define PAIR_X (1 << 29) /*Instruction pairs in X pipe only, and can not pair with a following instruction*/ -#define PAIR_X_BRANCH (2 << 29) +#define PAIR_X_BRANCH (2 << 29) /*Instruction pairs in both X and Y pipes*/ -#define PAIR_XY (3 << 29) +#define PAIR_XY (3 << 29) #define PAIR_MASK (3 << 29) -#define INVALID 0 +#define INVALID 0 -static int prev_full; -static uint32_t prev_opcode; +static int prev_full; +static uint32_t prev_opcode; static uint32_t *prev_timings; -static uint32_t prev_op_32; -static uint32_t prev_regmask; +static uint32_t prev_op_32; +static uint32_t prev_regmask; static uint64_t *prev_deps; -static uint32_t prev_fetchdat; +static uint32_t prev_fetchdat; static uint32_t last_regmask_modified; static uint32_t regmask_modified; -static uint32_t opcode_timings[256] = -{ +static uint32_t opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, /* ADD ADD PUSH ES POP ES*/ @@ -196,10 +198,11 @@ static uint32_t opcode_timings[256] = PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), /* CLD STD INCDEC*/ PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_RMW, INVALID + // clang-format on }; -static uint32_t opcode_timings_mod3[256] = -{ +static uint32_t opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, /* ADD ADD PUSH ES POP ES*/ @@ -333,10 +336,11 @@ static uint32_t opcode_timings_mod3[256] = PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), /* CLD STD INCDEC*/ PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_REG, INVALID + // clang-format on }; -static uint32_t opcode_timings_0f[256] = -{ +static uint32_t opcode_timings_0f[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -416,9 +420,10 @@ static uint32_t opcode_timings_0f[256] = INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = -{ +static uint32_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -497,106 +502,122 @@ static uint32_t opcode_timings_0f_mod3[256] = INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, + // clang-format on }; -static uint32_t opcode_timings_shift[8] = -{ +static uint32_t opcode_timings_shift[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = -{ +static uint32_t opcode_timings_shift_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + // clang-format on }; -static uint32_t opcode_timings_shift_imm[8] = -{ +static uint32_t opcode_timings_shift_imm[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + // clang-format on }; -static uint32_t opcode_timings_shift_imm_mod3[8] = -{ +static uint32_t opcode_timings_shift_imm_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + // clang-format on }; -static uint32_t opcode_timings_shift_cl[8] = -{ +static uint32_t opcode_timings_shift_cl[8] = { + // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), + // clang-format on }; -static uint32_t opcode_timings_shift_cl_mod3[8] = -{ +static uint32_t opcode_timings_shift_cl_mod3[8] = { + // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), + // clang-format on }; -static uint32_t opcode_timings_f6[8] = -{ +static uint32_t opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) + // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = -{ +static uint32_t opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) + // clang-format on }; -static uint32_t opcode_timings_f7[8] = -{ +static uint32_t opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) + // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = -{ +static uint32_t opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) + // clang-format on }; -static uint32_t opcode_timings_ff[8] = -{ +static uint32_t opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), /* JMP JMP far PUSH*/ PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID + // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = -{ +static uint32_t opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), /* JMP JMP far PUSH*/ PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID + // clang-format on }; -static uint32_t opcode_timings_d8[8] = -{ +static uint32_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), /* FSUBs FSUBRs FDIVs FDIVRs*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = -{ +static uint32_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), /* FSUB FSUBR FDIV FDIVR*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_d9[8] = -{ +static uint32_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FLDENV FLDCW FSTENV FSTCW*/ PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5) + // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = -{ +static uint32_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -625,31 +646,34 @@ static uint32_t opcode_timings_d9_mod3[64] = PAIR_X | CYCLES(91), INVALID, PAIR_X | CYCLES(60), PAIR_X | CYCLES(161), /* opFRNDINT opFSCALE opFSIN opFCOS*/ PAIR_X | CYCLES(20), PAIR_X | CYCLES(14), PAIR_X | CYCLES(140), PAIR_X | CYCLES(141) + // clang-format on }; -static uint32_t opcode_timings_da[8] = -{ +static uint32_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48) + // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = -{ +static uint32_t opcode_timings_da_mod3[8] = { + // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, PAIR_X | CYCLES(5), INVALID, INVALID + // clang-format on }; - -static uint32_t opcode_timings_db[8] = -{ +static uint32_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FLDe FSTPe*/ INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = -{ +static uint32_t opcode_timings_db_mod3[64] = { + // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), @@ -675,383 +699,387 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint32_t opcode_timings_dc[8] = -{ +static uint32_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), /* FSUBd FSUBRd FDIVd FDIVRd*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = -{ +static uint32_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_dd[8] = -{ +static uint32_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FRSTOR FSAVE FSTSW*/ PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = -{ +static uint32_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FUCOM FUCOMP*/ PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_de[8] = -{ +static uint32_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38) }; -static uint32_t opcode_timings_de_mod3[8] = -{ +static uint32_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7), /* FSUB FSUBR FDIV FDIVR*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_df[8] = -{ +static uint32_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13), /* FILDiq FBSTP FISTPiq*/ INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13) + // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = -{ +static uint32_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ PAIR_X | CYCLES(6), INVALID, INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_8x[8] = -{ +static uint32_t opcode_timings_8x[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM + // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = -{ +static uint32_t opcode_timings_8x_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG + // clang-format on }; -static uint32_t opcode_timings_81[8] = -{ +static uint32_t opcode_timings_81[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM + // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = -{ +static uint32_t opcode_timings_81_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG + // clang-format on }; -static int decode_delay; +static int decode_delay; static uint8_t last_prefix; -static inline int COUNT(uint32_t c, int op_32) +static inline int +COUNT(uint32_t c, int op_32) { - if (c & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - if (!(c & PAIR_MASK)) - return c & 0xffff; - - return c & CYCLES_MASK; + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + if (!(c & PAIR_MASK)) + return c & 0xffff; + + return c & CYCLES_MASK; } -void codegen_timing_686_block_start(void) +void +codegen_timing_686_block_start(void) { - prev_full = decode_delay = 0; - regmask_modified = last_regmask_modified = 0; + prev_full = decode_delay = 0; + regmask_modified = last_regmask_modified = 0; } -void codegen_timing_686_start(void) +void +codegen_timing_686_start(void) { - decode_delay = 0; - last_prefix = 0; + decode_delay = 0; + last_prefix = 0; } -void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) { - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - - /*6x86 can decode 1 prefix per instruction per clock with no penalty. If - either instruction has more than one prefix then decode is delayed by - one cycle for each additional prefix*/ - decode_delay++; + if ((prefix & 0xf8) == 0xd8) { + last_prefix = prefix; + return; + } + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) { + /*0fh prefix is 'free' when used on conditional jumps*/ last_prefix = prefix; + return; + } + + /*6x86 can decode 1 prefix per instruction per clock with no penalty. If + either instruction has more than one prefix then decode is delayed by + one cycle for each additional prefix*/ + decode_delay++; + last_prefix = prefix; } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - if (addr_regmask & IMPL_ESP) - addr_regmask |= (1 << REG_ESP); + if (addr_regmask & IMPL_ESP) + addr_regmask |= (1 << REG_ESP); - if (regmask_modified & addr_regmask) - { - regmask_modified = 0; - return 2; - } + if (regmask_modified & addr_regmask) { + regmask_modified = 0; + return 2; + } - if (last_regmask_modified & addr_regmask) - return 1; + if (last_regmask_modified & addr_regmask) + return 1; - return 0; + return 0; } -void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd0: + case 0xd1: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: - timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + /*One prefix per instruction is free*/ + decode_delay--; + if (decode_delay < 0) + decode_delay = 0; - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; - - if (prev_full) - { - uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); - int agi_stall = 0; - - if (regmask & IMPL_ESP) - regmask |= SRCDEP_ESP | DSTDEP_ESP; - - agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); - - /*Second instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (prev_regmask & regmask) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else - { - int t1 = COUNT(prev_timings[prev_opcode], prev_op_32); - int t2 = COUNT(timings[opcode], op_32); - int t_pair = (t1 > t2) ? t1 : t2; - - if (!t_pair) - fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += t_pair + agi_stall; - decode_delay = (-t_pair) + 1 + agi_stall; - - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; - prev_full = 0; - return; - } + if (prev_full) { + uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); + int agi_stall = 0; + + if (regmask & IMPL_ESP) + regmask |= SRCDEP_ESP | DSTDEP_ESP; + + agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); + + /*Second instruction in the pair*/ + if ((timings[opcode] & PAIR_MASK) == PAIR_NP) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) + && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else if (prev_regmask & regmask) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else { + int t1 = COUNT(prev_timings[prev_opcode], prev_op_32); + int t2 = COUNT(timings[opcode], op_32); + int t_pair = (t1 > t2) ? t1 : t2; + + if (!t_pair) + fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); + + agi_stall = check_agi(deps, opcode, fetchdat, op_32); + + codegen_block_cycles += t_pair + agi_stall; + decode_delay = (-t_pair) + 1 + agi_stall; + + last_regmask_modified = regmask_modified; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; + prev_full = 0; + return; } - - if (!prev_full) - { - /*First instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - { - /*Instruction not pairable*/ - int agi_stall = 0; - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - } - else - { - /*Instruction might pair with next*/ - prev_full = 1; - prev_opcode = opcode; - prev_timings = timings; - prev_op_32 = op_32; - prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - if (prev_regmask & IMPL_ESP) - prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; - prev_deps = deps; - prev_fetchdat = fetchdat; - return; - } + } + + if (!prev_full) { + /*First instruction in the pair*/ + if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) { + /*Instruction not pairable*/ + int agi_stall = 0; + + agi_stall = check_agi(deps, opcode, fetchdat, op_32); + + codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; + last_regmask_modified = regmask_modified; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + } else { + /*Instruction might pair with next*/ + prev_full = 1; + prev_opcode = opcode; + prev_timings = timings; + prev_op_32 = op_32; + prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + if (prev_regmask & IMPL_ESP) + prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; + prev_deps = deps; + prev_fetchdat = fetchdat; + return; } + } } -void codegen_timing_686_block_end(void) +void +codegen_timing_686_block_end(void) { - if (prev_full) - { - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - prev_full = 0; - } + if (prev_full) { + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; + prev_full = 0; + } } -codegen_timing_t codegen_timing_686 = -{ - codegen_timing_686_start, - codegen_timing_686_prefix, - codegen_timing_686_opcode, - codegen_timing_686_block_start, - codegen_timing_686_block_end, - NULL +codegen_timing_t codegen_timing_686 = { + codegen_timing_686_start, + codegen_timing_686_prefix, + codegen_timing_686_opcode, + codegen_timing_686_block_start, + codegen_timing_686_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_common.c b/src/cpu/codegen_timing_common.c index a1f1b6ce76..0c538fc4e8 100644 --- a/src/cpu/codegen_timing_common.c +++ b/src/cpu/codegen_timing_common.c @@ -8,8 +8,8 @@ #include "codegen_timing_common.h" -uint64_t opcode_deps[256] = -{ +uint64_t opcode_deps[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, /* ADD ADD PUSH ES POP ES*/ @@ -140,10 +140,11 @@ uint64_t opcode_deps[256] = 0, 0, 0, 0, /* CLD STD INCDEC*/ 0, 0, MODRM, 0 + // clang-format on }; -uint64_t opcode_deps_mod3[256] = -{ +uint64_t opcode_deps_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* ADD ADD PUSH ES POP ES*/ @@ -274,10 +275,11 @@ uint64_t opcode_deps_mod3[256] = 0, 0, 0, 0, /* CLD STD INCDEC*/ 0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0 + // clang-format on }; -uint64_t opcode_deps_0f[256] = -{ +uint64_t opcode_deps_0f[256] = { + // clang-format off /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, @@ -357,9 +359,10 @@ uint64_t opcode_deps_0f[256] = 0, MODRM | MMX_MULTIPLY, 0, 0, MODRM, MODRM, MODRM, 0, MODRM, MODRM, MODRM, 0, + // clang-format on }; -uint64_t opcode_deps_0f_mod3[256] = -{ +uint64_t opcode_deps_0f_mod3[256] = { + // clang-format off /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, @@ -439,10 +442,11 @@ uint64_t opcode_deps_0f_mod3[256] = 0, MODRM | MMX_MULTIPLY, 0, 0, MODRM, MODRM, MODRM, 0, MODRM, MODRM, MODRM, 0, + // clang-format on }; -uint64_t opcode_deps_0f0f[256] = -{ +uint64_t opcode_deps_0f0f[256] = { + // clang-format off /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -522,9 +526,10 @@ uint64_t opcode_deps_0f0f[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_0f0f_mod3[256] = -{ +uint64_t opcode_deps_0f0f_mod3[256] = { + // clang-format off /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -604,97 +609,111 @@ uint64_t opcode_deps_0f0f_mod3[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_shift[8] = -{ +uint64_t opcode_deps_shift[8] = { + // clang-format off MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, + // clang-format on }; -uint64_t opcode_deps_shift_mod3[8] = -{ +uint64_t opcode_deps_shift_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, + // clang-format on }; -uint64_t opcode_deps_shift_cl[8] = -{ +uint64_t opcode_deps_shift_cl[8] = { + // clang-format off MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, + // clang-format on }; -uint64_t opcode_deps_shift_cl_mod3[8] = -{ +uint64_t opcode_deps_shift_cl_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, + // clang-format on }; -uint64_t opcode_deps_f6[8] = -{ +uint64_t opcode_deps_f6[8] = { + // clang-format off /* TST NOT NEG*/ MODRM, 0, MODRM, MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f6_mod3[8] = -{ +uint64_t opcode_deps_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f7[8] = -{ +uint64_t opcode_deps_f7[8] = { + // clang-format off /* TST NOT NEG*/ MODRM, 0, MODRM, MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f7_mod3[8] = -{ +uint64_t opcode_deps_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_ff[8] = -{ +uint64_t opcode_deps_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ MODRM, MODRM, MODRM | IMPL_ESP, MODRM, /* JMP JMP far PUSH*/ MODRM, MODRM, MODRM | IMPL_ESP, 0 + // clang-format on }; -uint64_t opcode_deps_ff_mod3[8] = -{ +uint64_t opcode_deps_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM, /* JMP JMP far PUSH*/ SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0 + // clang-format on }; -uint64_t opcode_deps_d8[8] = -{ +uint64_t opcode_deps_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM, /* FSUBs FSUBRs FDIVs FDIVRs*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_d8_mod3[8] = -{ +uint64_t opcode_deps_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG, /* FSUB FSUBR FDIV FDIVR*/ FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG + // clang-format on }; -uint64_t opcode_deps_d9[8] = -{ +uint64_t opcode_deps_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM, /* FLDENV FLDCW FSTENV FSTCW*/ MODRM, MODRM, MODRM, MODRM + // clang-format on }; -uint64_t opcode_deps_d9_mod3[64] = -{ +uint64_t opcode_deps_d9_mod3[64] = { + // clang-format off /*FLD*/ FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, @@ -722,32 +741,35 @@ uint64_t opcode_deps_d9_mod3[64] = 0, 0, 0, 0, /* opFRNDINT opFSCALE opFSIN opFCOS*/ 0, 0, 0, 0 + // clang-format on }; -uint64_t opcode_deps_da[8] = -{ +uint64_t opcode_deps_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_da_mod3[8] = -{ +uint64_t opcode_deps_da_mod3[8] = { + // clang-format off 0, 0, 0, 0, /* FCOMPP*/ 0, FPU_POP2, 0, 0 + // clang-format on }; - -uint64_t opcode_deps_db[8] = -{ +uint64_t opcode_deps_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FLDe FSTPe*/ 0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM + // clang-format on }; -uint64_t opcode_deps_db_mod3[64] = -{ +uint64_t opcode_deps_db_mod3[64] = { + // clang-format off 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -767,84 +789,97 @@ uint64_t opcode_deps_db_mod3[64] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_dc[8] = -{ +uint64_t opcode_deps_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FSUBd FSUBRd FDIVd FDIVRd*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_dc_mod3[8] = -{ +uint64_t opcode_deps_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG + // clang-format on }; -uint64_t opcode_deps_dd[8] = -{ +uint64_t opcode_deps_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FRSTOR FSAVE FSTSW*/ MODRM, 0, MODRM, MODRM + // clang-format on }; -uint64_t opcode_deps_dd_mod3[8] = -{ +uint64_t opcode_deps_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ 0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, /* FUCOM FUCOMP*/ FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0 + // clang-format on }; -uint64_t opcode_deps_de[8] = -{ +uint64_t opcode_deps_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_de_mod3[8] = -{ +uint64_t opcode_deps_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2, /* FSUBP FSUBRP FDIVP FDIVRP*/ FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP + // clang-format on }; -uint64_t opcode_deps_df[8] = -{ +uint64_t opcode_deps_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FILDiq FBSTP FISTPiq*/ 0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM + // clang-format on }; -uint64_t opcode_deps_df_mod3[8] = -{ +uint64_t opcode_deps_df_mod3[8] = { + // clang-format off 0, 0, 0, 0, /* FSTSW AX*/ 0, 0, 0, 0 + // clang-format on }; -uint64_t opcode_deps_81[8] = -{ +uint64_t opcode_deps_81[8] = { + // clang-format off MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632 + // clang-format on }; -uint64_t opcode_deps_81_mod3[8] = -{ +uint64_t opcode_deps_81_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632 + // clang-format on }; -uint64_t opcode_deps_8x[8] = -{ +uint64_t opcode_deps_8x[8] = { + // clang-format off MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8 + // clang-format on }; -uint64_t opcode_deps_8x_mod3[8] = -{ +uint64_t opcode_deps_8x_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8 + // clang-format on }; diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index 6799978026..3d28a89deb 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -1,79 +1,79 @@ #include "codegen_ops.h" /*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1ull << 0) +#define SRCDEP_REG (1ULL << 0) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) +#define SRCDEP_RM (1ULL << 1) /*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1ull << 2) +#define DSTDEP_REG (1ULL << 2) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) +#define DSTDEP_RM (1ULL << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 /*Instruction has input dependency on given register*/ -#define SRCDEP_EAX (1ull << 4) -#define SRCDEP_ECX (1ull << 5) -#define SRCDEP_EDX (1ull << 6) -#define SRCDEP_EBX (1ull << 7) -#define SRCDEP_ESP (1ull << 8) -#define SRCDEP_EBP (1ull << 9) -#define SRCDEP_ESI (1ull << 10) -#define SRCDEP_EDI (1ull << 11) +#define SRCDEP_EAX (1ULL << 4) +#define SRCDEP_ECX (1ULL << 5) +#define SRCDEP_EDX (1ULL << 6) +#define SRCDEP_EBX (1ULL << 7) +#define SRCDEP_ESP (1ULL << 8) +#define SRCDEP_EBP (1ULL << 9) +#define SRCDEP_ESI (1ULL << 10) +#define SRCDEP_EDI (1ULL << 11) /*Instruction modifies given register*/ -#define DSTDEP_EAX (1ull << 12) -#define DSTDEP_ECX (1ull << 13) -#define DSTDEP_EDX (1ull << 14) -#define DSTDEP_EBX (1ull << 15) -#define DSTDEP_ESP (1ull << 16) -#define DSTDEP_EBP (1ull << 17) -#define DSTDEP_ESI (1ull << 18) -#define DSTDEP_EDI (1ull << 19) +#define DSTDEP_EAX (1ULL << 12) +#define DSTDEP_ECX (1ULL << 13) +#define DSTDEP_EDX (1ULL << 14) +#define DSTDEP_EBX (1ULL << 15) +#define DSTDEP_ESP (1ULL << 16) +#define DSTDEP_EBP (1ULL << 17) +#define DSTDEP_ESI (1ULL << 18) +#define DSTDEP_EDI (1ULL << 19) /*Instruction has ModR/M byte*/ -#define MODRM (1ull << 20) +#define MODRM (1ULL << 20) /*Instruction implicitly uses ESP*/ -#define IMPL_ESP (1ull << 21) +#define IMPL_ESP (1ULL << 21) /*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1ull << 22) +#define MMX_SHIFTPACK (1ULL << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ULL << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ULL << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ULL << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ULL << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ULL << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ULL << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ULL << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ULL << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ULL << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ULL << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#define FPU_READ_STREG (1ULL << 31) /*Instruction writes to ST(reg)*/ -#define FPU_WRITE_STREG (1ull << 32) +#define FPU_WRITE_STREG (1ULL << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 31) +#define FPU_RW_STREG (3ULL << 31) -#define FPU_FXCH (1ull << 33) +#define FPU_FXCH (1ULL << 33) -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) +#define HAS_IMM8 (1ULL << 34) +#define HAS_IMM1632 (1ULL << 35) #define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 6a59fc157f..4a9f23cd82 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -8,873 +8,758 @@ #include <86box/mem.h> #include "cpu.h" #include <86box/machine.h> + #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_ops.h" #include "codegen_timing_common.h" -typedef enum uop_type_t -{ - UOP_ALU = 0, /*Executes in Integer X or Y units*/ - UOP_ALUX, /*Executes in Integer X unit*/ - UOP_LOAD, /*Executes in Load unit*/ - UOP_STORE, /*Executes in Store unit*/ - UOP_FLOAD, /*Executes in Load unit*/ - UOP_FSTORE, /*Executes in Store unit*/ - UOP_MLOAD, /*Executes in Load unit*/ - UOP_MSTORE, /*Executes in Store unit*/ - UOP_FLOAT, /*Executes in Floating Point unit*/ - UOP_MEU, /*Executes in Multimedia unit*/ - UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ - UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ - UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ - UOP_BRANCH, /*Executes in Branch unit*/ - UOP_LIMM /*Does not require an execution unit*/ +typedef enum uop_type_t { + UOP_ALU = 0, /*Executes in Integer X or Y units*/ + UOP_ALUX, /*Executes in Integer X unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORE, /*Executes in Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORE, /*Executes in Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORE, /*Executes in Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MEU, /*Executes in Multimedia unit*/ + UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ + UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ + UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_LIMM /*Does not require an execution unit*/ } uop_type_t; -typedef enum decode_type_t -{ - DECODE_SHORT, - DECODE_LONG, - DECODE_VECTOR +typedef enum decode_type_t { + DECODE_SHORT, + DECODE_LONG, + DECODE_VECTOR } decode_type_t; #define MAX_UOPS 10 -typedef struct risc86_uop_t -{ - uop_type_t type; - int throughput; - int latency; +typedef struct risc86_uop_t { + uop_type_t type; + int throughput; + int latency; } risc86_uop_t; -typedef struct risc86_instruction_t -{ - int nr_uops; - decode_type_t decode_type; - risc86_uop_t uop[MAX_UOPS]; +typedef struct risc86_instruction_t { + int nr_uops; + decode_type_t decode_type; + risc86_uop_t uop[MAX_UOPS]; } risc86_instruction_t; -static const risc86_instruction_t alu_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t alux_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t alu_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t alux_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t branch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t limm_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t load_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} -}; - -static const risc86_instruction_t store_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; - - -static const risc86_instruction_t bswap_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t leave_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t lods_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t mov_reg_seg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, -}; -static const risc86_instruction_t movs_op = -{ - .nr_uops = 4, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t pop_reg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t pop_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t push_imm_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, -}; -static const risc86_instruction_t push_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t push_seg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t stos_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t test_reg_b_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t test_mem_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t test_mem_imm_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t xchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t m3dn_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t mmx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t mmx_mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} -}; -static const risc86_instruction_t mmx_shift_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t load_3dn_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t load_mmx_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t load_mmx_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} -}; -static const risc86_instruction_t load_mmx_shift_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t mload_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} -}; - -static const risc86_instruction_t mstore_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t pmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} -}; -static const risc86_instruction_t pmul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} -}; - -static const risc86_instruction_t float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} -}; -static const risc86_instruction_t load_float_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} -}; -static const risc86_instruction_t fstore_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t fdiv_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} -}; -static const risc86_instruction_t fdiv_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} -}; -static const risc86_instruction_t fsin_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} -}; -static const risc86_instruction_t fsqrt_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} -}; - -static const risc86_instruction_t vector_fldcw_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} -}; -static const risc86_instruction_t vector_float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} -}; -static const risc86_instruction_t vector_float_l_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} -}; -static const risc86_instruction_t vector_flde_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} -}; -static const risc86_instruction_t vector_fste_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, - .uop[1] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} -}; - -static const risc86_instruction_t vector_alu1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alu2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alu3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alu6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alux1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alux3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alux6_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alu_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_alux_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_arpl_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} -}; -static const risc86_instruction_t vector_bound_op = -{ - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_bsx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} -}; -static const risc86_instruction_t vector_call_far_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_cli_sti_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} -}; -static const risc86_instruction_t vector_cmps_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_cmpsb_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_cmpxchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, -}; -static const risc86_instruction_t vector_cmpxchg_b_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, -}; -static const risc86_instruction_t vector_cpuid_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} -}; -static const risc86_instruction_t vector_div16_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} -}; -static const risc86_instruction_t vector_div16_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} -}; -static const risc86_instruction_t vector_div32_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} -}; -static const risc86_instruction_t vector_div32_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} -}; -static const risc86_instruction_t vector_emms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} -}; -static const risc86_instruction_t vector_enter_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 10, .latency = 10} -}; -static const risc86_instruction_t vector_femms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} -}; -static const risc86_instruction_t vector_in_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} -}; -static const risc86_instruction_t vector_ins_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_int_op = -{ - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_iret_op = -{ - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_invd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} -}; -static const risc86_instruction_t vector_jmp_far_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_lss_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 3, .latency = 3} -}; -static const risc86_instruction_t vector_mov_mem_seg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_mov_seg_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} -}; -static const risc86_instruction_t vector_mov_seg_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} -}; -static const risc86_instruction_t vector_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_mul_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_mul64_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_out_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} -}; -static const risc86_instruction_t vector_outs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 10, .latency = 10}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_pusha_op = -{ - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_popa_op = -{ - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_popf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 17, .latency = 17} -}; -static const risc86_instruction_t vector_push_mem_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_pushf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_ret_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_retf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_scas_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_scasb_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_setcc_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_setcc_reg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_test_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_test_mem_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_xchg_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} -}; -static const risc86_instruction_t vector_xlat_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} -}; -static const risc86_instruction_t vector_wbinvd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} +static const risc86_instruction_t alu_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t branch_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t limm_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t load_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t store_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t bswap_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t leave_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t lods_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t loop_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t movs_op = { + .nr_uops = 4, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_reg_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_imm_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t push_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t stos_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_b_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_b_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t xchg_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t m3dn_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t mmx_shift_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_3dn_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t load_mmx_shift_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mload_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t mstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t pmul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t float_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t load_float_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t fstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t fdiv_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fdiv_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fsin_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} +}; +static const risc86_instruction_t fsqrt_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} +}; + +static const risc86_instruction_t vector_fldcw_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} +}; +static const risc86_instruction_t vector_float_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_float_l_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} +}; +static const risc86_instruction_t vector_flde_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_fste_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, + .uop[1] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t vector_alu1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu2_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu6_op = { + .nr_uops = 6, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux6_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_arpl_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_bound_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_bsx_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_call_far_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cli_sti_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} +}; +static const risc86_instruction_t vector_cmps_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpsb_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpxchg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cmpxchg_b_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cpuid_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} +}; +static const risc86_instruction_t vector_div16_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div16_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div32_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_div32_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_emms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} +}; +static const risc86_instruction_t vector_enter_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_femms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} +}; +static const risc86_instruction_t vector_in_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} +}; +static const risc86_instruction_t vector_ins_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_int_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_iret_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[3] = { .type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_invd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} +}; +static const risc86_instruction_t vector_jmp_far_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_loop_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_lss_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_mem_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mov_seg_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_seg_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_out_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_outs_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1 }, + .uop[1] = { .type = UOP_STORE, .throughput = 10, .latency = 10}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_pusha_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popa_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_LOAD, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 17, .latency = 17} +}; +static const risc86_instruction_t vector_push_mem_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_pushf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_ret_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_retf_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scas_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scasb_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_reg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_b_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xchg_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xlat_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t vector_wbinvd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} }; #define INVALID NULL -static const risc86_instruction_t *opcode_timings[256] = -{ +static const risc86_instruction_t *opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1007,10 +892,11 @@ static const risc86_instruction_t *opcode_timings[256] = &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, /* CLD STD INCDEC*/ &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_op, &alu_op, &alux_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1143,10 +1029,11 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, /* CLD STD INCDEC*/ &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f[256] = -{ +static const risc86_instruction_t *opcode_timings_0f[256] = { + // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, @@ -1226,9 +1113,10 @@ static const risc86_instruction_t *opcode_timings_0f[256] = INVALID, &pmul_mem_op, INVALID, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, @@ -1308,10 +1196,11 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] = INVALID, &pmul_op, INVALID, INVALID, &mmx_op, &mmx_op, &mmx_op, INVALID, &mmx_op, &mmx_op, &mmx_op, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f[256] = -{ +static const risc86_instruction_t *opcode_timings_0f0f[256] = { + // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1391,10 +1280,10 @@ static const risc86_instruction_t *opcode_timings_0f0f[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = { + // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1474,118 +1363,135 @@ static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift[8] = -{ +static const risc86_instruction_t *opcode_timings_shift[8] = { + // clang-format off &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_b[8] = { + // clang-format off &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_mod3[8] = { + // clang-format off &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = { + // clang-format off &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &alux_op, &alux_op, &alux_op, &alux_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_80[8] = -{ +static const risc86_instruction_t *opcode_timings_80[8] = { + // clang-format off &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_80_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_80_mod3[8] = { + // clang-format off &alux_op, &alux_op, &alux_store_op, &alux_store_op, &alux_op, &alux_op, &alux_op, &alux_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x[8] = -{ +static const risc86_instruction_t *opcode_timings_8x[8] = { + // clang-format off &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_8x_mod3[8] = { + // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6[8] = -{ +static const risc86_instruction_t *opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, /* MUL IMUL DIV IDIV*/ &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alux_op, &alux_op, /* MUL IMUL DIV IDIV*/ &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7[8] = -{ +static const risc86_instruction_t *opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, /* MUL IMUL DIV IDIV*/ &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, /* MUL IMUL DIV IDIV*/ &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff[8] = -{ +static const risc86_instruction_t *opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, /* JMP JMP far PUSH*/ &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, /* JMP JMP far PUSH*/ &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8[8] = -{ +static const risc86_instruction_t *opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FSUBs FSUBRs FDIVs FDIVRs*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ &float_op, &float_op, &float_op, &float_op, /* FSUB FSUBR FDIV FDIVR*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9[8] = -{ +static const risc86_instruction_t *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDENV FLDCW FSTENV FSTCW*/ &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = -{ +static const risc86_instruction_t *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, @@ -1614,31 +1520,35 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = &fdiv_op, INVALID, &fsqrt_op, &fsin_op, /* opFRNDINT opFSCALE opFSIN opFCOS*/ &float_op, &fdiv_op, &fsin_op, &fsin_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_da[8] = -{ +static const risc86_instruction_t *opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_da_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, &float_op, INVALID, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_db[8] = -{ +static const risc86_instruction_t *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ INVALID, &vector_flde_op, INVALID, &vector_fste_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = -{ +static const risc86_instruction_t *opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1664,108 +1574,113 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc[8] = -{ +static const risc86_instruction_t *opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FSUBd FSUBRd FDIVd FDIVRd*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ &float_op, &float_op, INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ &float_op, &float_op, &fdiv_op, &fdiv_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd[8] = -{ +static const risc86_instruction_t *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FRSTOR FSAVE FSTSW*/ &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, /* FUCOM FUCOMP*/ &float_op, &float_op, INVALID, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_de[8] = -{ +static const risc86_instruction_t *opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_de_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ &float_op, &float_op, INVALID, &float_op, /* FSUBP FSUBRP FDIVP FDIVRP*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_df[8] = -{ +static const risc86_instruction_t *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FILDiq FBSTP FISTPiq*/ INVALID, &load_float_op, &vector_float_l_op, &fstore_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_df_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ &float_op, INVALID, INVALID, INVALID + // clang-format on }; - static uint8_t last_prefix; -static int prefixes; +static int prefixes; static int decode_timestamp; static int last_complete_timestamp; -typedef struct k6_unit_t -{ - uint32_t uop_mask; - int first_available_cycle; +typedef struct k6_unit_t { + uint32_t uop_mask; + int first_available_cycle; } k6_unit_t; -static int nr_units; +static int nr_units; static k6_unit_t *units; /*K6 has dedicated MMX unit*/ -static k6_unit_t k6_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX)}, /*Integer X*/ - {.uop_mask = (1 << UOP_ALU)}, /*Integer Y*/ - {.uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL)}, /*Multimedia*/ - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +static k6_unit_t k6_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) }, /*Integer X*/ + { .uop_mask = (1 << UOP_ALU) }, /*Integer Y*/ + { .uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) }, /*Multimedia*/ + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ }; #define NR_K6_UNITS (sizeof(k6_units) / sizeof(k6_unit_t)) /*K6-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and 3DNow ALU between two execution units*/ -static k6_unit_t k6_2_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +static k6_unit_t k6_2_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ }; #define NR_K6_2_UNITS (sizeof(k6_2_units) / sizeof(k6_unit_t)) @@ -1775,57 +1690,52 @@ static int mul_first_available_cycle; static int shift_first_available_cycle; static int m3dnow_first_available_cycle; -static int uop_run(const risc86_uop_t *uop, int decode_time) -{ - int c; - k6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; - - /*UOP_LIMM does not require execution*/ - if (uop->type == UOP_LIMM) - return decode_time; - - /*Handle shared units on K6-2 and later*/ - if (units == k6_2_units) - { - if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) - decode_time = mul_first_available_cycle; - else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) - decode_time = shift_first_available_cycle; - else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) - decode_time = m3dnow_first_available_cycle; +static int +uop_run(const risc86_uop_t *uop, int decode_time) +{ + k6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; + + /*UOP_LIMM does not require execution*/ + if (uop->type == UOP_LIMM) + return decode_time; + + /*Handle shared units on K6-2 and later*/ + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) + decode_time = mul_first_available_cycle; + else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) + decode_time = shift_first_available_cycle; + else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) + decode_time = m3dnow_first_available_cycle; + } + + /*Find execution unit for this uOP*/ + for (int c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } } - - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) - { - if (units[c].uop_mask & (1 << uop->type)) - { - if (units[c].first_available_cycle < best_start_cycle) - { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; - } - } - } - if (!best_unit) - fatal("uop_run: can not find execution unit\n"); - - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->throughput; - - if (units == k6_2_units) - { - if (uop->type == UOP_MEU_MUL) - mul_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_SHIFT) - shift_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_3DN) - m3dnow_first_available_cycle = best_start_cycle + uop->throughput; - } - - return best_start_cycle + uop->throughput; + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); + + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; + + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL) + mul_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_SHIFT) + shift_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_3DN) + m3dnow_first_available_cycle = best_start_cycle + uop->throughput; + } + + return best_start_cycle + uop->throughput; } /*The K6 decoder can decode, per clock : @@ -1833,14 +1743,13 @@ static int uop_run(const risc86_uop_t *uop, int decode_time) - 1 'long' instruction, up to 4 uOPs - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay) */ -static struct -{ - int nr_uops; - const risc86_uop_t *uops[4]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is - part of a dependency chain and the start time is the completion time of - the previous uop*/ - int earliest_start[4]; +static struct { + int nr_uops; + const risc86_uop_t *uops[4]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[4]; } decode_buffer; #define NR_OPQUADS 6 @@ -1858,495 +1767,465 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush(void) +void +decode_flush(void) { - int c; - int uop_timestamp = 0; + int uop_timestamp = 0; - /*Decoded opquad can not be submitted if there are no free spaces in the - opquad buffer*/ - if (decode_timestamp < opquad_completion_timestamp[next_opquad]) - decode_timestamp = opquad_completion_timestamp[next_opquad]; + /*Decoded opquad can not be submitted if there are no free spaces in the + opquad buffer*/ + if (decode_timestamp < opquad_completion_timestamp[next_opquad]) + decode_timestamp = opquad_completion_timestamp[next_opquad]; - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < decode_buffer.nr_uops; c++) - { - int start_timestamp; + /*Submit uops to execution units, and determine the latest completion time*/ + for (int c = 0; c < decode_buffer.nr_uops; c++) { + int start_timestamp; - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; - - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } - - /*Calculate opquad completion time. Since opquads complete in order, it - must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; else - last_complete_timestamp = uop_timestamp; - - /*Advance to next opquad in buffer*/ - opquad_completion_timestamp[next_opquad] = last_complete_timestamp; - next_opquad++; - if (next_opquad == NR_OPQUADS) - next_opquad = 0; + start_timestamp = decode_buffer.earliest_start[c]; + + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } + + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opquad in buffer*/ + opquad_completion_timestamp[next_opquad] = last_complete_timestamp; + next_opquad++; + if (next_opquad == NR_OPQUADS) + next_opquad = 0; - decode_timestamp++; - decode_buffer.nr_uops = 0; + decode_timestamp++; + decode_buffer.nr_uops = 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on K6 short decoding*/ -static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) -{ - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) - { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; - - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } +static int +codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +{ + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) -{ - uint32_t regmask_required; - uint32_t regmask_modified; - int c, d; - int earliest_start = 0; - decode_type_t decode_type = ins->decode_type; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - - /*Generate input register mask, and determine the earliest time this - instruction can start. This is not accurate, as this is calculated per - x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) - { - if (regmask_required & (1 << c)) - { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } - } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) - { - int reg = fetchdat & 7; - - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; +static void +decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +{ + uint32_t regmask_required; + uint32_t regmask_modified; + int c; + int d; + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if (deps & FPU_RW_STREG) { + int reg = fetchdat & 7; + + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } + + /*Short decoders are limited to 7 bytes*/ + if (decode_type == DECODE_SHORT && instr_length > 7) + decode_type = DECODE_LONG; + /*Long decoder is limited to 11 bytes*/ + else if (instr_length > 11) + decode_type = DECODE_VECTOR; + + switch (decode_type) { + case DECODE_SHORT: + if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1]; + decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1; + } + decode_buffer.nr_uops += ins->nr_uops; - /*Short decoders are limited to 7 bytes*/ - if (decode_type == DECODE_SHORT && instr_length > 7) - decode_type = DECODE_LONG; - /*Long decoder is limited to 11 bytes*/ - else if (instr_length > 11) - decode_type = DECODE_VECTOR; - - switch (decode_type) - { - case DECODE_SHORT: - if (decode_buffer.nr_uops) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - if (ins->nr_uops > 1) - { - decode_buffer.uops[decode_buffer.nr_uops+1] = &ins->uop[1]; - decode_buffer.earliest_start[decode_buffer.nr_uops+1] = -1; - } - decode_buffer.nr_uops += ins->nr_uops; - - decode_flush(); + decode_flush(); + } else { + decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[1] = &ins->uop[1]; + decode_buffer.earliest_start[1] = -1; } + } + break; + + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush(); + + decode_buffer.nr_uops = ins->nr_uops; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; else - { - decode_buffer.nr_uops = ins->nr_uops; - decode_buffer.uops[0] = &ins->uop[0]; - decode_buffer.earliest_start[0] = earliest_start; - if (ins->nr_uops > 1) - { - decode_buffer.uops[1] = &ins->uop[1]; - decode_buffer.earliest_start[1] = -1; - } - } - break; - - case DECODE_LONG: - if (decode_buffer.nr_uops) - decode_flush(); - - decode_buffer.nr_uops = ins->nr_uops; - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[c] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[c] = earliest_start; - else - decode_buffer.earliest_start[c] = -1; - } + decode_buffer.earliest_start[c] = -1; + } + decode_flush(); + break; + + case DECODE_VECTOR: + if (decode_buffer.nr_uops) decode_flush(); - break; - - case DECODE_VECTOR: - if (decode_buffer.nr_uops) - decode_flush(); - - decode_timestamp++; - d = 0; - - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; - - if (d == 4) - { - d = 0; - decode_buffer.nr_uops = 4; - decode_flush(); - } - } - if (d) - { - decode_buffer.nr_uops = d; - decode_flush(); - } - break; - } - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) - { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } + decode_timestamp++; + d = 0; + + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if (d == 4) { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) { + decode_buffer.nr_uops = d; + decode_flush(); + } + break; + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps & FPU_POP) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) - { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } } -void codegen_timing_k6_block_start(void) +void +codegen_timing_k6_block_start(void) { - int c; + int c; - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; - mul_first_available_cycle = 0; - shift_first_available_cycle = 0; - m3dnow_first_available_cycle = 0; + mul_first_available_cycle = 0; + shift_first_available_cycle = 0; + m3dnow_first_available_cycle = 0; - decode_timestamp = 0; - last_complete_timestamp = 0; + decode_timestamp = 0; + last_complete_timestamp = 0; - for (c = 0; c < NR_OPQUADS; c++) - opquad_completion_timestamp[c] = 0; - next_opquad = 0; + for (c = 0; c < NR_OPQUADS; c++) + opquad_completion_timestamp[c] = 0; + next_opquad = 0; - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; } -void codegen_timing_k6_start(void) -{ - if (cpu_s->cpu_type == CPU_K6) - { - units = k6_units; - nr_units = NR_K6_UNITS; - } - else - { - units = k6_2_units; - nr_units = NR_K6_2_UNITS; - } - last_prefix = 0; - prefixes = 0; +void +codegen_timing_k6_start(void) +{ + if (cpu_s->cpu_type == CPU_K6) { + units = k6_units; + nr_units = NR_K6_UNITS; + } else { + units = k6_2_units; + nr_units = NR_K6_2_UNITS; + } + last_prefix = 0; + prefixes = 0; } -void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix != 0x0f) - decode_timestamp++; + if (prefix != 0x0f) + decode_timestamp++; - last_prefix = prefix; - prefixes++; + last_prefix = prefix; + prefixes++; } -void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - const risc86_instruction_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - if (opcode == 0x0f) - { - /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ - uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; - - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 7) == 4) - { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } +void +codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +{ + const risc86_instruction_t **ins_table; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + if (opcode == 0x0f) { + /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ + uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; } - - opcode = fastreadb(cs + opcode_pc); - - ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; - deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } } - else - { - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - } - break; - - case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; - default: - switch (opcode) - { - case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } + opcode = fastreadb(cs + opcode_pc); + + ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; + deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } else { + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + } + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); - else - decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + default: + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } -void codegen_timing_k6_block_end(void) +void +codegen_timing_k6_block_end(void) { - if (decode_buffer.nr_uops) - { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } -int codegen_timing_k6_jump_cycles(void) +int +codegen_timing_k6_jump_cycles(void) { - if (decode_buffer.nr_uops) - return 1; - return 0; + if (decode_buffer.nr_uops) + return 1; + return 0; } -codegen_timing_t codegen_timing_k6 = -{ - codegen_timing_k6_start, - codegen_timing_k6_prefix, - codegen_timing_k6_opcode, - codegen_timing_k6_block_start, - codegen_timing_k6_block_end, - codegen_timing_k6_jump_cycles +codegen_timing_t codegen_timing_k6 = { + codegen_timing_k6_start, + codegen_timing_k6_prefix, + codegen_timing_k6_opcode, + codegen_timing_k6_block_start, + codegen_timing_k6_block_end, + codegen_timing_k6_jump_cycles }; diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index cf40e084e1..2c087ae86c 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -8,902 +8,786 @@ #include "cpu.h" #include <86box/mem.h> #include <86box/machine.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_ops.h" #include "codegen_timing_common.h" -typedef enum uop_type_t -{ - UOP_ALU = 0, /*Executes in Port 0 or 1 ALU units*/ - UOP_ALUP0, /*Executes in Port 0 ALU unit*/ - UOP_LOAD, /*Executes in Load unit*/ - UOP_STORED, /*Executes in Data Store unit*/ - UOP_STOREA, /*Executes in Address Store unit*/ - UOP_FLOAD, /*Executes in Load unit*/ - UOP_FSTORED, /*Executes in Data Store unit*/ - UOP_FSTOREA, /*Executes in Address Store unit*/ - UOP_MLOAD, /*Executes in Load unit*/ - UOP_MSTORED, /*Executes in Data Store unit*/ - UOP_MSTOREA, /*Executes in Address Store unit*/ - UOP_FLOAT, /*Executes in Floating Point unit*/ - UOP_MMX, /*Executes in Port 0 or 1 ALU units as MMX*/ - UOP_MMX_SHIFT, /*Executes in Port 1 ALU unit. Uses MMX shifter*/ - UOP_MMX_MUL, /*Executes in Port 0 ALU unit. Uses MMX multiplier*/ - UOP_BRANCH, /*Executes in Branch unit*/ - UOP_FXCH /*Does not require an execution unit*/ +typedef enum uop_type_t { + UOP_ALU = 0, /*Executes in Port 0 or 1 ALU units*/ + UOP_ALUP0, /*Executes in Port 0 ALU unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORED, /*Executes in Data Store unit*/ + UOP_STOREA, /*Executes in Address Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORED, /*Executes in Data Store unit*/ + UOP_FSTOREA, /*Executes in Address Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORED, /*Executes in Data Store unit*/ + UOP_MSTOREA, /*Executes in Address Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MMX, /*Executes in Port 0 or 1 ALU units as MMX*/ + UOP_MMX_SHIFT, /*Executes in Port 1 ALU unit. Uses MMX shifter*/ + UOP_MMX_MUL, /*Executes in Port 0 ALU unit. Uses MMX multiplier*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_FXCH /*Does not require an execution unit*/ } uop_type_t; -typedef enum decode_type_t -{ - DECODE_SIMPLE, - DECODE_COMPLEX, +typedef enum decode_type_t { + DECODE_SIMPLE, + DECODE_COMPLEX, } decode_type_t; #define MAX_UOPS 10 -typedef struct p6_uop_t -{ - uop_type_t type; - int latency; +typedef struct p6_uop_t { + uop_type_t type; + int latency; } p6_uop_t; -typedef struct macro_op_t -{ - int nr_uops; - decode_type_t decode_type; - p6_uop_t uop[MAX_UOPS]; +typedef struct macro_op_t { + int nr_uops; + decode_type_t decode_type; + p6_uop_t uop[MAX_UOPS]; } macro_op_t; -static const macro_op_t alu_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t alup0_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t load_alup0_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t alu_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; -static const macro_op_t alup0_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; - -static const macro_op_t branch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_BRANCH, .latency = 2} -}; - -static const macro_op_t fxch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FXCH, .latency = 1} -}; - -static const macro_op_t load_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_LOAD, .latency = 1} -}; - -static const macro_op_t store_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1} -}; - - -static const macro_op_t bswap_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, -}; -static const macro_op_t leave_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t lods_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t loop_op = -{ - .nr_uops = 5, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1}, - .uop[4] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t mov_reg_seg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, -}; -static const macro_op_t movs_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t pop_reg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t pop_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t push_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1}, -}; -static const macro_op_t push_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} -}; -static const macro_op_t push_seg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t stos_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t test_reg_b_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t test_mem_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t test_mem_imm_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t xchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; - - -static const macro_op_t mmx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX, .latency = 1} -}; -static const macro_op_t mmx_mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} -}; -static const macro_op_t mmx_shift_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} -}; -static const macro_op_t load_mmx_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX, .latency = 2} -}; -static const macro_op_t load_mmx_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} -}; -static const macro_op_t load_mmx_shift_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 2} -}; -static const macro_op_t mload_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MLOAD, .latency = 1}, -}; - -static const macro_op_t mstore_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MSTORED, .latency = 1}, - .uop[1] = {.type = UOP_MSTOREA, .latency = 1} -}; -static const macro_op_t pmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} -}; -static const macro_op_t pmul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} -}; -static const macro_op_t float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 1} -}; -static const macro_op_t fadd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 2} -}; -static const macro_op_t fmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 3} -}; -static const macro_op_t float2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1} -}; -static const macro_op_t fchs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .latency = 2} -}; -static const macro_op_t load_float_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1} -}; -static const macro_op_t load_fadd_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 2} -}; -static const macro_op_t load_fmul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 4} -}; -static const macro_op_t fstore_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FSTORED, .latency = 1}, - .uop[1] = {.type = UOP_FSTOREA, .latency = 1}, -}; -static const macro_op_t load_fiadd_op = -{ - .nr_uops = 7, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .latency = 1}, - .uop[3] = {.type = UOP_FLOAT, .latency = 1}, - .uop[4] = {.type = UOP_FLOAT, .latency = 1}, - .uop[5] = {.type = UOP_FLOAT, .latency = 1}, - .uop[6] = {.type = UOP_FLOAT, .latency = 1} -}; -static const macro_op_t fdiv_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 37} -}; -static const macro_op_t fdiv_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 37} -}; -static const macro_op_t fsin_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 62} -}; -static const macro_op_t fsqrt_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 69} -}; - -static const macro_op_t fldcw_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 10} -}; -static const macro_op_t complex_float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 1} -}; -static const macro_op_t complex_float_l_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 50} -}; -static const macro_op_t flde_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAD, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .latency = 2} -}; -static const macro_op_t fste_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 2}, - .uop[1] = {.type = UOP_FSTORED, .latency = 1}, - .uop[2] = {.type = UOP_FSTOREA, .latency = 1} -}; - -static const macro_op_t complex_alu1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t alu2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t alu3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t alu6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1}, - .uop[4] = {.type = UOP_ALU, .latency = 1}, - .uop[5] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t complex_alup0_1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t alup0_3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t alup0_6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1}, - .uop[3] = {.type = UOP_ALUP0, .latency = 1}, - .uop[4] = {.type = UOP_ALUP0, .latency = 1}, - .uop[5] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t arpl_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_ALU, .latency = 3} -}; -static const macro_op_t bound_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t bsx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 10} -}; -static const macro_op_t call_far_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t cli_sti_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 7} -}; -static const macro_op_t cmps_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t cmpsb_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t cmpxchg_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; -static const macro_op_t cmpxchg_b_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; -static const macro_op_t complex_push_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1} -}; - -static const macro_op_t cpuid_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 23} -}; -static const macro_op_t div16_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 21} -}; -static const macro_op_t div16_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 21} -}; -static const macro_op_t div32_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 37} -}; -static const macro_op_t div32_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 37} -}; -static const macro_op_t emms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 50} -}; -static const macro_op_t enter_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 10} -}; -static const macro_op_t femms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 6} -}; -static const macro_op_t in_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 18} -}; -static const macro_op_t ins_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 18}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t int_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 20}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_STORED, .latency = 1}, - .uop[4] = {.type = UOP_STOREA, .latency = 1}, - .uop[5] = {.type = UOP_STORED, .latency = 1}, - .uop[6] = {.type = UOP_STOREA, .latency = 1}, - .uop[7] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t iret_op = -{ - .nr_uops = 5, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_LOAD, .latency = 3}, - .uop[2] = {.type = UOP_LOAD, .latency = 3}, - .uop[3] = {.type = UOP_ALU, .latency = 20}, - .uop[4] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t invd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 500} -}; -static const macro_op_t jmp_far_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t lss_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 3} -}; -static const macro_op_t mov_mem_seg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, -}; -static const macro_op_t mov_seg_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 3} -}; -static const macro_op_t mov_seg_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3} -}; -static const macro_op_t mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t mul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t mul64_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1}, - .uop[3] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t out_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 18} -}; -static const macro_op_t outs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 18} -}; -static const macro_op_t pusha_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 2}, - .uop[1] = {.type = UOP_STOREA, .latency = 2}, - .uop[2] = {.type = UOP_STORED, .latency = 2}, - .uop[3] = {.type = UOP_STOREA, .latency = 2}, - .uop[4] = {.type = UOP_STORED, .latency = 2}, - .uop[5] = {.type = UOP_STOREA, .latency = 2}, - .uop[6] = {.type = UOP_STORED, .latency = 2}, - .uop[7] = {.type = UOP_STOREA, .latency = 2} -}; -static const macro_op_t popa_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .latency = 1} -}; -static const macro_op_t popf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 6}, - .uop[2] = {.type = UOP_ALUP0, .latency = 10} -}; -static const macro_op_t pushf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} -}; -static const macro_op_t ret_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t retf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 3}, - .uop[2] = {.type = UOP_BRANCH, .latency = 1} -}; -static const macro_op_t scas_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t scasb_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t setcc_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_FSTORED, .latency = 1}, - .uop[3] = {.type = UOP_FSTOREA, .latency = 1} -}; -static const macro_op_t setcc_reg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t test_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t test_mem_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} -}; -static const macro_op_t xchg_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} -}; -static const macro_op_t xlat_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1} -}; -static const macro_op_t wbinvd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 10000} +static const macro_op_t alu_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALU, .latency = 1} +}; +static const macro_op_t alup0_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t load_alup0_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t alu_store_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} +}; +static const macro_op_t alup0_store_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} +}; + +static const macro_op_t branch_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_BRANCH, .latency = 2} +}; + +static const macro_op_t fxch_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FXCH, .latency = 1} +}; + +static const macro_op_t load_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_LOAD, .latency = 1} +}; + +static const macro_op_t store_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1} +}; + +static const macro_op_t bswap_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, +}; +static const macro_op_t leave_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t lods_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t loop_op = { + .nr_uops = 5, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1}, + .uop[4] = { .type = UOP_BRANCH, .latency = 1} +}; +static const macro_op_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, +}; +static const macro_op_t movs_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t pop_reg_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t pop_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t push_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1}, +}; +static const macro_op_t push_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1} +}; +static const macro_op_t push_seg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t stos_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[1] = {.type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t test_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1} +}; +static const macro_op_t test_reg_b_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t test_mem_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t test_mem_imm_b_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t xchg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; + +static const macro_op_t mmx_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX, .latency = 1} +}; +static const macro_op_t mmx_mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} +}; +static const macro_op_t mmx_shift_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} +}; +static const macro_op_t load_mmx_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX, .latency = 2} +}; +static const macro_op_t load_mmx_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_MUL, .latency = 2} +}; +static const macro_op_t load_mmx_shift_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_SHIFT, .latency = 2} +}; +static const macro_op_t mload_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_MLOAD, .latency = 1}, +}; + +static const macro_op_t mstore_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_MSTORED, .latency = 1}, + .uop[1] = { .type = UOP_MSTOREA, .latency = 1} +}; +static const macro_op_t pmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} +}; +static const macro_op_t pmul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_MUL, .latency = 2} +}; +static const macro_op_t float_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 1} +}; +static const macro_op_t fadd_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 2} +}; +static const macro_op_t fmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 3} +}; +static const macro_op_t float2_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1} +}; +static const macro_op_t fchs_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 2}, + .uop[1] = { .type = UOP_FLOAT, .latency = 2}, + .uop[2] = { .type = UOP_FLOAT, .latency = 2} +}; +static const macro_op_t load_float_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1} +}; +static const macro_op_t load_fadd_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 2} +}; +static const macro_op_t load_fmul_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 4} +}; +static const macro_op_t fstore_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FSTORED, .latency = 1}, + .uop[1] = { .type = UOP_FSTOREA, .latency = 1}, +}; +static const macro_op_t load_fiadd_op = { + .nr_uops = 7, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1}, + .uop[2] = { .type = UOP_FLOAT, .latency = 1}, + .uop[3] = { .type = UOP_FLOAT, .latency = 1}, + .uop[4] = { .type = UOP_FLOAT, .latency = 1}, + .uop[5] = { .type = UOP_FLOAT, .latency = 1}, + .uop[6] = { .type = UOP_FLOAT, .latency = 1} +}; +static const macro_op_t fdiv_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 37} +}; +static const macro_op_t fdiv_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1 }, + .uop[1] = { .type = UOP_FLOAT, .latency = 37} +}; +static const macro_op_t fsin_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 62} +}; +static const macro_op_t fsqrt_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 69} +}; + +static const macro_op_t fldcw_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 10} +}; +static const macro_op_t complex_float_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 1} +}; +static const macro_op_t complex_float_l_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 50} +}; +static const macro_op_t flde_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAD, .latency = 1}, + .uop[2] = { .type = UOP_FLOAT, .latency = 2} +}; +static const macro_op_t fste_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 2}, + .uop[1] = { .type = UOP_FSTORED, .latency = 1}, + .uop[2] = { .type = UOP_FSTOREA, .latency = 1} +}; + +static const macro_op_t complex_alu1_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1} +}; +static const macro_op_t alu2_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t alu3_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t alu6_op = { + .nr_uops = 6, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1}, + .uop[4] = { .type = UOP_ALU, .latency = 1}, + .uop[5] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t complex_alup0_1_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t alup0_3_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t alup0_6_op = { + .nr_uops = 6, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1}, + .uop[3] = { .type = UOP_ALUP0, .latency = 1}, + .uop[4] = { .type = UOP_ALUP0, .latency = 1}, + .uop[5] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t arpl_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_ALU, .latency = 3} +}; +static const macro_op_t bound_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t bsx_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 10} +}; +static const macro_op_t call_far_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_BRANCH, .latency = 1} +}; +static const macro_op_t cli_sti_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 7} +}; +static const macro_op_t cmps_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t cmpsb_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t cmpxchg_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} +}; +static const macro_op_t cmpxchg_b_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} +}; +static const macro_op_t complex_push_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1} +}; + +static const macro_op_t cpuid_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 23} +}; +static const macro_op_t div16_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 21} +}; +static const macro_op_t div16_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALUP0, .latency = 21} +}; +static const macro_op_t div32_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 37} +}; +static const macro_op_t div32_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALUP0, .latency = 37} +}; +static const macro_op_t emms_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 50} +}; +static const macro_op_t enter_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1 }, + .uop[1] = { .type = UOP_STOREA, .latency = 1 }, + .uop[2] = { .type = UOP_ALU, .latency = 10} +}; +static const macro_op_t femms_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 6} +}; +static const macro_op_t in_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 18} +}; +static const macro_op_t ins_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 18}, + .uop[1] = { .type = UOP_STORED, .latency = 1 }, + .uop[2] = { .type = UOP_STOREA, .latency = 1 }, + .uop[3] = { .type = UOP_ALU, .latency = 1 } +}; +static const macro_op_t int_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 20}, + .uop[1] = { .type = UOP_STORED, .latency = 1 }, + .uop[2] = { .type = UOP_STOREA, .latency = 1 }, + .uop[3] = { .type = UOP_STORED, .latency = 1 }, + .uop[4] = { .type = UOP_STOREA, .latency = 1 }, + .uop[5] = { .type = UOP_STORED, .latency = 1 }, + .uop[6] = { .type = UOP_STOREA, .latency = 1 }, + .uop[7] = { .type = UOP_BRANCH, .latency = 1 } +}; +static const macro_op_t iret_op = { + .nr_uops = 5, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 3 }, + .uop[1] = { .type = UOP_LOAD, .latency = 3 }, + .uop[2] = { .type = UOP_LOAD, .latency = 3 }, + .uop[3] = { .type = UOP_ALU, .latency = 20}, + .uop[4] = { .type = UOP_BRANCH, .latency = 1 } +}; +static const macro_op_t invd_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 500} +}; +static const macro_op_t jmp_far_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_BRANCH, .latency = 1} +}; +static const macro_op_t lss_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 3} +}; +static const macro_op_t mov_mem_seg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, +}; +static const macro_op_t mov_seg_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 3} +}; +static const macro_op_t mov_seg_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3} +}; +static const macro_op_t mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t mul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t mul64_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t mul64_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1}, + .uop[3] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t out_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 18} +}; +static const macro_op_t outs_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALU, .latency = 18} +}; +static const macro_op_t pusha_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 2}, + .uop[1] = { .type = UOP_STOREA, .latency = 2}, + .uop[2] = { .type = UOP_STORED, .latency = 2}, + .uop[3] = { .type = UOP_STOREA, .latency = 2}, + .uop[4] = { .type = UOP_STORED, .latency = 2}, + .uop[5] = { .type = UOP_STOREA, .latency = 2}, + .uop[6] = { .type = UOP_STORED, .latency = 2}, + .uop[7] = { .type = UOP_STOREA, .latency = 2} +}; +static const macro_op_t popa_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_LOAD, .latency = 1}, + .uop[3] = { .type = UOP_LOAD, .latency = 1}, + .uop[4] = { .type = UOP_LOAD, .latency = 1}, + .uop[5] = { .type = UOP_LOAD, .latency = 1}, + .uop[6] = { .type = UOP_LOAD, .latency = 1}, + .uop[7] = { .type = UOP_LOAD, .latency = 1} +}; +static const macro_op_t popf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALU, .latency = 6 }, + .uop[2] = { .type = UOP_ALUP0, .latency = 10} +}; +static const macro_op_t pushf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1} +}; +static const macro_op_t ret_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .latency = 1} +}; +static const macro_op_t retf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 3}, + .uop[2] = { .type = UOP_BRANCH, .latency = 1} +}; +static const macro_op_t scas_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t scasb_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t setcc_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_FSTORED, .latency = 1}, + .uop[3] = { .type = UOP_FSTOREA, .latency = 1} +}; +static const macro_op_t setcc_reg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t test_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t test_mem_b_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} +}; +static const macro_op_t xchg_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} +}; +static const macro_op_t xlat_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1} +}; +static const macro_op_t wbinvd_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 10000} }; #define INVALID NULL -static const macro_op_t *opcode_timings[256] = -{ +static const macro_op_t *opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1036,10 +920,11 @@ static const macro_op_t *opcode_timings[256] = &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ &complex_alu1_op, &complex_alu1_op, &alup0_store_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_mod3[256] = -{ +static const macro_op_t *opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1173,10 +1058,11 @@ static const macro_op_t *opcode_timings_mod3[256] = &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ &complex_alu1_op, &complex_alu1_op, &complex_alup0_1_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_0f[256] = -{ +static const macro_op_t *opcode_timings_0f[256] = { + // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, &invd_op, &wbinvd_op, INVALID, INVALID, @@ -1256,9 +1142,10 @@ static const macro_op_t *opcode_timings_0f[256] = INVALID, &pmul_mem_op, INVALID, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + // clang-format on }; -static const macro_op_t *opcode_timings_0f_mod3[256] = -{ +static const macro_op_t *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, &invd_op, &wbinvd_op, INVALID, INVALID, @@ -1342,113 +1229,131 @@ static const macro_op_t *opcode_timings_0f_mod3[256] = static const macro_op_t *opcode_timings_shift[8] = { + // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_b[8] = -{ +static const macro_op_t *opcode_timings_shift_b[8] = { + // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_mod3[8] = -{ +static const macro_op_t *opcode_timings_shift_mod3[8] = { + // clang-format off &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_b_mod3[8] = -{ +static const macro_op_t *opcode_timings_shift_b_mod3[8] = { + // clang-format off &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op + // clang-format on }; -static const macro_op_t *opcode_timings_80[8] = -{ +static const macro_op_t *opcode_timings_80[8] = { + // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, + // clang-format on }; -static const macro_op_t *opcode_timings_80_mod3[8] = -{ +static const macro_op_t *opcode_timings_80_mod3[8] = { + // clang-format off &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op, + // clang-format on }; -static const macro_op_t *opcode_timings_8x[8] = -{ +static const macro_op_t *opcode_timings_8x[8] = { + // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, + // clang-format on }; -static const macro_op_t *opcode_timings_8x_mod3[8] = -{ +static const macro_op_t *opcode_timings_8x_mod3[8] = { + // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f6[8] = -{ +static const macro_op_t *opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op, /* MUL IMUL DIV IDIV*/ &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f6_mod3[8] = -{ +static const macro_op_t *opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alup0_op, &alup0_op, /* MUL IMUL DIV IDIV*/ &mul_op, &mul_op, &div16_op, &div16_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f7[8] = -{ +static const macro_op_t *opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op, /* MUL IMUL DIV IDIV*/ &mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f7_mod3[8] = -{ +static const macro_op_t *opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, /* MUL IMUL DIV IDIV*/ &mul64_op, &mul64_op, &div32_op, &div32_op, + // clang-format on }; -static const macro_op_t *opcode_timings_ff[8] = -{ +static const macro_op_t *opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ &branch_op, &jmp_far_op, &push_mem_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_ff_mod3[8] = -{ +static const macro_op_t *opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ &branch_op, &jmp_far_op, &complex_push_mem_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_d8[8] = -{ +static const macro_op_t *opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FSUBs FSUBRs FDIVs FDIVRs*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_d8_mod3[8] = -{ +static const macro_op_t *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ &fadd_op, &fmul_op, &float_op, &float_op, /* FSUB FSUBR FDIV FDIVR*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const macro_op_t *opcode_timings_d9[8] = -{ +static const macro_op_t *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDENV FLDCW FSTENV FSTCW*/ &complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op + // clang-format on }; -static const macro_op_t *opcode_timings_d9_mod3[64] = -{ +static const macro_op_t *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, @@ -1477,31 +1382,35 @@ static const macro_op_t *opcode_timings_d9_mod3[64] = &fdiv_op, INVALID, &fsqrt_op, &fsin_op, /* opFRNDINT opFSCALE opFSIN opFCOS*/ &float_op, &fdiv_op, &fsin_op, &fsin_op + // clang-format on }; -static const macro_op_t *opcode_timings_da[8] = -{ +static const macro_op_t *opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_da_mod3[8] = -{ +static const macro_op_t *opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, &float_op, INVALID, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_db[8] = -{ +static const macro_op_t *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ INVALID, &flde_op, INVALID, &fste_op + // clang-format on }; -static const macro_op_t *opcode_timings_db_mod3[64] = -{ +static const macro_op_t *opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1527,153 +1436,152 @@ static const macro_op_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static const macro_op_t *opcode_timings_dc[8] = -{ +static const macro_op_t *opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FSUBd FSUBRd FDIVd FDIVRd*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_dc_mod3[8] = -{ +static const macro_op_t *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ &fadd_op, &fmul_op, INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ &float_op, &float_op, &fdiv_op, &fdiv_op + // clang-format on }; -static const macro_op_t *opcode_timings_dd[8] = -{ +static const macro_op_t *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FRSTOR FSAVE FSTSW*/ &complex_float_l_op, INVALID, &complex_float_l_op, &complex_float_l_op + // clang-format on }; -static const macro_op_t *opcode_timings_dd_mod3[8] = -{ +static const macro_op_t *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, /* FUCOM FUCOMP*/ &float_op, &float_op, INVALID, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_de[8] = -{ +static const macro_op_t *opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, + // clang-format on }; -static const macro_op_t *opcode_timings_de_mod3[8] = -{ +static const macro_op_t *opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ &fadd_op, &fmul_op, INVALID, &float_op, /* FSUBP FSUBRP FDIVP FDIVRP*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const macro_op_t *opcode_timings_df[8] = -{ +static const macro_op_t *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FILDiq FBSTP FISTPiq*/ INVALID, &load_float_op, &complex_float_l_op, &fstore_op, + // clang-format on }; -static const macro_op_t *opcode_timings_df_mod3[8] = -{ +static const macro_op_t *opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ &float_op, INVALID, INVALID, INVALID + // clang-format on }; - static uint8_t last_prefix; -static int prefixes; +static int prefixes; static int decode_timestamp; static int last_complete_timestamp; -typedef struct p6_unit_t -{ - uint32_t uop_mask; - double first_available_cycle; +typedef struct p6_unit_t { + uint32_t uop_mask; + double first_available_cycle; } p6_unit_t; -static int nr_units; +static int nr_units; static p6_unit_t *units; /*Pentium Pro has no MMX*/ -static p6_unit_t ppro_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT)}, /*Port 0*/ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH)}, /*Port 1*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD)}, /*Port 2*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED)}, /*Port 3*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA)}, /*Port 4*/ +static p6_unit_t ppro_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) }, /*Port 0*/ + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) }, /*Port 1*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) }, /*Port 2*/ + { .uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) }, /*Port 3*/ + { .uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) }, /*Port 4*/ }; #define NR_PPRO_UNITS (sizeof(ppro_units) / sizeof(p6_unit_t)) /*Pentium II/Celeron assigns the multiplier to port 0, the shifter to port 1, and shares the MMX ALU*/ -static p6_unit_t p2_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) | /*Port 0*/ - (1 << UOP_MMX) | (1 << UOP_MMX_MUL)}, - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) | /*Port 1*/ - (1 << UOP_MMX) | (1 << UOP_MMX_SHIFT)}, - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Port 2*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED)}, /*Port 3*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA)}, /*Port 4*/ +static p6_unit_t p2_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) | /*Port 0*/ + (1 << UOP_MMX) | (1 << UOP_MMX_MUL) }, + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) | /*Port 1*/ + (1 << UOP_MMX) | (1 << UOP_MMX_SHIFT) }, + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Port 2*/ + { .uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED) }, /*Port 3*/ + { .uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA) }, /*Port 4*/ }; #define NR_P2_UNITS (sizeof(p2_units) / sizeof(p6_unit_t)) -static int uop_run(const p6_uop_t *uop, int decode_time) +static int +uop_run(const p6_uop_t *uop, int decode_time) { - int c; - p6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; - - /*UOP_FXCH does not require execution*/ - if (uop->type == UOP_FXCH) - return decode_time; - - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) - { - if (units[c].uop_mask & (1 << uop->type)) - { - if (units[c].first_available_cycle < best_start_cycle) - { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; - } - } - } - if (!best_unit) - fatal("uop_run: can not find execution unit\n"); + p6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->latency; + /*UOP_FXCH does not require execution*/ + if (uop->type == UOP_FXCH) + return decode_time; + /*Find execution unit for this uOP*/ + for (int c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->latency; - return best_start_cycle + uop->latency; + return best_start_cycle + uop->latency; } /*The P6 decoders can decode, per clock : - 1 to 3 'simple' instructions, each up to 1 uOP and 7 bytes long - 1 'complex' instruction, up to 4 uOPs or 3 per cycle for instructions longer than 4 uOPs */ -static struct -{ - int nr_uops; - const p6_uop_t *uops[6]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is - part of a dependency chain and the start time is the completion time of - the previous uop*/ - int earliest_start[6]; +static struct { + int nr_uops; + const p6_uop_t *uops[6]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[6]; } decode_buffer; #define NR_OPSEQS 3 @@ -1691,421 +1599,400 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush_p6(void) +void +decode_flush_p6(void) { - int c; - int start_timestamp, uop_timestamp = 0; - - /*Decoded opseq can not be submitted if there are no free spaces in the - opseq buffer*/ - if (decode_timestamp < opseq_completion_timestamp[next_opseq]) - decode_timestamp = opseq_completion_timestamp[next_opseq]; - - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; - - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < (decode_buffer.nr_uops); c++) - { - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; + int start_timestamp; + int uop_timestamp = 0; - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } + /*Decoded opseq can not be submitted if there are no free spaces in the + opseq buffer*/ + if (decode_timestamp < opseq_completion_timestamp[next_opseq]) + decode_timestamp = opseq_completion_timestamp[next_opseq]; - /*Calculate opseq completion time. Since opseqs complete in order, it - must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; - else - last_complete_timestamp = uop_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Advance to next opseq in buffer*/ - opseq_completion_timestamp[next_opseq] = last_complete_timestamp; - next_opseq++; - if (next_opseq == NR_OPSEQS) - next_opseq = 0; + /*Submit uops to execution units, and determine the latest completion time*/ + for (int c = 0; c < (decode_buffer.nr_uops); c++) { + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; + + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } + + /*Calculate opseq completion time. Since opseqs complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opseq in buffer*/ + opseq_completion_timestamp[next_opseq] = last_complete_timestamp; + next_opseq++; + if (next_opseq == NR_OPSEQS) + next_opseq = 0; - decode_timestamp++; - decode_buffer.nr_uops = 0; + decode_timestamp++; + decode_buffer.nr_uops = 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on P6 simple decoding*/ -static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) -{ - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) - { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; - - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } +static int +codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +{ + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -static void decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) -{ - uint32_t regmask_required; - uint32_t regmask_modified; - int c; - int d = 0; /*Complex decoder uOPs*/ - int earliest_start = 0; - decode_type_t decode_type = ins->decode_type; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - - /*Generate input register mask, and determine the earliest time this - instruction can start. This is not accurate, as this is calculated per - x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) - { - if (regmask_required & (1 << c)) - { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } - } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) - { - int reg = fetchdat & 7; - - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; +static void +decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +{ + uint32_t regmask_required; + uint32_t regmask_modified; + int c; + int d = 0; /*Complex decoder uOPs*/ + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; } - - /*Simple decoders are limited to 7 bytes & 1 uOP*/ - if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) - decode_type = DECODE_COMPLEX; - - switch (decode_type) - { - case DECODE_SIMPLE: - if (decode_buffer.nr_uops - d == 2) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 3; - decode_flush_p6(); - } - else if (decode_buffer.nr_uops - d == 1) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 2+d; - if (d) - decode_flush_p6(); - } - else if (decode_buffer.nr_uops) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 1+d; - } - else - { - decode_buffer.nr_uops = 1; - decode_buffer.uops[0] = &ins->uop[0]; - decode_buffer.earliest_start[0] = earliest_start; - } - break; - - case DECODE_COMPLEX: - if (decode_buffer.nr_uops) - decode_flush_p6(); /*The 4-1-1 arrangement implies that a complex ins. can't be decoded after a simple one*/ - - d = 0; - - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; - - if ((d == 3) && (ins->nr_uops > 4)) /*Ins. with >4 uOPs require the use of special units only present on 3 translate PLAs*/ - { - d = 0; - decode_buffer.nr_uops = 3; - decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/ - } - } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if (deps & FPU_RW_STREG) { + int reg = fetchdat & 7; + + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } + + /*Simple decoders are limited to 7 bytes & 1 uOP*/ + if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) + decode_type = DECODE_COMPLEX; + + switch (decode_type) { + case DECODE_SIMPLE: + if (decode_buffer.nr_uops - d == 2) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 3; + decode_flush_p6(); + } else if (decode_buffer.nr_uops - d == 1) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 2 + d; if (d) - { - decode_buffer.nr_uops = d; - } - break; - } + decode_flush_p6(); + } else if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 1 + d; + } else { + decode_buffer.nr_uops = 1; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + } + break; + + case DECODE_COMPLEX: + if (decode_buffer.nr_uops) + decode_flush_p6(); /*The 4-1-1 arrangement implies that a complex ins. can't be decoded after a simple one*/ + + d = 0; + + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) - { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } + if ((d == 3) && (ins->nr_uops > 4)) { /*Ins. with >4 uOPs require the use of special units only present on 3 translate PLAs*/ + d = 0; + decode_buffer.nr_uops = 3; + decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/ + } + } + if (d) { + decode_buffer.nr_uops = d; + } + break; + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps & FPU_POP) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) - { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } } -void codegen_timing_p6_block_start(void) +void +codegen_timing_p6_block_start(void) { - int c; + int c; - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; - decode_timestamp = 0; - last_complete_timestamp = 0; + decode_timestamp = 0; + last_complete_timestamp = 0; - for (c = 0; c < NR_OPSEQS; c++) - opseq_completion_timestamp[c] = 0; - next_opseq = 0; + for (c = 0; c < NR_OPSEQS; c++) + opseq_completion_timestamp[c] = 0; + next_opseq = 0; - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; } -void codegen_timing_p6_start(void) -{ - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - { - units = ppro_units; - nr_units = NR_PPRO_UNITS; - } - else - { - units = p2_units; - nr_units = NR_P2_UNITS; - } - last_prefix = 0; - prefixes = 0; +void +codegen_timing_p6_start(void) +{ + if (cpu_s->cpu_type == CPU_PENTIUMPRO) { + units = ppro_units; + nr_units = NR_PPRO_UNITS; + } else { + units = p2_units; + nr_units = NR_P2_UNITS; + } + last_prefix = 0; + prefixes = 0; } -void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix != 0x0f) - decode_timestamp++; + if (prefix != 0x0f) + decode_timestamp++; - last_prefix = prefix; - prefixes++; + last_prefix = prefix; + prefixes++; } -void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - const macro_op_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; +void +codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +{ + const macro_op_t **ins_table; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); - else - decode_instruction(&complex_alu1_op, 0, fetchdat, op_32, bit8); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&complex_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } -void codegen_timing_p6_block_end(void) +void +codegen_timing_p6_block_end(void) { - if (decode_buffer.nr_uops) - { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush_p6(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush_p6(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } -int codegen_timing_p6_jump_cycles(void) +int +codegen_timing_p6_jump_cycles(void) { - if (decode_buffer.nr_uops) - return 1; - return 0; + if (decode_buffer.nr_uops) + return 1; + return 0; } -codegen_timing_t codegen_timing_p6 = -{ - codegen_timing_p6_start, - codegen_timing_p6_prefix, - codegen_timing_p6_opcode, - codegen_timing_p6_block_start, - codegen_timing_p6_block_end, - codegen_timing_p6_jump_cycles +codegen_timing_t codegen_timing_p6 = { + codegen_timing_p6_start, + codegen_timing_p6_prefix, + codegen_timing_p6_opcode, + codegen_timing_p6_block_start, + codegen_timing_p6_block_end, + codegen_timing_p6_jump_cycles }; diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 232455f6d5..3951acc942 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -14,8 +14,11 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> +#include + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -23,46 +26,45 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" - /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 28) +#define CYCLES_HAS_MULTI (1 << 28) #define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) /*Instruction lasts given number of cycles. Does not pair*/ #define CYCLES(c) (c | PAIR_NP) - -static int pair_timings[4][4] = -{ -/* Reg RM RMW Branch*/ -/*Reg*/ {1, 2, 3, 2}, -/*RM*/ {2, 2, 3, 3}, -/*RMW*/ {3, 4, 5, 4}, -/*Branch*/ {-1, -1, -1, -1} +static int pair_timings[4][4] = { + /* Reg RM RMW Branch*/ + /*Reg*/ {1, 2, 3, 2 }, + /*RM*/ + { 2, 2, 3, 3 }, + /*RMW*/ + { 3, 4, 5, 4 }, + /*Branch*/ + { -1, -1, -1, -1} }; /*Instruction follows either register timing, read-modify, or read-modify-write. May be pairable*/ -#define CYCLES_REG (0ull << 0) -#define CYCLES_RM (1ull << 0) -#define CYCLES_RMW (2ull << 0) +#define CYCLES_REG (0ull << 0) +#define CYCLES_RM (1ull << 0) +#define CYCLES_RMW (2ull << 0) #define CYCLES_BRANCH (3ull << 0) /*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/ -#define CYCLES_HASIMM (3ull << 2) +#define CYCLES_HASIMM (3ull << 2) #define CYCLES_IMM8 (1ull << 2) #define CYCLES_IMM1632 (2ull << 2) -#define CYCLES_MASK ((1ull << 7) - 1) - +#define CYCLES_MASK ((1ull << 7) - 1) /*Instruction does not pair*/ #define PAIR_NP (0ull << 29) /*Instruction pairs in U pipe only*/ -#define PAIR_U (1ull << 29) +#define PAIR_U (1ull << 29) /*Instruction pairs in V pipe only*/ -#define PAIR_V (2ull << 29) +#define PAIR_V (2ull << 29) /*Instruction pairs in both U and V pipes*/ #define PAIR_UV (3ull << 29) /*Instruction pairs in U pipe only and only with FXCH*/ @@ -70,36 +72,34 @@ static int pair_timings[4][4] = /*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/ #define PAIR_FXCH (6ull << 29) -#define PAIR_FPU (4ull << 29) +#define PAIR_FPU (4ull << 29) #define PAIR_MASK (7ull << 29) - /*comp_time = cycles until instruction complete i_overlap = cycles that overlap with integer f_overlap = cycles that overlap with subsequent FPU*/ -#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t)comp_time) | ((uint64_t)i_overlap << 41) | ((uint64_t)f_overlap << 49) | PAIR_FPU - -#define FPU_COMP_TIME(timing) (timing & 0xff) -#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) -#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) +#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t) comp_time) | ((uint64_t) i_overlap << 41) | ((uint64_t) f_overlap << 49) | PAIR_FPU -#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) -#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) +#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) -#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) +#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) +#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) -#define INVALID 0 +#define INVALID 0 -static int u_pipe_full; -static uint32_t u_pipe_opcode; +static int u_pipe_full; +static uint32_t u_pipe_opcode; static uint64_t *u_pipe_timings; -static uint32_t u_pipe_op_32; -static uint32_t u_pipe_regmask; -static uint32_t u_pipe_fetchdat; -static int u_pipe_decode_delay_offset; +static uint32_t u_pipe_op_32; +static uint32_t u_pipe_regmask; +static uint32_t u_pipe_fetchdat; +static int u_pipe_decode_delay_offset; static uint64_t *u_pipe_deps; static uint32_t regmask_modified; @@ -109,8 +109,8 @@ static uint32_t addr_regmask; static int fpu_latency; static int fpu_st_latency[8]; -static uint64_t opcode_timings[256] = -{ +static uint64_t opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, /* ADD ADD PUSH ES POP ES*/ @@ -243,10 +243,11 @@ static uint64_t opcode_timings[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), /* CLD STD INCDEC*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_RMW, INVALID + // clang-format on }; -static uint64_t opcode_timings_mod3[256] = -{ +static uint64_t opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* ADD ADD PUSH ES POP ES*/ @@ -380,10 +381,11 @@ static uint64_t opcode_timings_mod3[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), /* CLD STD INCDEC*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_REG, INVALID + // clang-format on }; -static uint64_t opcode_timings_0f[256] = -{ +static uint64_t opcode_timings_0f[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -463,9 +465,10 @@ static uint64_t opcode_timings_0f[256] = INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, + // clang-format on }; -static uint64_t opcode_timings_0f_mod3[256] = -{ +static uint64_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -545,86 +548,98 @@ static uint64_t opcode_timings_0f_mod3[256] = INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, + // clang-format on }; -static uint64_t opcode_timings_shift[8] = -{ +static uint64_t opcode_timings_shift[8] = { + // clang-format off PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, + // clang-format on }; -static uint64_t opcode_timings_shift_mod3[8] = -{ +static uint64_t opcode_timings_shift_mod3[8] = { + // clang-format off PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, + // clang-format on }; -static uint64_t opcode_timings_f6[8] = -{ +static uint64_t opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) + // clang-format on }; -static uint64_t opcode_timings_f6_mod3[8] = -{ +static uint64_t opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) + // clang-format on }; -static uint64_t opcode_timings_f7[8] = -{ +static uint64_t opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) + // clang-format on }; -static uint64_t opcode_timings_f7_mod3[8] = -{ +static uint64_t opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) + // clang-format on }; -static uint64_t opcode_timings_ff[8] = -{ +static uint64_t opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), /* JMP JMP far PUSH*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID + // clang-format on }; -static uint64_t opcode_timings_ff_mod3[8] = -{ +static uint64_t opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), /* JMP JMP far PUSH*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID + // clang-format on }; -static uint64_t opcode_timings_d8[8] = -{ +static uint64_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBs FSUBRs FDIVs FDIVRs*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_d8_mod3[8] = -{ +static uint64_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUB FSUBR FDIV FDIVR*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_d9[8] = -{ +static uint64_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), /* FLDENV FLDCW FSTENV FSTCW*/ PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0) + // clang-format on }; -static uint64_t opcode_timings_d9_mod3[64] = -{ +static uint64_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -653,32 +668,35 @@ static uint64_t opcode_timings_d9_mod3[64] = PAIR_NP | FPU_CYCLES(64,2,2), INVALID, PAIR_NP | FPU_CYCLES(70,69,2), PAIR_NP | FPU_CYCLES(89,2,2), /* opFRNDINT opFSCALE opFSIN opFCOS*/ PAIR_NP | FPU_CYCLES(9,0,0), PAIR_NP | FPU_CYCLES(20,5,0), PAIR_NP | FPU_CYCLES(65,2,2), PAIR_NP | FPU_CYCLES(65,2,2) + // clang-format on }; -static uint64_t opcode_timings_da[8] = -{ +static uint64_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) + // clang-format on }; -static uint64_t opcode_timings_da_mod3[8] = -{ +static uint64_t opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; - -static uint64_t opcode_timings_db[8] = -{ +static uint64_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), /* FLDe FSTPe*/ INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0) + // clang-format on }; -static uint64_t opcode_timings_db_mod3[64] = -{ +static uint64_t opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -704,616 +722,606 @@ static uint64_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint64_t opcode_timings_dc[8] = -{ +static uint64_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBd FSUBRd FDIVd FDIVRd*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_dc_mod3[8] = -{ +static uint64_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_dd[8] = -{ +static uint64_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), /* FRSTOR FSAVE FSTSW*/ PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0) + // clang-format on }; -static uint64_t opcode_timings_dd_mod3[8] = -{ +static uint64_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), /* FUCOM FUCOMP*/ PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; -static uint64_t opcode_timings_de[8] = -{ +static uint64_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) + // clang-format on }; -static uint64_t opcode_timings_de_mod3[8] = -{ +static uint64_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBP FSUBRP FDIVP FDIVRP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_df[8] = -{ +static uint64_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), /* FILDiq FBSTP FISTPiq*/ INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0) + // clang-format on }; -static uint64_t opcode_timings_df_mod3[8] = -{ +static uint64_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ PAIR_NP | FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID + // clang-format on }; -static uint64_t opcode_timings_81[8] = -{ +static uint64_t opcode_timings_81[8] = { + // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632 + // clang-format on }; -static uint64_t opcode_timings_81_mod3[8] = -{ +static uint64_t opcode_timings_81_mod3[8] = { + // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG + // clang-format on }; -static uint64_t opcode_timings_8x[8] = -{ +static uint64_t opcode_timings_8x[8] = { + // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8 + // clang-format on }; -static uint64_t opcode_timings_8x_mod3[8] = -{ +static uint64_t opcode_timings_8x_mod3[8] = { + // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG + // clang-format on }; -static int decode_delay, decode_delay_offset; +static int decode_delay; +static int decode_delay_offset; static uint8_t last_prefix; -static int prefixes; +static int prefixes; -static inline int COUNT(uint64_t timings, uint64_t deps, int op_32) +static inline int +COUNT(uint64_t timings, uint64_t deps, int op_32) { - if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) - return FPU_I_LATENCY(timings); - if (timings & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)timings >> 8) & 0xff; - return (uintptr_t)timings & 0xff; - } - if (!(timings & PAIR_MASK)) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FX) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FXCH) - return timings & 0xffff; - if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) - timings &= 3; - switch (timings & CYCLES_MASK) - { - case CYCLES_REG: - return 1; - case CYCLES_RM: - return 2; - case CYCLES_RMW: - return 3; - case CYCLES_BRANCH: - return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2; - } - - fatal("Illegal COUNT %016llx\n", timings); - - return timings; + if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) + return FPU_I_LATENCY(timings); + if (timings & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return ((uintptr_t) timings >> 8) & 0xff; + return (uintptr_t) timings & 0xff; + } + if (!(timings & PAIR_MASK)) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FX) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FXCH) + return timings & 0xffff; + if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) + timings &= 3; + switch (timings & CYCLES_MASK) { + case CYCLES_REG: + return 1; + case CYCLES_RM: + return 2; + case CYCLES_RMW: + return 3; + case CYCLES_BRANCH: + return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2; + } + + fatal("Illegal COUNT %016" PRIu64 "\n", timings); + + return timings; } -static int codegen_fpu_latencies(uint64_t deps, int reg) +static int +codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + int latency = fpu_latency; - if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) - latency = fpu_st_latency[0]; - if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) - latency = fpu_st_latency[1]; - if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) - latency = fpu_st_latency[reg]; + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) + latency = fpu_st_latency[reg]; - return latency; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 +#define SUB_AND_CLAMP(latency, count) \ + latency -= count; \ + if (latency < 0) \ + latency = 0 -static void codegen_fpu_latency_clock(int count) +static void +codegen_fpu_latency_clock(int count) { - SUB_AND_CLAMP(fpu_latency, count); - SUB_AND_CLAMP(fpu_st_latency[0], count); - SUB_AND_CLAMP(fpu_st_latency[1], count); - SUB_AND_CLAMP(fpu_st_latency[2], count); - SUB_AND_CLAMP(fpu_st_latency[3], count); - SUB_AND_CLAMP(fpu_st_latency[4], count); - SUB_AND_CLAMP(fpu_st_latency[5], count); - SUB_AND_CLAMP(fpu_st_latency[6], count); - SUB_AND_CLAMP(fpu_st_latency[7], count); + SUB_AND_CLAMP(fpu_latency, count); + SUB_AND_CLAMP(fpu_st_latency[0], count); + SUB_AND_CLAMP(fpu_st_latency[1], count); + SUB_AND_CLAMP(fpu_st_latency[2], count); + SUB_AND_CLAMP(fpu_st_latency[3], count); + SUB_AND_CLAMP(fpu_st_latency[4], count); + SUB_AND_CLAMP(fpu_st_latency[5], count); + SUB_AND_CLAMP(fpu_st_latency[6], count); + SUB_AND_CLAMP(fpu_st_latency[7], count); } -static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) +static inline int +codegen_timing_has_displacement(uint32_t fetchdat, int op_32) { - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /*Has SIB*/ - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) - return 1; - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) - return 1; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) - return 1; + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /*Has SIB*/ + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) + return 1; + } else { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) + return 1; } - return 0; + } else { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) + return 1; + } + return 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on Pentium MMX parallel decoding*/ -static inline int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) +static inline int +codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) { - int len = prefixes; - if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) - { - len += 2; /*Opcode + ModR/M*/ - if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) - len++; - if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; - - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } + int len = prefixes; + if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) { + len += 2; /*Opcode + ModR/M*/ + if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) + len++; + if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -void codegen_timing_pentium_block_start(void) +void +codegen_timing_pentium_block_start(void) { - u_pipe_full = decode_delay = decode_delay_offset = 0; + u_pipe_full = decode_delay = decode_delay_offset = 0; } -void codegen_timing_pentium_start(void) +void +codegen_timing_pentium_start(void) { - last_prefix = 0; - prefixes = 0; + last_prefix = 0; + prefixes = 0; } -void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) { - prefixes++; - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) - { - /*On Pentium MMX 0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67)) - { - /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ - decode_delay_offset += 2; - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; + prefixes++; + if ((prefix & 0xf8) == 0xd8) { + last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) { + /*On Pentium MMX 0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67)) { + /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ + decode_delay_offset += 2; last_prefix = prefix; + return; + } + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) { + /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ + last_prefix = prefix; + return; + } + /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not - cause AGIs with each other, but do with instructions that use it explicitly*/ - if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) - addr_regmask |= (1 << REG_ESP); + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); - return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } -static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +static void +codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) { - int instr_cycles, latency = 0; - - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - { -/* if (timings[opcode] & FPU_WRITE_ST0) - fatal("FPU_WRITE_ST0\n"); - if (timings[opcode] & FPU_WRITE_ST1) - fatal("FPU_WRITE_ST1\n"); - if (timings[opcode] & FPU_WRITE_STREG) - fatal("FPU_WRITE_STREG\n");*/ - instr_cycles = 0; + int instr_cycles; + int latency = 0; + + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else { +#if 0 + if (timings[opcode] & FPU_WRITE_ST0) + fatal("FPU_WRITE_ST0\n"); + if (timings[opcode] & FPU_WRITE_ST1) + fatal("FPU_WRITE_ST1\n"); + if (timings[opcode] & FPU_WRITE_STREG) + fatal("FPU_WRITE_STREG\n");*/ +#endif + instr_cycles = 0; + } + + if ((decode_delay + decode_delay_offset) > 0) + codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); + else + codegen_fpu_latency_clock(instr_cycles); + instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); + instr_cycles += exec_delay; + if ((decode_delay + decode_delay_offset) > 0) + codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; + else + codegen_block_cycles += instr_cycles; + + decode_delay = (-instr_cycles) + 1; + + if (deps[opcode] & FPU_POP) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c] = fpu_st_latency[c + 1]; + fpu_st_latency[7] = 0; + } + if (deps[opcode] & FPU_POP2) { + for (uint8_t c = 0; c < 6; c++) + fpu_st_latency[c] = fpu_st_latency[c + 2]; + fpu_st_latency[6] = fpu_st_latency[7] = 0; + } + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) { + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[opcode] & FPU_PUSH) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c + 1] = fpu_st_latency[c]; + fpu_st_latency[0] = 0; + } + if (deps[opcode] & FPU_WRITE_ST0) { +#if 0 + if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ +#endif + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) { +#if 0 + if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ +#endif + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) { + int reg = fetchdat & 7; + if (deps[opcode] & FPU_POP) + reg--; + if (reg >= 0 && !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) { + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); } + } +} - if ((decode_delay + decode_delay_offset) > 0) - codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); - else - codegen_fpu_latency_clock(instr_cycles); - instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); - instr_cycles += exec_delay; - if ((decode_delay + decode_delay_offset) > 0) - codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; - else - codegen_block_cycles += instr_cycles; +void +codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +{ + uint64_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; + + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; - decode_delay = (-instr_cycles) + 1; + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - if (deps[opcode] & FPU_POP) - { - int c; + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - for (c = 0; c < 7; c++) - fpu_st_latency[c] = fpu_st_latency[c+1]; - fpu_st_latency[7] = 0; - } - if (deps[opcode] & FPU_POP2) - { - int c; + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) != PAIR_FXCH) + goto nopair; - for (c = 0; c < 6; c++) - fpu_st_latency[c] = fpu_st_latency[c+2]; - fpu_st_latency[6] = fpu_st_latency[7] = 0; - } - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - { - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } + if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) + goto nopair; - if (deps[opcode] & FPU_PUSH) - { - int c; + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) == PAIR_FXCH) { + int temp; - for (c = 0; c < 7; c++) - fpu_st_latency[c+1] = fpu_st_latency[c]; - fpu_st_latency[0] = 0; - } - if (deps[opcode] & FPU_WRITE_ST0) - { -/* if (fpu_st_latency[0]) - fatal("Bad latency ST0\n");*/ - fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_ST1) - { -/* if (fpu_st_latency[1]) - fatal("Bad latency ST1\n");*/ - fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps[opcode] & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) - { - fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); - } - } -} + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - uint64_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } + temp = fpu_st_latency[fetchdat & 7]; + fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; + fpu_st_latency[0] = temp; - if (u_pipe_full) - { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) != PAIR_FXCH) - goto nopair; - - if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && - (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) - goto nopair; - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) == PAIR_FXCH) - { - int temp; - - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - - temp = fpu_st_latency[fetchdat & 7]; - fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; - fpu_st_latency[0] = temp; - - u_pipe_full = 0; - decode_delay_offset = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; - return; - } - - if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; - int t2 = timings[opcode] & CYCLES_MASK; - int t_pair; - uint64_t temp_timing; - uint64_t temp_deps = 0; - - if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) - t1 &= 3; - if (!(timings[opcode] & PAIR_FPU)) - t2 &= 3; - - if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) - fatal("Pair out of range\n"); - - t_pair = pair_timings[t1][t2]; - if (t_pair < 1) - fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); - - /*Instruction can pair with previous*/ - temp_timing = t_pair; - if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); - u_pipe_full = 0; - decode_delay_offset = 0; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; - addr_regmask = 0; - return; - } - } -nopair: - /*Instruction can not pair with previous*/ - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; + u_pipe_full = 0; + decode_delay_offset = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; + return; } - if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - /*Instruction might pair with next*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - u_pipe_fetchdat = fetchdat; - u_pipe_decode_delay_offset = decode_delay_offset; - u_pipe_deps = deps; - decode_delay_offset = 0; - return; - } + if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) <= 0) { + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) { + int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; + int t2 = timings[opcode] & CYCLES_MASK; + int t_pair; + uint64_t temp_timing; + uint64_t temp_deps = 0; + + if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) + t1 &= 3; + if (!(timings[opcode] & PAIR_FPU)) + t2 &= 3; + + if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) + fatal("Pair out of range\n"); + + t_pair = pair_timings[t1][t2]; + if (t_pair < 1) + fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); + + /*Instruction can pair with previous*/ + temp_timing = t_pair; + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); + u_pipe_full = 0; + decode_delay_offset = 0; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + addr_regmask = 0; + return; + } } - /*Instruction can not pair and must run now*/ - if (check_agi(deps, opcode, fetchdat, op_32)) - agi_stall = 1; - codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - addr_regmask = 0; +nopair: + /*Instruction can not pair with previous*/ + /*Run previous now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; + } + + if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) { + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) { + /*Instruction might pair with next*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; + decode_delay_offset = 0; + return; + } + } + /*Instruction can not pair and must run now*/ + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + addr_regmask = 0; } -void codegen_timing_pentium_block_end(void) +void +codegen_timing_pentium_block_end(void) { - if (u_pipe_full) - { - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - codegen_block_cycles++; - codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; - u_pipe_full = 0; - } + if (u_pipe_full) { + /*Run previous now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + codegen_block_cycles++; + codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; + u_pipe_full = 0; + } } -codegen_timing_t codegen_timing_pentium = -{ - codegen_timing_pentium_start, - codegen_timing_pentium_prefix, - codegen_timing_pentium_opcode, - codegen_timing_pentium_block_start, - codegen_timing_pentium_block_end, - NULL +codegen_timing_t codegen_timing_pentium = { + codegen_timing_pentium_start, + codegen_timing_pentium_prefix, + codegen_timing_pentium_opcode, + codegen_timing_pentium_block_start, + codegen_timing_pentium_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index a1ee02b63e..11dd912b4f 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -4,19 +4,21 @@ #include #include <86box/86box.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include <86box/mem.h> #include "codegen.h" #include "codegen_ops.h" #include "codegen_timing_common.h" -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) +#define CYCLES(c) (int *) c +#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = -{ +static int *opcode_timings[256] = { + // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -36,10 +38,11 @@ static int *opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_mod3[256] = -{ +static int *opcode_timings_mod3[256] = { + // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_0f[256] = -{ +static int *opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] = /*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, + // clang-format on }; -static int *opcode_timings_0f_mod3[256] = -{ +static int *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -104,60 +109,72 @@ static int *opcode_timings_0f_mod3[256] = /*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, + // clang-format on }; -static int *opcode_timings_shift[8] = -{ +static int *opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) + // clang-format on }; -static int *opcode_timings_shift_mod3[8] = -{ +static int *opcode_timings_shift_mod3[8] = { + // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static int *opcode_timings_f6[8] = -{ +static int *opcode_timings_f6[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f6_mod3[8] = -{ +static int *opcode_timings_f6_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f7[8] = -{ +static int *opcode_timings_f7[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_f7_mod3[8] = -{ +static int *opcode_timings_f7_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_ff[8] = -{ +static int *opcode_timings_ff[8] = { + // clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_ff_mod3[8] = -{ +static int *opcode_timings_ff_mod3[8] = { + // clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_d8[8] = -{ +static int *opcode_timings_d8[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_d8_mod3[8] = -{ +static int *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_d9[8] = -{ +static int *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) + // clang-format on }; -static int *opcode_timings_d9_mod3[64] = -{ +static int *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), /*FXCH*/ @@ -174,26 +191,29 @@ static int *opcode_timings_d9_mod3[64] = CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3), /* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474) + // clang-format on }; -static int *opcode_timings_da[8] = -{ +static int *opcode_timings_da[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_da_mod3[8] = -{ +static int *opcode_timings_da_mod3[8] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL + // clang-format on }; - -static int *opcode_timings_db[8] = -{ +static int *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) + // clang-format on }; -static int *opcode_timings_db_mod3[64] = -{ +static int *opcode_timings_db_mod3[64] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -203,54 +223,63 @@ static int *opcode_timings_db_mod3[64] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -static int *opcode_timings_dc[8] = -{ +static int *opcode_timings_dc[8] = { + // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74) + // clang-format on }; -static int *opcode_timings_dc_mod3[8] = -{ +static int *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_dd[8] = -{ +static int *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) + // clang-format on }; -static int *opcode_timings_dd_mod3[8] = -{ +static int *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL + // clang-format on }; -static int *opcode_timings_de[8] = -{ +static int *opcode_timings_de[8] = { + // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_de_mod3[8] = -{ +static int *opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_df[8] = -{ +static int *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) + // clang-format on }; -static int *opcode_timings_df_mod3[8] = -{ +static int *opcode_timings_df_mod3[8] = { + // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL + // clang-format on }; -static int *opcode_timings_8x[8] = -{ +static int *opcode_timings_8x[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; static int *opcode_timings_8x_mod3[8] = @@ -264,158 +293,169 @@ static int *opcode_timings_81[8] = static int *opcode_timings_81_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static inline int COUNT(int *c, int op_32) -{ - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; +static inline int +COUNT(int *c, int op_32) +{ + if ((uintptr_t) c <= 10000) + return (int) (uintptr_t) c; + if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + return *c; } -void codegen_timing_winchip_block_start(void) +void +codegen_timing_winchip_block_start(void) { - regmask_modified = 0; + regmask_modified = 0; } -void codegen_timing_winchip_start(void) +void +codegen_timing_winchip_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) { - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } -void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; +void +codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +{ + int **timings; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ + codegen_block_cycles += timing_count; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_winchip_block_end(void) +void +codegen_timing_winchip_block_end(void) { + // } -codegen_timing_t codegen_timing_winchip = -{ - codegen_timing_winchip_start, - codegen_timing_winchip_prefix, - codegen_timing_winchip_opcode, - codegen_timing_winchip_block_start, - codegen_timing_winchip_block_end, - NULL +codegen_timing_t codegen_timing_winchip = { + codegen_timing_winchip_start, + codegen_timing_winchip_prefix, + codegen_timing_winchip_opcode, + codegen_timing_winchip_block_start, + codegen_timing_winchip_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c index f96304072d..d4e32611e4 100644 --- a/src/cpu/codegen_timing_winchip2.c +++ b/src/cpu/codegen_timing_winchip2.c @@ -14,6 +14,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_ops.h" @@ -23,46 +24,46 @@ #include "codegen_timing_common.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 31) +#define CYCLES_HAS_MULTI (1 << 31) -#define CYCLES_FPU (1 << 30) +#define CYCLES_FPU (1 << 30) #define CYCLES_IS_MMX_MUL (1 << 29) #define CYCLES_IS_MMX_SHIFT (1 << 28) #define CYCLES_IS_MMX_ANY (1 << 27) #define CYCLES_IS_3DNOW (1 << 26) -#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) #define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) -#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) -#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) -#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) +#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) -#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) +#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) -#define CYCLES(c) c -#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) +#define CYCLES(c) c +#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) /*comp_time = cycles until instruction complete i_overlap = cycles that overlap with integer f_overlap = cycles that overlap with subsequent FPU*/ #define FPU_CYCLES(comp_time, i_overlap, f_overlap) (comp_time) | (i_overlap << 8) | (f_overlap << 16) | CYCLES_FPU -#define FPU_COMP_TIME(timing) (timing & 0xff) -#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) -#define FPU_F_OVERLAP(timing) ((timing >> 16) & 0xff) +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 16) & 0xff) -#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) +#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) -#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) +#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) -#define FPU_RESULT_LATENCY(timing) ((timing >> 8) & 0xff) +#define FPU_RESULT_LATENCY(timing) ((timing >> 8) & 0xff) -#define INVALID 0 +#define INVALID 0 -static uint32_t opcode_timings[256] = -{ +static uint32_t opcode_timings[256] = { + // clang-format off /*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), /*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), @@ -82,10 +83,11 @@ static uint32_t opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID + // clang-format on }; -static uint32_t opcode_timings_mod3[256] = -{ +static uint32_t opcode_timings_mod3[256] = { + // clang-format off /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), /*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), @@ -105,10 +107,11 @@ static uint32_t opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f[256] = -{ +static uint32_t opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -128,9 +131,10 @@ static uint32_t opcode_timings_0f[256] = /*d0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), /*e0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), /*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = -{ +static uint32_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -150,66 +154,78 @@ static uint32_t opcode_timings_0f_mod3[256] = /*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), /*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), /*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, + // clang-format on }; -static uint32_t opcode_timings_shift[8] = -{ +static uint32_t opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) + // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = -{ +static uint32_t opcode_timings_shift_mod3[8] = { + // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static uint32_t opcode_timings_f6[8] = -{ +static uint32_t opcode_timings_f6[8] = { + // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = -{ +static uint32_t opcode_timings_f6_mod3[8] = { + // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static uint32_t opcode_timings_f7[8] = -{ +static uint32_t opcode_timings_f7[8] = { + // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = -{ +static uint32_t opcode_timings_f7_mod3[8] = { + // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static uint32_t opcode_timings_ff[8] = -{ +static uint32_t opcode_timings_ff[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID + // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = -{ +static uint32_t opcode_timings_ff_mod3[8] = { + // clang-format off CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID + // clang-format on }; -static uint32_t opcode_timings_d8[8] = -{ +static uint32_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUBs FSUBRs FDIVs FDIVRs*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = -{ +static uint32_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUB FSUBR FDIV FDIVR*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_d9[8] = -{ +static uint32_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), /* FLDENV FLDCW FSTENV FSTCW*/ FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0) + // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = -{ +static uint32_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -238,32 +254,35 @@ static uint32_t opcode_timings_d9_mod3[64] = FPU_CYCLES(64,2,2), INVALID, FPU_CYCLES(70,69,2),FPU_CYCLES(89,2,2), /* opFRNDINT opFSCALE opFSIN opFCOS*/ FPU_CYCLES(9,0,0), FPU_CYCLES(20,5,0), FPU_CYCLES(65,2,2), FPU_CYCLES(65,2,2) + // clang-format on }; -static uint32_t opcode_timings_da[8] = -{ +static uint32_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) + // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = -{ +static uint32_t opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; - -static uint32_t opcode_timings_db[8] = -{ +static uint32_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), /* FLDe FSTPe*/ INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0) + // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = -{ +static uint32_t opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -289,455 +308,469 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint32_t opcode_timings_dc[8] = -{ +static uint32_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUBd FSUBRd FDIVd FDIVRd*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = -{ +static uint32_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_dd[8] = -{ +static uint32_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), /* FRSTOR FSAVE FSTSW*/ FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0) + // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = -{ +static uint32_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FUCOM FUCOMP*/ FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_de[8] = -{ +static uint32_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) + // clang-format on }; -static uint32_t opcode_timings_de_mod3[8] = -{ +static uint32_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0), /* FSUBP FSUBRP FDIVP FDIVRP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_df[8] = -{ +static uint32_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), /* FILDiq FBSTP FISTPiq*/ INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0) + // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = -{ +static uint32_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_8x[8] = -{ +static uint32_t opcode_timings_8x[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = -{ +static uint32_t opcode_timings_8x_mod3[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_81[8] = -{ +static uint32_t opcode_timings_81[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = -{ +static uint32_t opcode_timings_81_mod3[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static int decode_delay, decode_delay_offset; -static int fpu_latency; -static int fpu_st_latency[8]; +static int decode_delay; +static int decode_delay_offset; +static int fpu_latency; +static int fpu_st_latency[8]; -static int u_pipe_full; -static uint32_t u_pipe_opcode; +static int u_pipe_full; +static uint32_t u_pipe_opcode; static uint32_t *u_pipe_timings; -static uint32_t u_pipe_op_32; -static uint32_t u_pipe_regmask; -static uint32_t u_pipe_fetchdat; -static int u_pipe_decode_delay_offset; +static uint32_t u_pipe_op_32; +static uint32_t u_pipe_regmask; +static uint32_t u_pipe_fetchdat; +static int u_pipe_decode_delay_offset; static uint64_t *u_pipe_deps; -int can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) -{ - /*Only MMX/3DNow instructions can pair*/ - if (!(timing_b & CYCLES_IS_MMX)) - return 0; - /*Only one MMX multiply per cycle*/ - if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) - return 0; - /*Only one MMX shift/pack per cycle*/ - if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) - return 0; - /*Second instruction can not access registers written by first*/ - if (u_pipe_regmask & regmask_b) - return 0; - /*Must have had enough time to decode prefixes*/ - if ((decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) > 0) - return 0; - - return 1; +int +can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) +{ + /*Only MMX/3DNow instructions can pair*/ + if (!(timing_b & CYCLES_IS_MMX)) + return 0; + /*Only one MMX multiply per cycle*/ + if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) + return 0; + /*Only one MMX shift/pack per cycle*/ + if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) + return 0; + /*Second instruction can not access registers written by first*/ + if (u_pipe_regmask & regmask_b) + return 0; + /*Must have had enough time to decode prefixes*/ + if ((decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) > 0) + return 0; + + return 1; } -static inline int COUNT(uint32_t c, int op_32) -{ - if (c & CYCLES_FPU) - return FPU_I_LATENCY(c); - if (c & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return (c >> 8) & 0xff; - return c & 0xff; - } - return GET_CYCLES(c); +static inline int +COUNT(uint32_t c, int op_32) +{ + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not - cause AGIs with each other, but do with instructions that use it explicitly*/ - if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) - addr_regmask |= (1 << REG_ESP); + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); - return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } -static int codegen_fpu_latencies(uint64_t deps, int reg) +static int +codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + int latency = fpu_latency; - if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) - latency = fpu_st_latency[0]; - if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) - latency = fpu_st_latency[1]; - if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) - latency = fpu_st_latency[reg]; + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) + latency = fpu_st_latency[reg]; - return latency; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 - -static void codegen_fpu_latency_clock(int count) -{ - SUB_AND_CLAMP(fpu_latency, count); - SUB_AND_CLAMP(fpu_st_latency[0], count); - SUB_AND_CLAMP(fpu_st_latency[1], count); - SUB_AND_CLAMP(fpu_st_latency[2], count); - SUB_AND_CLAMP(fpu_st_latency[3], count); - SUB_AND_CLAMP(fpu_st_latency[4], count); - SUB_AND_CLAMP(fpu_st_latency[5], count); - SUB_AND_CLAMP(fpu_st_latency[6], count); - SUB_AND_CLAMP(fpu_st_latency[7], count); +#define SUB_AND_CLAMP(latency, count) \ + latency -= count; \ + if (latency < 0) \ + latency = 0 + +static void +codegen_fpu_latency_clock(int count) +{ + SUB_AND_CLAMP(fpu_latency, count); + SUB_AND_CLAMP(fpu_st_latency[0], count); + SUB_AND_CLAMP(fpu_st_latency[1], count); + SUB_AND_CLAMP(fpu_st_latency[2], count); + SUB_AND_CLAMP(fpu_st_latency[3], count); + SUB_AND_CLAMP(fpu_st_latency[4], count); + SUB_AND_CLAMP(fpu_st_latency[5], count); + SUB_AND_CLAMP(fpu_st_latency[6], count); + SUB_AND_CLAMP(fpu_st_latency[7], count); } -static void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) -{ - int instr_cycles, latency = 0; - - if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - instr_cycles = 0; - - if ((decode_delay + decode_delay_offset) > 0) - codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); - else - codegen_fpu_latency_clock(instr_cycles); - instr_cycles += COUNT(timings[opcode], op_32); - instr_cycles += exec_delay; - if ((decode_delay + decode_delay_offset) > 0) - codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; - else - codegen_block_cycles += instr_cycles; - decode_delay = (-instr_cycles) + 1; - +static void +codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +{ + int instr_cycles; + int latency = 0; + + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else + instr_cycles = 0; + + if ((decode_delay + decode_delay_offset) > 0) + codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); + else + codegen_fpu_latency_clock(instr_cycles); + instr_cycles += COUNT(timings[opcode], op_32); + instr_cycles += exec_delay; + if ((decode_delay + decode_delay_offset) > 0) + codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; + else + codegen_block_cycles += instr_cycles; + decode_delay = (-instr_cycles) + 1; + + if (deps[opcode] & FPU_POP) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c] = fpu_st_latency[c + 1]; + fpu_st_latency[7] = 0; + } + if (deps[opcode] & FPU_POP2) { + for (uint8_t c = 0; c < 6; c++) + fpu_st_latency[c] = fpu_st_latency[c + 2]; + fpu_st_latency[6] = fpu_st_latency[7] = 0; + } + if (timings[opcode] & CYCLES_FPU) { +#if 0 + if (fpu_latency) + fatal("Bad latency FPU\n");*/ +#endif + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[opcode] & FPU_PUSH) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c + 1] = fpu_st_latency[c]; + fpu_st_latency[0] = 0; + } + if (deps[opcode] & FPU_WRITE_ST0) { +#if 0 + if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ +#endif + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) { +#if 0 + if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ +#endif + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps[opcode] & FPU_POP) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c] = fpu_st_latency[c+1]; - fpu_st_latency[7] = 0; - } - if (deps[opcode] & FPU_POP2) - { - int c; - - for (c = 0; c < 6; c++) - fpu_st_latency[c] = fpu_st_latency[c+2]; - fpu_st_latency[6] = fpu_st_latency[7] = 0; - } - if (timings[opcode] & CYCLES_FPU) - { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } - - if (deps[opcode] & FPU_PUSH) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c+1] = fpu_st_latency[c]; - fpu_st_latency[0] = 0; - } - if (deps[opcode] & FPU_WRITE_ST0) - { -/* if (fpu_st_latency[0]) - fatal("Bad latency ST0\n");*/ - fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_ST1) - { -/* if (fpu_st_latency[1]) - fatal("Bad latency ST1\n");*/ - fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps[opcode] & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) - { -/* if (fpu_st_latency[reg]) - fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ - fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) { +#if 0 + if (fpu_st_latency[reg]) + fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ +#endif + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); } + } } -static void codegen_timing_winchip2_block_start(void) +static void +codegen_timing_winchip2_block_start(void) { - regmask_modified = 0; - decode_delay = decode_delay_offset = 0; - u_pipe_full = 0; + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; + u_pipe_full = 0; } -static void codegen_timing_winchip2_start(void) +static void +codegen_timing_winchip2_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) +static void +codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix == 0x0f) - { - /*0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; + if (prefix == 0x0f) { + /*0fh prefix is 'free'*/ last_prefix = prefix; + return; + } + /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } -static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; - - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; - - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; +static void +codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +{ + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; + + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (u_pipe_full) - { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - - if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) - { - int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; - int cycles_b = timings[opcode] & 0xff; - uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; - uint64_t temp_deps = 0; - - if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - - codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall); - u_pipe_full = 0; - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; - return; - } - else - { - /*No pairing, run first instruction now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - regmask_modified = u_pipe_regmask; - } - } - if (timings[opcode] & CYCLES_IS_MMX) - { - /*Might pair with next instruction*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - u_pipe_fetchdat = fetchdat; - u_pipe_decode_delay_offset = decode_delay_offset; - u_pipe_deps = deps; - decode_delay_offset = 0; - return; - } + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); + + if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) { + int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; + int cycles_b = timings[opcode] & 0xff; + uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; + uint64_t temp_deps = 0; + + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; - if (check_agi(deps, opcode, fetchdat, op_32)) + codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall); + u_pipe_full = 0; + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + return; + } else { + /*No pairing, run first instruction now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) agi_stall = 1; - codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + regmask_modified = u_pipe_regmask; + } + } + if (timings[opcode] & CYCLES_IS_MMX) { + /*Might pair with next instruction*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; + decode_delay_offset = 0; + return; + } + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -static void codegen_timing_winchip2_block_end(void) +static void +codegen_timing_winchip2_block_end(void) { - if (u_pipe_full) - { - int agi_stall = 0; - - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - } + if (u_pipe_full) { + int agi_stall = 0; + + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + } } -codegen_timing_t codegen_timing_winchip2 = -{ - codegen_timing_winchip2_start, - codegen_timing_winchip2_prefix, - codegen_timing_winchip2_opcode, - codegen_timing_winchip2_block_start, - codegen_timing_winchip2_block_end, - NULL +codegen_timing_t codegen_timing_winchip2 = { + codegen_timing_winchip2_start, + codegen_timing_winchip2_prefix, + codegen_timing_winchip2_opcode, + codegen_timing_winchip2_block_start, + codegen_timing_winchip2_block_end, + NULL }; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 3380e7ce47..4398df36cf 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -18,6 +18,7 @@ * Copyright 2016-2020 Miran Grca. * Copyright 2018-2021 Fred N. van Kempen. */ +#include #include #include #include @@ -32,11 +33,15 @@ #include <86box/machine.h> #include <86box/io.h> #include "x86_ops.h" +#include "x86seg_common.h" #include <86box/mem.h> #include <86box/nmi.h> #include <86box/pic.h> #include <86box/pci.h> #include <86box/gdbstub.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + #ifdef USE_DYNAREC # include "codegen.h" #endif @@ -50,27 +55,31 @@ #define CCR3_NMI_EN (1 << 1) enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_PAE = (1 << 6), - CPUID_MCE = (1 << 7), - CPUID_CMPXCHG8B = (1 << 8), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_MTRR = (1 << 12), - CPUID_PGE = (1 << 13), - CPUID_MCA = (1 << 14), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) + CPUID_FPU = (1 << 0), /* On-chip Floating Point Unit */ + CPUID_VME = (1 << 1), /* Virtual 8086 mode extensions */ + CPUID_DE = (1 << 2), /* Debugging extensions */ + CPUID_PSE = (1 << 3), /* Page Size Extension */ + CPUID_TSC = (1 << 4), /* Time Stamp Counter */ + CPUID_MSR = (1 << 5), /* Model-specific registers */ + CPUID_PAE = (1 << 6), /* Physical Address Extension */ + CPUID_MCE = (1 << 7), /* Machine Check Exception */ + CPUID_CMPXCHG8B = (1 << 8), /* CMPXCHG8B instruction */ + CPUID_APIC = (1 << 9), /* On-chip APIC */ + CPUID_AMDPGE = (1 << 9), /* Global Page Enable (AMD K5 Model 0 only) */ + CPUID_AMDSEP = (1 << 10), /* SYSCALL and SYSRET instructions (AMD K6 only) */ + CPUID_SEP = (1 << 11), /* SYSENTER and SYSEXIT instructions (SYSCALL and SYSRET if EAX=80000001h) */ + CPUID_MTRR = (1 << 12), /* Memory type range registers */ + CPUID_PGE = (1 << 13), /* Page Global Enable */ + CPUID_MCA = (1 << 14), /* Machine Check Architecture */ + CPUID_CMOV = (1 << 15), /* Conditional move instructions */ + CPUID_PAT = (1 << 16), /* Page Attribute Table */ + CPUID_MMX = (1 << 23), /* MMX technology */ + CPUID_FXSR = (1 << 24) /* FXSAVE and FXRSTOR instructions */ }; -/*Addition flags returned by CPUID function 0x80000001*/ -#define CPUID_3DNOW (1UL << 31UL) -#define CPUID_3DNOWE (1UL << 30UL) +/* Additional flags returned by CPUID function 0x80000001 */ +#define CPUID_3DNOWE (1UL << 30UL) /* Extended 3DNow! instructions */ +#define CPUID_3DNOW (1UL << 31UL) /* 3DNow! instructions */ /* Make sure this is as low as possible. */ cpu_state_t cpu_state; @@ -80,66 +89,169 @@ fpu_state_t fpu_state; uint32_t abrt_error; #ifdef USE_DYNAREC -const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f, - *x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32, - *x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32, - *x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32, - *x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32, - *x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32, - *x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32, - *x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32, - *x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32, - *x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE, - *x86_dynarec_opcodes_3DNOW; +const OpFn *x86_dynarec_opcodes; +const OpFn *x86_dynarec_opcodes_0f; +const OpFn *x86_dynarec_opcodes_d8_a16; +const OpFn *x86_dynarec_opcodes_d8_a32; +const OpFn *x86_dynarec_opcodes_d9_a16; +const OpFn *x86_dynarec_opcodes_d9_a32; +const OpFn *x86_dynarec_opcodes_da_a16; +const OpFn *x86_dynarec_opcodes_da_a32; +const OpFn *x86_dynarec_opcodes_db_a16; +const OpFn *x86_dynarec_opcodes_db_a32; +const OpFn *x86_dynarec_opcodes_dc_a16; +const OpFn *x86_dynarec_opcodes_dc_a32; +const OpFn *x86_dynarec_opcodes_dd_a16; +const OpFn *x86_dynarec_opcodes_dd_a32; +const OpFn *x86_dynarec_opcodes_de_a16; +const OpFn *x86_dynarec_opcodes_de_a32; +const OpFn *x86_dynarec_opcodes_df_a16; +const OpFn *x86_dynarec_opcodes_df_a32; +const OpFn *x86_dynarec_opcodes_REPE; +const OpFn *x86_dynarec_opcodes_REPNE; +const OpFn *x86_dynarec_opcodes_3DNOW; #endif -const OpFn *x86_opcodes, *x86_opcodes_0f, - *x86_opcodes_d8_a16, *x86_opcodes_d8_a32, - *x86_opcodes_d9_a16, *x86_opcodes_d9_a32, - *x86_opcodes_da_a16, *x86_opcodes_da_a32, - *x86_opcodes_db_a16, *x86_opcodes_db_a32, - *x86_opcodes_dc_a16, *x86_opcodes_dc_a32, - *x86_opcodes_dd_a16, *x86_opcodes_dd_a32, - *x86_opcodes_de_a16, *x86_opcodes_de_a32, - *x86_opcodes_df_a16, *x86_opcodes_df_a32, - *x86_opcodes_REPE, *x86_opcodes_REPNE, - *x86_opcodes_3DNOW; - -uint16_t cpu_fast_off_count, cpu_fast_off_val; +const OpFn *x86_opcodes; +const OpFn *x86_opcodes_0f; +const OpFn *x86_opcodes_d8_a16; +const OpFn *x86_opcodes_d8_a32; +const OpFn *x86_opcodes_d9_a16; +const OpFn *x86_opcodes_d9_a32; +const OpFn *x86_opcodes_da_a16; +const OpFn *x86_opcodes_da_a32; +const OpFn *x86_opcodes_db_a16; +const OpFn *x86_opcodes_db_a32; +const OpFn *x86_opcodes_dc_a16; +const OpFn *x86_opcodes_dc_a32; +const OpFn *x86_opcodes_dd_a16; +const OpFn *x86_opcodes_dd_a32; +const OpFn *x86_opcodes_de_a16; +const OpFn *x86_opcodes_de_a32; +const OpFn *x86_opcodes_df_a16; +const OpFn *x86_opcodes_df_a32; +const OpFn *x86_opcodes_REPE; +const OpFn *x86_opcodes_REPNE; +const OpFn *x86_opcodes_3DNOW; + +const OpFn *x86_2386_opcodes; +const OpFn *x86_2386_opcodes_0f; +const OpFn *x86_2386_opcodes_d8_a16; +const OpFn *x86_2386_opcodes_d8_a32; +const OpFn *x86_2386_opcodes_d9_a16; +const OpFn *x86_2386_opcodes_d9_a32; +const OpFn *x86_2386_opcodes_da_a16; +const OpFn *x86_2386_opcodes_da_a32; +const OpFn *x86_2386_opcodes_db_a16; +const OpFn *x86_2386_opcodes_db_a32; +const OpFn *x86_2386_opcodes_dc_a16; +const OpFn *x86_2386_opcodes_dc_a32; +const OpFn *x86_2386_opcodes_dd_a16; +const OpFn *x86_2386_opcodes_dd_a32; +const OpFn *x86_2386_opcodes_de_a16; +const OpFn *x86_2386_opcodes_de_a32; +const OpFn *x86_2386_opcodes_df_a16; +const OpFn *x86_2386_opcodes_df_a32; +const OpFn *x86_2386_opcodes_REPE; +const OpFn *x86_2386_opcodes_REPNE; + +uint16_t cpu_fast_off_count; +uint16_t cpu_fast_off_val; uint16_t temp_seg_data[4] = { 0, 0, 0, 0 }; -int isa_cycles, cpu_inited, - - cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, - cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, - cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, - cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, - - cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, - cpu_cyrix_alignment, CPUID, - - is186, is_nec, - is286, is386, is6117, is486 = 1, - cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, - is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu, - - timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, - timing_mm, timing_mml, timing_bt, timing_bnt, - timing_int, timing_int_rm, timing_int_v86, timing_int_pm, - timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm, - timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, - timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, - timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; -uint32_t cpu_features, cpu_fast_off_flags; +int isa_cycles; +int cpu_inited; + +int cpu_cycles_read; +int cpu_cycles_read_l; +int cpu_cycles_write; +int cpu_cycles_write_l; +int cpu_prefetch_cycles; +int cpu_prefetch_width; +int cpu_mem_prefetch_cycles; +int cpu_rom_prefetch_cycles; +int cpu_waitstates; +int cpu_cache_int_enabled; +int cpu_cache_ext_enabled; +int cpu_isa_speed; +int cpu_pci_speed; +int cpu_isa_pci_div; +int cpu_agp_speed; +int cpu_alt_reset; + +int cpu_override; +int cpu_effective; +int cpu_multi; +int cpu_16bitbus; +int cpu_64bitbus; +int cpu_cyrix_alignment; +int cpu_cpurst_on_sr; +int cpu_use_exec = 0; +int CPUID; + +int is186; +int is_nec; +int is286; +int is386; +int is6117; +int is486 = 1; +int cpu_isintel; +int cpu_iscyrix; +int hascache; +int isibm486; +int israpidcad; +int is_vpc; +int is_am486; +int is_am486dxl; +int is_pentium; +int is_k5; +int is_k6; +int is_p6; +int is_cxsmm; +int hasfpu; + +int timing_rr; +int timing_mr; +int timing_mrl; +int timing_rm; +int timing_rml; +int timing_mm; +int timing_mml; +int timing_bt; +int timing_bnt; +int timing_int; +int timing_int_rm; +int timing_int_v86; +int timing_int_pm; +int timing_int_pm_outer; +int timing_iret_rm; +int timing_iret_v86; +int timing_iret_pm; +int timing_iret_pm_outer; +int timing_call_rm; +int timing_call_pm; +int timing_call_pm_gate; +int timing_call_pm_gate_inner; +int timing_retf_rm; +int timing_retf_pm; +int timing_retf_pm_outer; +int timing_jmp_rm; +int timing_jmp_pm; +int timing_jmp_pm_gate; +int timing_misaligned; + +uint32_t cpu_features; +uint32_t cpu_fast_off_flags; uint32_t _tr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint32_t cache_index = 0; uint8_t _cache[2048]; -uint64_t cpu_CR4_mask, tsc = 0; -uint64_t pmc[2] = { 0, 0 }; +uint64_t cpu_CR4_mask; +uint64_t tsc = 0; -double cpu_dmulti, cpu_busspeed; +double cpu_dmulti; +double cpu_busspeed; msr_t msr; @@ -148,11 +260,18 @@ cyrix_t cyrix; cpu_family_t *cpu_f; CPU *cpu_s; -uint8_t do_translate = 0, do_translate2 = 0; +uint8_t do_translate = 0; +uint8_t do_translate2 = 0; -void (*cpu_exec)(int cycs); +void (*cpu_exec)(int32_t cycs); -static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; +static uint8_t ccr0; +static uint8_t ccr1; +static uint8_t ccr2; +static uint8_t ccr3; +static uint8_t ccr4; +static uint8_t ccr5; +static uint8_t ccr6; static int cyrix_addr; @@ -225,7 +344,8 @@ cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine) { const machine_t *machine_s = &machines[machine]; const CPU *cpu_s = &cpu_family->cpus[cpu]; - uint32_t packages, bus_speed; + uint32_t packages; + uint32_t bus_speed; uint8_t i; double multi; @@ -360,7 +480,7 @@ SF_FPU_reset(void) fpu_state.fcs = 0; fpu_state.fds = 0; fpu_state.fdp = 0; - memset(fpu_state.st_space, 0, sizeof(floatx80)*8); + memset(fpu_state.st_space, 0, sizeof(floatx80) * 8); } } @@ -446,9 +566,12 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_386_0f); #endif - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; - x86_opcodes_3DNOW = ops_3DNOW; + x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_2386_opcodes_REPE = ops_2386_REPE; + x86_2386_opcodes_REPNE = ops_2386_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; @@ -510,6 +633,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_df_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_sf_fpu_d8_a16; + x86_2386_opcodes_d8_a32 = ops_2386_sf_fpu_d8_a32; + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_df_a32; } else { x86_opcodes_d8_a16 = ops_fpu_d8_a16; x86_opcodes_d8_a32 = ops_fpu_d8_a32; @@ -527,6 +667,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_de_a32; x86_opcodes_df_a16 = ops_fpu_df_a16; x86_opcodes_df_a32 = ops_fpu_df_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_fpu_d8_a16; + x86_2386_opcodes_d8_a32 = ops_2386_fpu_d8_a32; + x86_2386_opcodes_d9_a16 = ops_2386_fpu_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_df_a32; } } else { #ifdef USE_DYNAREC @@ -563,6 +720,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_nofpu_a32; x86_opcodes_df_a16 = ops_nofpu_a16; x86_opcodes_df_a32 = ops_nofpu_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_d8_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_d9_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_d9_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_da_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_da_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_db_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_db_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_dc_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_dc_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_dd_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_dd_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_de_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_de_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_df_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_df_a32 = ops_2386_nofpu_a32; } #ifdef USE_DYNAREC @@ -573,6 +747,7 @@ cpu_set(void) timing_misaligned = 0; cpu_cyrix_alignment = 0; + cpu_cpurst_on_sr = 0; cpu_CR4_mask = 0; switch (cpu_s->cpu_type) { @@ -589,6 +764,7 @@ cpu_set(void) #else x86_setopcodes(ops_186, ops_186_0f); #endif + x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f); break; case CPU_286: @@ -597,6 +773,7 @@ cpu_set(void) #else x86_setopcodes(ops_286, ops_286_0f); #endif + x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f); if (fpu_type == FPU_287) { #ifdef USE_DYNAREC @@ -647,6 +824,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32; } else { x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; @@ -662,6 +854,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_287_de_a32; x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32; } } @@ -704,11 +911,13 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_ibm486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f); cpu_features = CPU_FEATURE_MSR; - /* FALLTHROUGH */ + fallthrough; case CPU_386SX: case CPU_386DX: - if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ + /* In case we get Deskpro 386 emulation */ + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC if (fpu_softfloat) { x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16; @@ -757,6 +966,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32; } else { x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; @@ -772,6 +996,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_287_de_a32; x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32; } } @@ -818,6 +1057,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 3; /* register dest - memory src */ @@ -857,6 +1097,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 3; /* register dest - memory src */ @@ -895,7 +1136,7 @@ cpu_set(void) case CPU_i486DX_SLENH: cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - /* FALLTHROUGH */ + fallthrough; case CPU_RAPIDCAD: case CPU_i486SX: case CPU_i486DX: @@ -909,6 +1150,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 2; /* register dest - memory src */ @@ -1153,7 +1395,6 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; if (cpu_s->cpu_type == CPU_PENTIUMMMX) cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_pentium); @@ -1207,7 +1448,9 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); else x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - // x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); +# if 0 + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); +# endif # else if (cpu_s->cpu_type == CPU_Cx6x86MX) x86_setopcodes(ops_386, ops_c6x86mx_0f); @@ -1215,7 +1458,9 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentium_0f); else x86_setopcodes(ops_386, ops_c6x86mx_0f); - // x86_setopcodes(ops_386, ops_c6x86_0f); +# if 0 + x86_setopcodes(ops_386, ops_c6x86_0f); +# endif # endif timing_rr = 1; /* register dest - register src */ @@ -1263,7 +1508,6 @@ cpu_set(void) cpu_features |= CPU_FEATURE_MSR | CPU_FEATURE_CR4; if (cpu_s->cpu_type == CPU_Cx6x86MX) cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); if (cpu_s->cpu_type >= CPU_CxGX1) cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; @@ -1358,18 +1602,22 @@ cpu_set(void) cpu_features |= CPU_FEATURE_3DNOW; if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) cpu_features |= CPU_FEATURE_3DNOWE; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); #if defined(DEV_BRANCH) && defined(USE_AMD_K5) cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; if (cpu_s->cpu_type >= CPU_K6) { cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); if (cpu_s->cpu_type <= CPU_K6) cpu_CR4_mask |= CR4_PCE; - } + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; + } else + cpu_CR4_mask |= CR4_PGE; #else cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; if (cpu_s->cpu_type == CPU_K6) cpu_CR4_mask |= CR4_PCE; + else if (cpu_s->cpu_type >= CPU_K6_2C) + cpu_CR4_mask |= CR4_PGE; #endif #ifdef USE_DYNAREC @@ -1461,7 +1709,6 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; if (cpu_s->cpu_type >= CPU_PENTIUM2) cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_PGE; if (cpu_s->cpu_type == CPU_PENTIUM2D) cpu_CR4_mask |= CR4_OSFXSR; @@ -1509,8 +1756,8 @@ cpu_set(void) timing_misaligned = 2; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + msr.fcr = (1 << 7) | (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE | CR4_PGE; cpu_cyrix_alignment = 1; @@ -1520,7 +1767,7 @@ cpu_set(void) break; default: - fatal("cpu_set : unknown CPU type %llu\n", cpu_s->cpu_type); + fatal("cpu_set : unknown CPU type %" PRIu64 "\n", cpu_s->cpu_type); } switch (fpu_type) { @@ -1546,17 +1793,26 @@ cpu_set(void) x87_concurrency = x87_concurrency_486; } + cpu_use_exec = 0; + if (is386) { #if defined(USE_DYNAREC) && !defined(USE_GDBSTUB) - if (cpu_use_dynarec) + if (cpu_use_dynarec) { cpu_exec = exec386_dynarec; - else + cpu_use_exec = 1; + } else #endif - cpu_exec = exec386; + /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ + if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) { + cpu_exec = exec386; + cpu_use_exec = 1; + } else + cpu_exec = exec386_2386; } else if (cpu_s->cpu_type >= CPU_286) - cpu_exec = exec386; + cpu_exec = exec386_2386; else cpu_exec = execx86; + mmx_init(); gdbstub_cpu_init(); } @@ -1571,12 +1827,13 @@ cpu_set_isa_speed(int speed) { if (speed) { cpu_isa_speed = speed; - pc_speed_changed(); } else if (cpu_busspeed >= 8000000) cpu_isa_speed = 8000000; else cpu_isa_speed = cpu_busspeed; + pc_speed_changed(); + cpu_log("cpu_set_isa_speed(%d) = %d\n", speed, cpu_isa_speed); } @@ -1647,7 +1904,7 @@ cpu_current_pc(char *bufp) sprintf(bufp, "%04X:%04X", CS, cpu_state.pc); - return (bufp); + return bufp; } void @@ -1657,7 +1914,7 @@ cpu_CPUID(void) case CPU_i486SX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -1671,11 +1928,14 @@ cpu_CPUID(void) case CPU_i486DX_SLENH: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { - EAX = CPUID; + if ((CPUID == 0x0436) && (cr0 & (1 << 29))) + EAX = 0x0470; + else + EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME; } else @@ -1684,21 +1944,21 @@ cpu_CPUID(void) case CPU_ENH_Am486DX: if (!EAX) { - EAX = 1; - EBX = 0x68747541; + EAX = 0x00000001; + EBX = 0x68747541;/* AuthenticAMD */ ECX = 0x444D4163; EDX = 0x69746E65; } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ + EDX = CPUID_FPU; } else EAX = EBX = ECX = EDX = 0; break; case CPU_WINCHIP: if (!EAX) { - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -1709,7 +1969,7 @@ cpu_CPUID(void) EDX = 0x48727561; } } else if (EAX == 1) { - EAX = 0x540; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -1723,7 +1983,7 @@ cpu_CPUID(void) case CPU_WINCHIP2: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -1735,7 +1995,7 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) @@ -1780,13 +2040,15 @@ cpu_CPUID(void) case CPU_PENTIUM: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + if (cpu_s->cpu_type != CPU_P24T) + EDX |= CPUID_MCE; } else EAX = EBX = ECX = EDX = 0; break; @@ -1795,103 +2057,123 @@ cpu_CPUID(void) case CPU_K5: if (!EAX) { EAX = 0x00000001; - EBX = 0x68747541; + EBX = 0x68747541; /* AuthenticAMD */ EDX = 0x69746E65; ECX = 0x444D4163; } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE; } else EAX = EBX = ECX = EDX = 0; break; case CPU_5K86: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x7428354B; - ECX = 0x5020296D; - EDX = 0x65636F72; - } else if (EAX == 0x80000003) { - EAX = 0x726F7373; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000004) - EAX = EBX = ECX = EDX = 0; - else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x04800000; - ECX = 0x08040120; - EDX = 0x10040120; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K5(tm) Proce */ + EBX = 0x7428354B; + ECX = 0x5020296D; + EDX = 0x65636F72; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x726F7373; /* ssor */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x04800000; /* TLBs */ + ECX = 0x08040120; /* L1 data cache */ + EDX = 0x10040120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; #endif case CPU_K6: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x6D74364B; - ECX = 0x202F7720; - EDX = 0x746C756D; - } else if (EAX == 0x80000003) { - EAX = 0x64656D69; - EBX = 0x65206169; - ECX = 0x6E657478; - EDX = 0x6E6F6973; - } else if (EAX == 0x80000004) { - EAX = 0x73; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x02800140; - ECX = 0x20020220; - EDX = 0x20020220; - } else if (EAX == 0x8FFFFFFF) { - EAX = 0x4778654E; - EBX = 0x72656E65; - ECX = 0x6F697461; - EDX = 0x444D416E; - } else - EAX = EBX = ECX = EDX = 0; + switch (EAX) { + case 0: + EAX = 0x00000001; + EBX = 0x68747541; /* AuthenticAMD */ + EDX = 0x69746E65; + ECX = 0x444D4163; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2D444D41; /* AMD-K6tm w/ mult */ + EBX = 0x6D74364B; + ECX = 0x202F7720; + EDX = 0x746C756D; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x64656D69; /* imedia extension */ + EBX = 0x65206169; + ECX = 0x6E657478; + EDX = 0x6E6F6973; + break; + case 0x80000004: /* Processor name string */ + EAX = 0x73; /* s */ + EBX = ECX = EDX = 0; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x8FFFFFFF: /* Easter egg */ + EAX = 0x4778654E; /* NexGenerationAMD */ + EBX = 0x72656E65; + ECX = 0x6F697461; + EDX = 0x444D416E; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } break; case CPU_K6_2: case CPU_K6_2C: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -1900,6 +2182,8 @@ cpu_CPUID(void) EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000000: EAX = 0x80000005; @@ -1908,7 +2192,9 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW; + if (cpu_s->cpu_type == CPU_K6_2C) + EDX |= CPUID_PGE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ @@ -1922,11 +2208,11 @@ cpu_CPUID(void) ECX = 0x00000000; EDX = 0x00000000; break; - case 0x80000005: /*Cache information*/ + case 0x80000005: /* Cache information */ EAX = 0; - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; default: EAX = EBX = ECX = EDX = 0; @@ -1937,7 +2223,7 @@ cpu_CPUID(void) case CPU_K6_3: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -1945,7 +2231,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; @@ -1954,7 +2240,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -1971,8 +2257,8 @@ cpu_CPUID(void) case 0x80000005: /* Cache information */ EAX = 0; EBX = 0x02800140; /* TLBs */ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ break; case 0x80000006: /* L2 Cache information */ EAX = EBX = EDX = 0; @@ -1988,7 +2274,7 @@ cpu_CPUID(void) case CPU_K6_3P: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; EBX = 0x68747541; /* AuthenticAMD */ ECX = 0x444d4163; EDX = 0x69746e65; @@ -1996,7 +2282,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; @@ -2005,7 +2291,7 @@ cpu_CPUID(void) case 0x80000001: EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW | CPUID_3DNOWE; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ @@ -2045,7 +2331,7 @@ cpu_CPUID(void) case CPU_PENTIUMMMX: if (!EAX) { EAX = 0x00000001; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2060,7 +2346,7 @@ cpu_CPUID(void) case CPU_Cx6x86: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2074,7 +2360,7 @@ cpu_CPUID(void) case CPU_Cx6x86L: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2088,7 +2374,7 @@ cpu_CPUID(void) case CPU_CxGX1: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2102,7 +2388,7 @@ cpu_CPUID(void) case CPU_Cx6x86MX: if (!EAX) { EAX = 0x00000001; - EBX = 0x69727943; + EBX = 0x69727943; /* CyrixInstead */ EDX = 0x736e4978; ECX = 0x64616574; } else if (EAX == 1) { @@ -2117,7 +2403,7 @@ cpu_CPUID(void) case CPU_PENTIUMPRO: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2125,9 +2411,14 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - EAX = 0x00000001; + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ EBX = ECX = 0; - EDX = 0x00000000; + EDX = 0x06040a42; /* 2nd-level cache: 256 KB, 4-way set associative, 32-byte line size + 1st-level data cache: 8 KB, 2-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache: 8 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; @@ -2135,7 +2426,7 @@ cpu_CPUID(void) case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2143,9 +2434,14 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { - EAX = 0x00000001; + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ EBX = ECX = 0; - EDX = 0x00000000; + EDX = 0x0c040843; /* 2nd-level cache: 512 KB, 4-way set associative, 32-byte line size + 1st-level data cache: 16 KB, 4-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache: 16 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; @@ -2153,7 +2449,7 @@ cpu_CPUID(void) case CPU_PENTIUM2D: if (!EAX) { EAX = 0x00000002; - EBX = 0x756e6547; + EBX = 0x756e6547; /* GenuineIntel */ EDX = 0x49656e69; ECX = 0x6c65746e; } else if (EAX == 1) { @@ -2161,9 +2457,22 @@ cpu_CPUID(void) EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { - EAX = 0x00000001; + EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries + Instruction TLB: 4 MB pages, fully associative, 2 entries + Data TLB: 4 KB pages, 4-way set associative, 64 entries */ EBX = ECX = 0; - EDX = 0x00000000; + if (cpu_f->package == CPU_PKG_SLOT2) /* Pentium II Xeon Drake */ + EDX = 0x0c040844; /* 2nd-level cache: 1 MB, 4-way set associative, 32-byte line size + 1st-level data cache: 16 KB, 4-way set associative, 32-byte line size + Data TLB: 4 MB pages, 4-way set associative, 8 entries + 1st-level instruction cache: 16 KB, 4-way set associative, 32-byte line size */ + else if (!strncmp(cpu_f->internal_name, "celeron", 7)) { /* Celeron */ + if (CPUID >= 0x660) /* Mendocino */ + EDX = 0x0c040841; /* 2nd-level cache: 128 KB, 4-way set associative, 32-byte line size */ + else /* Covington */ + EDX = 0x0c040840; /* No 2nd-level cache */ + } else /* Pentium II Deschutes and OverDrive */ + EDX = 0x0c040843; /* 2nd-level cache: 512 KB, 4-way set associative, 32-byte line size */ } else EAX = EBX = ECX = EDX = 0; break; @@ -2171,7 +2480,7 @@ cpu_CPUID(void) case CPU_CYRIX3S: switch (EAX) { case 0: - EAX = 1; + EAX = 0x00000001; if (msr.fcr2 & (1 << 14)) { EBX = msr.fcr3 >> 32; ECX = msr.fcr3 & 0xffffffff; @@ -2183,11 +2492,13 @@ cpu_CPUID(void) } break; case 1: - EAX = CPUID; + EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID); EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 7)) + EDX |= CPUID_PGE; break; case 0x80000000: EAX = 0x80000005; @@ -2197,6 +2508,8 @@ cpu_CPUID(void) EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 7)) + EDX |= CPUID_PGE; break; case 0x80000002: /* Processor name string */ EAX = 0x20414956; /* VIA Samuel */ @@ -2223,12 +2536,22 @@ cpu_ven_reset(void) memset(&msr, 0, sizeof(msr)); switch (cpu_s->cpu_type) { + case CPU_WINCHIP: + case CPU_WINCHIP2: + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msr.mcr_ctrl = 0xf8000000; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + msr.fcr |= (1 << 18) | (1 << 20); + msr.mcr_ctrl |= (1 << 17); + } + break; + case CPU_K6_2P: case CPU_K6_3P: case CPU_K6_3: case CPU_K6_2C: msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; - /* FALLTHROUGH */ + fallthrough; case CPU_K6_2: #if defined(DEV_BRANCH) && defined(USE_AMD_K5) case CPU_K5: @@ -2242,7 +2565,11 @@ cpu_ven_reset(void) case CPU_PENTIUM2: case CPU_PENTIUM2D: msr.mtrr_cap = 0x00000508ULL; - /* FALLTHROUGH */ + break; + + case CPU_CYRIX3S: + msr.fcr = (1 << 7) | (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | + (1 << 20) | (1 << 21); break; } } @@ -2256,18 +2583,28 @@ cpu_RDMSR(void) case CPU_IBM486BL: EAX = EDX = 0; switch (ECX) { + /* Processor Operation Register */ case 0x1000: EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); break; + /* Cache Region Control Register */ case 0x1001: - EAX = msr.ibm_crcr & 0xffffffffff; + EAX = msr.ibm_crcr & 0xffffffff; + EDX = (msr.ibm_crcr >> 32) & 0x0000ffff; break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) EAX = msr.ibm_por2 & 0x3f000000; break; + + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + EAX = msr.ibm_pcr & 0x00d6001a; + break; } break; @@ -2275,42 +2612,74 @@ cpu_RDMSR(void) case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { + /* Pentium Processor Parity Reversal Register */ case 0x02: EAX = msr.tr1; break; + /* Pentium Processor New Feature Control */ case 0x0e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ case 0x11: EAX = msr.cesr; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; + /* Feature Control Register */ case 0x107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; + /* Feature Control Register 4 */ case 0x10a: EAX = cpu_multi & 3; break; + /* Memory Configuration Register Control */ + case 0x120: + EAX = msr.mcr_ctrl; + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; case CPU_CYRIX3S: EAX = EDX = 0; switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2337,29 +2706,41 @@ cpu_RDMSR(void) if (cpu_busspeed >= 84000000) EAX |= (1 << 19); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + EAX = tsc & 0xffffffff; + EDX = (tsc >> 32) & 0xff; + break; + /* PERFCTR1 - Performance Counter Register 1 */ + case 0xc2: + EAX = msr.perfctr[1] & 0xffffffff; + EDX = msr.perfctr[1] >> 32; + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + EAX = 0x800000; /* L2 cache disabled */ + break; + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + EAX = 0x470079; + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + EAX = msr.evntsel[1] & 0xffffffff; + EDX = msr.evntsel[1] >> 32; + break; + /* Feature Control Register */ case 0x1107: EAX = msr.fcr; break; + /* Feature Control Register 2 */ case 0x1108: EAX = msr.fcr2 & 0xffffffff; EDX = msr.fcr2 >> 32; break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -2368,29 +2749,27 @@ cpu_RDMSR(void) EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; @@ -2408,37 +2787,75 @@ cpu_RDMSR(void) case CPU_K6_3: case CPU_K6_2P: case CPU_K6_3P: - EAX = EDX = 0; + EAX = 0; + /* EDX is left unchanged when reading this MSR! */ + if (ECX != 0x82) + EDX = 0; switch (ECX) { + /* Machine Check Address Register */ case 0x00000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; + /* Machine Check Type Register */ case 0x00000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; break; + /* Test Register 12 */ case 0x0000000e: EAX = msr.tr12; break; + /* Time Stamp Counter */ case 0x00000010: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_aar & 0xffffffff; + /* EDX is left unchanged! */ + break; + /* Hardware Configuration Register */ case 0x00000083: - EAX = msr.ecx83 & 0xffffffff; - EDX = msr.ecx83 >> 32; + EAX = msr.amd_hwcr & 0xffffffff; + EDX = msr.amd_hwcr >> 32; break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_watmcr & 0xffffffff; + EDX = msr.amd_watmcr >> 32; + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_rdmsr; + EAX = msr.amd_wapmrr & 0xffffffff; + EDX = msr.amd_wapmrr >> 32; + break; + /* Extended Feature Enable Register */ case 0xc0000080: EAX = msr.amd_efer & 0xffffffff; EDX = msr.amd_efer >> 32; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_rdmsr; - EAX = msr.star & 0xffffffff; - EDX = msr.star >> 32; + EAX = msr.amd_star & 0xffffffff; + EDX = msr.amd_star >> 32; break; + /* Write-Handling Control Register */ case 0xc0000082: EAX = msr.amd_whcr & 0xffffffff; EDX = msr.amd_whcr >> 32; break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2446,6 +2863,7 @@ cpu_RDMSR(void) EAX = msr.amd_uwccr & 0xffffffff; EDX = msr.amd_uwccr >> 32; break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_rdmsr; @@ -2453,6 +2871,7 @@ cpu_RDMSR(void) EAX = msr.amd_epmr & 0xffffffff; EDX = msr.amd_epmr >> 32; break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2460,6 +2879,7 @@ cpu_RDMSR(void) EAX = msr.amd_psor & 0xffffffff; EDX = msr.amd_psor >> 32; break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_rdmsr; @@ -2467,6 +2887,7 @@ cpu_RDMSR(void) EAX = msr.amd_pfir & 0xffffffff; EDX = msr.amd_pfir >> 32; break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_rdmsr; @@ -2484,52 +2905,253 @@ cpu_RDMSR(void) case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: + EAX = EDX = 0; + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { + /* Machine Check Exception Address */ + case 0x00000000: + case 0x80000000: + EAX = msr.mcar & 0xffffffff; + EDX = msr.mcar >> 32; + break; + /* Machine Check Exception Type */ + case 0x00000001: + case 0x80000001: + EAX = msr.mctr & 0xffffffff; + EDX = msr.mctr >> 32; + msr.mctr &= ~0x1; /* clear the machine check pending bit */ + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + EAX = msr.tr1; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_rdmsr; + EAX = msr.tr2; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + EAX = msr.tr3; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + EAX = msr.tr4; + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + EAX = msr.tr5; + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + EAX = msr.tr6; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + EAX = msr.tr7; + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + EAX = msr.tr9; + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + EAX = msr.tr10; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + EAX = msr.tr11; + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + EAX = msr.tr12; + break; + /* Time Stamp Counter */ + case 0x00000010: + case 0x80000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_rdmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + EAX = ((cr0 & (1 << 31)) ? 0x00000008 : 0x00000004); + break; + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + EAX = 0; + break; + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + EAX = 0; + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt; + break; + /* Unknown */ + case 0x8000001c: + EAX = 0x00000004; + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + EAX = msr.ecx8000001e; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + EAX = msr.ecx8000001f; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + EAX = (ECX & 0x1f) * 2; + break; + default: +pentium_invalid_rdmsr: + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + break; + #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: case CPU_Cx6x86MX: - if (cpu_s->cpu_type < CPU_Cx6x86) -#endif - EAX = EDX = 0; switch (ECX) { - case 0x00: - case 0x01: + /* Test Data */ + case 0x03: + EAX = msr.tr3; + break; + /* Test Address */ + case 0x04: + EAX = msr.tr4; break; + /* Test Command/Status */ + case 0x05: + EAX = msr.tr5; + break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* Performance Monitor - Control and Event Select */ + case 0x11: + EAX = msr.cesr; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + EAX = msr.pmc[0] & 0xffffffff; + EDX = msr.pmc[0] >> 32; + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + EAX = msr.pmc[1] & 0xffffffff; + EDX = msr.pmc[1] >> 32; + break; } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; +#endif case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + /* IA32_PLATFORM_ID - Platform ID */ case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) + if (cpu_s->cpu_type < CPU_PENTIUM2D) goto i686_invalid_rdmsr; if (cpu_f->package == CPU_PKG_SLOT2) - EDX |= 0x80000; + EDX |= (1 << 19); else if (cpu_f->package == CPU_PKG_SOCKET370) - EDX |= 0x100000; + EDX |= (1 << 20); break; + /* Unknown */ + case 0x18: + break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1B: EAX = msr.apic_base & 0xffffffff; EDX = msr.apic_base >> 32; cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ + case 0x20: + EAX = msr.ecx20 & 0xffffffff; + EDX = msr.ecx20 >> 32; + break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: EAX = 0xc4000000; EDX = 0; @@ -2564,47 +3186,85 @@ cpu_RDMSR(void) EAX |= (1 << 19); } break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + EAX = msr.test_ctl; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: - EAX = msr.ecx79 & 0xffffffff; - EDX = msr.ecx79 >> 32; + EAX = msr.bios_updt & 0xffffffff; + EDX = msr.bios_updt >> 32; + break; + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: + EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; + EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; - EDX = msr.ecx8x[ECX - 0x88] >> 32; + /* Unknown */ + case 0xae: break; + /* PERFCTR0 - Performance Counter Register 0 */ case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + EAX = msr.perfctr[ECX - 0xC1] & 0xffffffff; + EDX = msr.perfctr[ECX - 0xC1] >> 32; break; + /* MTRRcap */ case 0xfe: EAX = msr.mtrr_cap & 0xffffffff; EDX = msr.mtrr_cap >> 32; break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: - EAX = msr.ecx116 & 0xffffffff; - EDX = msr.ecx116 >> 32; + EAX = msr.bbl_cr_addr & 0xffffffff; + EDX = msr.bbl_cr_addr >> 32; break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: + EAX = msr.bbl_cr_decc & 0xffffffff; + EDX = msr.bbl_cr_decc >> 32; + break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: + EAX = msr.bbl_cr_ctl & 0xffffffff; + EDX = msr.bbl_cr_ctl >> 32; + break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: + EAX = msr.bbl_cr_trig & 0xffffffff; + EDX = msr.bbl_cr_trig >> 32; + break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: - EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; - EDX = msr.ecx11x[ECX - 0x118] >> 32; + EAX = msr.bbl_cr_busy & 0xffffffff; + EDX = msr.bbl_cr_busy >> 32; break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: - EAX = msr.ecx11e & 0xffffffff; - EDX = msr.ecx11e >> 32; + EAX = msr.bbl_cr_ctl3 & 0xffffffff; + EDX = msr.bbl_cr_ctl3 >> 32; + break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2613,6 +3273,7 @@ cpu_RDMSR(void) EAX |= msr.sysenter_cs; EDX = 0x00000000; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2620,6 +3281,7 @@ cpu_RDMSR(void) EAX = msr.sysenter_esp; EDX = 0x00000000; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; @@ -2627,44 +3289,49 @@ cpu_RDMSR(void) EAX = msr.sysenter_eip; EDX = 0x00000000; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: EAX = 0x00000105; EDX = 0x00000000; break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: EAX = msr.mcg_ctl & 0xffffffff; EDX = msr.mcg_ctl >> 32; break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - EAX = msr.ecx186 & 0xffffffff; - EDX = msr.ecx186 >> 32; - break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - EAX = msr.ecx187 & 0xffffffff; - EDX = msr.ecx187 >> 32; - break; + EAX = msr.evntsel[ECX - 0x186] & 0xffffffff; + EDX = msr.evntsel[ECX - 0x186] >> 32; + break; + /* Unknown */ + case 0x1d3: + break; + /* DEBUGCTLMSR - Debugging Control Register */ + case 0x1d9: + EAX = msr.debug_ctl; + break; + /* LASTBRANCHFROMIP - address from which a branch was last taken */ + case 0x1db: + /* LASTBRANCHTOIP - destination address of the last taken branch instruction */ + case 0x1dc: + /* LASTINTFROMIP - address at which an interrupt last occurred */ + case 0x1dd: + /* LASTINTTOIP - address to which the last interrupt caused a branch */ + case 0x1de: + break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - EAX = msr.ecx1e0 & 0xffffffff; - EDX = msr.ecx1e0 >> 32; - break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + EAX = msr.rob_cr_bkuptmpdr6; + break; + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) { EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; @@ -2673,75 +3340,87 @@ cpu_RDMSR(void) EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; } break; + /* MTRRfix64K_00000 */ case 0x250: EAX = msr.mtrr_fix64k_8000 & 0xffffffff; EDX = msr.mtrr_fix64k_8000 >> 32; break; + /* MTRRfix16K_80000 */ case 0x258: EAX = msr.mtrr_fix16k_8000 & 0xffffffff; EDX = msr.mtrr_fix16k_8000 >> 32; break; + /* MTRRfix16K_A0000 */ case 0x259: EAX = msr.mtrr_fix16k_a000 & 0xffffffff; EDX = msr.mtrr_fix16k_a000 >> 32; break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; break; + /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_rdmsr; EAX = msr.pat & 0xffffffff; EDX = msr.pat >> 32; break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + break; + /* MTRRdefType */ case 0x2ff: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: break; + /* Unknown */ case 0x570: EAX = msr.ecx570 & 0xffffffff; EDX = msr.ecx570 >> 32; break; - case 0x1002ff: - EAX = msr.ecx1002ff & 0xffffffff; - EDX = msr.ecx1002ff >> 32; - break; - case 0xf0f00250: - EAX = msr.ecxf0f00250 & 0xffffffff; - EDX = msr.ecxf0f00250 >> 32; - break; - case 0xf0f00258: - EAX = msr.ecxf0f00258 & 0xffffffff; - EDX = msr.ecxf0f00258 >> 32; - break; - case 0xf0f00259: - EAX = msr.ecxf0f00259 & 0xffffffff; - EDX = msr.ecxf0f00259 >> 32; + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: break; default: i686_invalid_rdmsr: @@ -2764,38 +3443,59 @@ cpu_WRMSR(void) switch (cpu_s->cpu_type) { case CPU_IBM386SLC: - case CPU_IBM486BL: case CPU_IBM486SLC: + case CPU_IBM486BL: switch (ECX) { + /* Processor Operation Register */ case 0x1000: msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); cpu_cache_int_enabled = (EAX & (1 << 7)); break; + /* Cache Region Control Register */ case 0x1001: - msr.ibm_crcr = EAX & 0xffffffffff; + msr.ibm_crcr = EAX | ((uint64_t) (EDX & 0x0000ffff) << 32); break; + /* Processor Operation Register */ case 0x1002: if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) msr.ibm_por2 = EAX & 0x3f000000; break; + /* Processor Control Register */ + case 0x1004: + if (cpu_s->cpu_type > CPU_IBM486SLC) + msr.ibm_pcr = EAX & 0x00d6001a; + break; } break; case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) { + /* Pentium Processor Parity Reversal Register */ case 0x02: msr.tr1 = EAX & 2; break; + /* Pentium Processor New Feature Control */ case 0x0e: - msr.tr12 = EAX & 0x228; + msr.tr12 = EAX & 0x248; break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Performance Monitor - Control and Event Select */ case 0x11: msr.cesr = EAX & 0xff00ff; break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* Feature Control Register */ case 0x107: msr.fcr = EAX; if (EAX & (1 << 9)) @@ -2815,76 +3515,111 @@ cpu_WRMSR(void) else CPUID = cpu_s->cpuid_model; break; + /* Feature Control Register 2 */ case 0x108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; + /* Memory Configuration Register 0..7 */ + case 0x110 ... 0x117: + temp = ECX - 0x110; + if (cpu_s->cpu_type == CPU_WINCHIP2) { + if (EAX & 0x1f) + msr.mcr_ctrl |= (1 << (temp + 9)); + else + msr.mcr_ctrl &= ~(1 << (temp + 9)); + } + msr.mcr[temp] = EAX | ((uint64_t) EDX << 32); + break; + /* Memory Configuration Register Control */ + case 0x120: + msr.mcr_ctrl = EAX & ((cpu_s->cpu_type == CPU_WINCHIP2) ? 0x1df : 0x1f); + break; + /* Unknown */ + case 0x131: + case 0x142 ... 0x145: + case 0x147: + case 0x150: + case 0x151: + break; } break; case CPU_CYRIX3S: switch (ECX) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */ + case 0xc1: + break; + /* PERFCTR0 - Performance Counter Register 1 */ + case 0xc2: + msr.perfctr[1] = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ + case 0x11e: + /* EVNTSEL0 - Performance Counter Event Select 0 - hardcoded */ + case 0x186: + break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ + case 0x187: + msr.evntsel[1] = EAX | ((uint64_t) EDX << 32); + break; + /* Feature Control Register */ case 0x1107: msr.fcr = EAX; if (EAX & (1 << 1)) cpu_features |= CPU_FEATURE_CX8; else cpu_features &= ~CPU_FEATURE_CX8; + if (EAX & (1 << 7)) + cpu_CR4_mask |= CR4_PGE; + else + cpu_CR4_mask &= ~CR4_PGE; break; + /* Feature Control Register 2 */ case 0x1108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); break; + /* Feature Control Register 3 */ case 0x1109: msr.fcr3 = EAX | ((uint64_t) EDX << 32); break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26A: - case 0x26B: - case 0x26C: - case 0x26D: - case 0x26E: - case 0x26F: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; @@ -2902,18 +3637,47 @@ cpu_WRMSR(void) case CPU_K6_2P: case CPU_K6_3P: switch (ECX) { - case 0x00: - case 0x01: + /* Machine Check Address Register */ + case 0x00000000: + if (cpu_s->cpu_type > CPU_5K86) + msr.mcar = EAX | ((uint64_t) EDX << 32); break; - case 0x0e: - msr.tr12 = EAX & 0x228; + /* Machine Check Type Register */ + case 0x00000001: + if (cpu_s->cpu_type > CPU_5K86) + msr.mctr = EAX | ((uint64_t) EDX << 32); break; - case 0x10: + /* Test Register 12 */ + case 0x0000000e: + msr.tr12 = EAX & 0x8; + break; + /* Time Stamp Counter */ + case 0x00000010: tsc = EAX | ((uint64_t) EDX << 32); break; - case 0x83: - msr.ecx83 = EAX | ((uint64_t) EDX << 32); + /* Array Access Register */ + case 0x00000082: + if (cpu_s->cpu_type > CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_aar = EAX | ((uint64_t) EDX << 32); break; + /* Hardware Configuration Register */ + case 0x00000083: + msr.amd_hwcr = EAX | ((uint64_t) EDX << 32); + break; + /* Write Allocate Top-of-Memory and Control Register */ + case 0x00000085: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_watmcr = EAX | ((uint64_t) EDX << 32); + break; + /* Write Allocate Programmable Memory Range Register */ + case 0x00000086: + if (cpu_s->cpu_type != CPU_5K86) + goto amd_k_invalid_wrmsr; + msr.amd_wapmrr = EAX | ((uint64_t) EDX << 32); + break; + /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); if (temp & ~1ULL) @@ -2921,39 +3685,46 @@ cpu_WRMSR(void) else msr.amd_efer = temp; break; + /* SYSCALL Target Address Register */ case 0xc0000081: if (cpu_s->cpu_type < CPU_K6_2) goto amd_k_invalid_wrmsr; - msr.star = EAX | ((uint64_t) EDX << 32); + msr.amd_star = EAX | ((uint64_t) EDX << 32); break; + /* Write-Handling Control Register */ case 0xc0000082: msr.amd_whcr = EAX | ((uint64_t) EDX << 32); break; + /* UC/WC Cacheability Control Register */ case 0xc0000085: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_uwccr = EAX | ((uint64_t) EDX << 32); break; + /* Enhanced Power Management Register */ case 0xc0000086: if (cpu_s->cpu_type < CPU_K6_2P) goto amd_k_invalid_wrmsr; msr.amd_epmr = EAX | ((uint64_t) EDX << 32); break; + /* Processor State Observability Register */ case 0xc0000087: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_psor = EAX | ((uint64_t) EDX << 32); break; + /* Page Flush/Invalidate Register */ case 0xc0000088: if (cpu_s->cpu_type < CPU_K6_2C) goto amd_k_invalid_wrmsr; msr.amd_pfir = EAX | ((uint64_t) EDX << 32); break; + /* Level-2 Cache Array Access Register */ case 0xc0000089: if (cpu_s->cpu_type < CPU_K6_3) goto amd_k_invalid_wrmsr; @@ -2970,201 +3741,430 @@ cpu_WRMSR(void) case CPU_P24T: case CPU_PENTIUM: case CPU_PENTIUMMMX: + cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + /* Filter out the upper 27 bits when ECX value is over 0x80000000, as per: + Ralf Brown, Pentium Model-Specific Registers and What They Reveal. + https://www.cs.cmu.edu/~ralf/papers/highmsr.html + But leave the bit 31 intact to be able to handle both low and high + MSRs in a single switch block. */ + switch (ECX & (ECX > 0x7fffffff ? 0x8000001f : 0x7fffffff)) { + /* Machine Check Exception Address */ + case 0x00000000: + case 0x80000000: + /* Machine Check Exception Type */ + case 0x00000001: + case 0x80000001: + break; + /* TR1 - Parity Reversal Test Register */ + case 0x00000002: + case 0x80000002: + msr.tr1 = EAX & 0x3fff; + break; + /* TR2 - Instruction Cache End Bit */ + case 0x00000004: + case 0x80000004: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + goto pentium_invalid_wrmsr; + msr.tr2 = EAX & 0xf; + break; + /* TR3 - Cache Test Data */ + case 0x00000005: + case 0x80000005: + msr.tr3 = EAX; + break; + /* TR4 - Cache Test Tag */ + case 0x00000006: + case 0x80000006: + msr.tr4 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffff1f : 0xffffff07); + break; + /* TR5 - Cache Test Control */ + case 0x00000007: + case 0x80000007: + msr.tr5 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0x87fff : 0x7fff); + break; + /* TR6 - TLB Test Command */ + case 0x00000008: + case 0x80000008: + msr.tr6 = EAX & 0xffffff07; + break; + /* TR7 - TLB Test Data */ + case 0x00000009: + case 0x80000009: + msr.tr7 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xfffffc7f : 0xffffff9c); + break; + /* TR9 - Branch Target Buffer Tag */ + case 0x0000000b: + case 0x8000000b: + msr.tr9 = EAX & ((cpu_s->cpu_type == CPU_PENTIUMMMX) ? 0xffffffff : 0xffffffc3); + break; + /* TR10 - Branch Target Buffer Target */ + case 0x0000000c: + case 0x8000000c: + msr.tr10 = EAX; + break; + /* TR11 - Branch Target Buffer Control */ + case 0x0000000d: + case 0x8000000d: + msr.tr11 = EAX & ((cpu_s->cpu_type >= CPU_PENTIUMMMX) ? 0x3001fcf : 0xfcf); + break; + /* TR12 - New Feature Control */ + case 0x0000000e: + case 0x8000000e: + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + temp = EAX & 0x38034f; + else if ((CPUID & 0xfff) >= 0x52b) + temp = EAX & 0x20435f; + else if ((CPUID & 0xfff) >= 0x520) + temp = EAX & 0x20035f; + else + temp = EAX & 0x20030f; + msr.tr12 = temp; + break; + /* Time Stamp Counter */ + case 0x00000010: + case 0x80000010: + tsc = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Control and Event Select */ + case 0x00000011: + case 0x80000011: + msr.cesr = EAX & 0x3ff03ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x00000012: + case 0x80000012: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x00000013: + case 0x80000013: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); + break; + /* Unknown */ + case 0x00000014: + case 0x80000014: + if ((CPUID & 0xfff) <= 0x520) + goto pentium_invalid_wrmsr; + break; + /* Unknown, possibly paging-related; initial value is 0004h, + becomes 0008h once paging is enabled */ + case 0x80000018: + /* Floating point - last prefetched opcode + bits 10-8: low three bits of first byte of FP instruction + bits 7-0: second byte of floating-point instruction */ + case 0x80000019: + /* Floating point - last executed non-control opcode */ + case 0x8000001a: + break; + /* Floating point - last non-control exception opcode - part + of FSTENV/FSAVE'd environment */ + case 0x8000001b: + EAX = msr.fp_last_xcpt & 0x7ff; + break; + /* Unknown */ + case 0x8000001c: + break; + /* Probe Mode Control */ + case 0x8000001d: + EAX = msr.probe_ctl & 0x7; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001e: + msr.ecx8000001e = EAX; + break; + /* Unknown, possibly scratchpad register */ + case 0x8000001f: + msr.ecx8000001f = EAX; + break; + /* Reserved/Unimplemented */ + case 0x80000003: + case 0x8000000a: + case 0x8000000f: + case 0x80000015 ... 0x80000017: + break; + default: +pentium_invalid_wrmsr: + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; + #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: case CPU_Cx6x86MX: -#endif cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { - case 0x00: - case 0x01: - break; + /* Test Data */ + case 0x03: + msr.tr3 = EAX; + /* Test Address */ + case 0x04: + msr.tr4 = EAX; + /* Test Command/Status */ + case 0x05: + msr.tr5 = EAX & 0x008f0f3b; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; - case 0x8b: -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type < CPU_Cx6x86) { -#endif - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - } -#endif + /* Performance Monitor - Control and Event Select */ + case 0x11: + msr.cesr = EAX & 0x7ff07ff; + break; + /* Performance Monitor - Event Counter 0 */ + case 0x12: + msr.pmc[0] = EAX | ((uint64_t) EDX << 32); + break; + /* Performance Monitor - Event Counter 1 */ + case 0x13: + msr.pmc[1] = EAX | ((uint64_t) EDX << 32); break; } break; +#endif case CPU_PENTIUMPRO: case CPU_PENTIUM2: case CPU_PENTIUM2D: - switch (ECX) { + /* Per RichardG's probing of a real Deschutes using my RDMSR tool, + we have discovered that the top 18 bits are filtered out. */ + switch (ECX & 0x00003fff) { + /* Machine Check Exception Address */ case 0x00: + /* Machine Check Exception Type */ case 0x01: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Time Stamp Counter */ case 0x10: tsc = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x18: + break; + /* IA32_APIC_BASE - APIC Base Address */ case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); - // msr.apic_base = EAX | ((uint64_t) EDX << 32); +#if 0 + msr.apic_base = EAX | ((uint64_t) EDX << 32); +#endif break; + /* Unknown (undocumented?) MSR used by the Hyper-V BIOS */ + case 0x20: + msr.ecx20 = EAX | ((uint64_t) EDX << 32); + break; + /* Unknown */ + case 0x21: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; + /* EBL_CR_POWERON - Processor Hard Power-On Configuration */ case 0x2a: break; + /* Unknown */ + case 0x32: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; + /* TEST_CTL - Test Control Register */ + case 0x33: + msr.test_ctl = EAX; + break; + /* Unknown */ + case 0x34: + case 0x3a: + case 0x3b: + case 0x50 ... 0x54: + break; + /* BIOS_UPDT_TRIG - BIOS Update Trigger */ case 0x79: - msr.ecx79 = EAX | ((uint64_t) EDX << 32); + msr.bios_updt = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_D0 ... BBL_CR_D3 - Chunk 0..3 Data Register + 8Bh: BIOS_SIGN - BIOS Update Signature */ + case 0x88 ... 0x8b: + msr.bbl_cr_dx[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); break; - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); + /* Unknown */ + case 0xae: break; + /* PERFCTR0 - Performance Counter Register 0 */ case 0xc1: + /* PERFCTR1 - Performance Counter Register 1 */ case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); + msr.perfctr[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRcap */ case 0xfe: msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_ADDR - L2 Cache Address Register */ case 0x116: - msr.ecx116 = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_addr = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_DECC - L2 Cache Date ECC Register */ case 0x118: + msr.bbl_cr_decc = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_CTL - L2 Cache Control Register */ case 0x119: + msr.bbl_cr_ctl = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_TRIG - L2 Cache Trigger Register */ case 0x11a: + msr.bbl_cr_trig = EAX | ((uint64_t) EDX << 32); + break; + /* BBL_CR_BUSY - L2 Cache Busy Register */ case 0x11b: - msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_busy = EAX | ((uint64_t) EDX << 32); break; + /* BBL_CR_CTL3 - L2 Cache Control Register 3 */ case 0x11e: - msr.ecx11e = EAX | ((uint64_t) EDX << 32); + msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x131: + case 0x14e ... 0x151: + case 0x154: + case 0x15b: + case 0x15f: + break; + /* SYSENTER_CS - SYSENTER target CS */ case 0x174: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_cs = EAX & 0xFFFF; break; + /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_esp = EAX; break; + /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; msr.sysenter_eip = EAX; break; + /* MCG_CAP - Machine Check Global Capability */ case 0x179: break; + /* MCG_STATUS - Machine Check Global Status */ case 0x17a: if (EAX || EDX) x86gpf(NULL, 0); break; + /* MCG_CTL - Machine Check Global Control */ case 0x17b: msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); break; + /* EVNTSEL0 - Performance Counter Event Select 0 */ case 0x186: - msr.ecx186 = EAX | ((uint64_t) EDX << 32); - break; + /* EVNTSEL1 - Performance Counter Event Select 1 */ case 0x187: - msr.ecx187 = EAX | ((uint64_t) EDX << 32); + msr.evntsel[ECX - 0x186] = EAX | ((uint64_t) EDX << 32); + break; + case 0x1d3: break; + /* DEBUGCTLMSR - Debugging Control Register */ + case 0x1d9: + msr.debug_ctl = EAX; + break; + /* ROB_CR_BKUPTMPDR6 */ case 0x1e0: - msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); - break; - case 0x200: - case 0x201: - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: + msr.rob_cr_bkuptmpdr6 = EAX; + break; + /* ECX & 0: MTRRphysBase0 ... MTRRphysBase7 + ECX & 1: MTRRphysMask0 ... MTRRphysMask7 */ + case 0x200 ... 0x20f: if (ECX & 1) msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); else msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix64K_00000 */ case 0x250: msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_80000 */ case 0x258: msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); break; + /* MTRRfix16K_A0000 */ case 0x259: msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); break; - case 0x268: - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: + /* MTRRfix4K_C0000 ... MTRRfix4K_F8000 */ + case 0x268 ... 0x26f: msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); break; + /* Page Attribute Table */ case 0x277: + if (cpu_s->cpu_type < CPU_PENTIUM2D) + goto i686_invalid_wrmsr; msr.pat = EAX | ((uint64_t) EDX << 32); break; + /* Unknown */ + case 0x280: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + break; + /* MTRRdefType */ case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); break; + /* MC0_CTL - Machine Check 0 Control */ case 0x400: + /* MC1_CTL - Machine Check 1 Control */ case 0x404: + /* MC2_CTL - Machine Check 2 Control */ case 0x408: + /* MC4_CTL - Machine Check 4 Control */ case 0x40c: + /* MC3_CTL - Machine Check 3 Control */ case 0x410: msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t) EDX << 32); break; + /* MC0_STATUS - Machine Check 0 Status */ case 0x401: + /* MC0_ADDR - Machine Check 0 Address */ case 0x402: + /* MC1_STATUS - Machine Check 1 Status */ case 0x405: + /* MC1_ADDR - Machine Check 1 Address */ case 0x406: - case 0x407: + /* MC2_STATUS - Machine Check 2 Status */ case 0x409: + /* MC2_ADDR - Machine Check 2 Address */ + case 0x40a: + /* MC4_STATUS - Machine Check 4 Status */ case 0x40d: + /* MC4_ADDR - Machine Check 4 Address */ case 0x40e: + /* MC3_STATUS - Machine Check 3 Status */ case 0x411: + /* MC3_ADDR - Machine Check 3 Address */ case 0x412: if (EAX || EDX) x86gpf(NULL, 0); break; + /* Unknown */ case 0x570: msr.ecx570 = EAX | ((uint64_t) EDX << 32); break; - case 0x1002ff: - msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00250: - msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00258: - msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32); - break; - case 0xf0f00259: - msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32); + /* Unknown, possibly debug registers? */ + case 0x1000 ... 0x1007: + /* Unknown, possibly control registers? */ + case 0x2000: + case 0x2002 ... 0x2004: break; default: i686_invalid_wrmsr: @@ -3177,7 +4177,7 @@ cpu_WRMSR(void) } static void -cpu_write(uint16_t addr, uint8_t val, void *priv) +cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { if (addr == 0xf0) { /* Writes to F0 clear FPU error and deassert the interrupt. */ @@ -3225,7 +4225,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv) if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); if ((val & 0xf) == 0xf) - cyrix.arr[3].size = 1ull << 32; /* 4 GB */ + cyrix.arr[3].size = 1ULL << 32; /* 4 GB */ else if (val & 0xf) cyrix.arr[3].size = 2048 << (val & 0xf); else @@ -3259,7 +4259,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -cpu_read(uint16_t addr, void *priv) +cpu_read(uint16_t addr, UNUSED(void *priv)) { if (addr == 0xf007) return 0x7f; @@ -3287,6 +4287,9 @@ cpu_read(uint16_t addr, void *priv) return cpu_s->cyrix_id & 0xff; case 0xff: return cpu_s->cyrix_id >> 8; + + default: + break; } if ((cyrix_addr & 0xf0) == 0xc0) @@ -3312,11 +4315,18 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, #else x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) { - x86_opcodes = opcodes; + x86_opcodes = opcodes; x86_opcodes_0f = opcodes_0f; } #endif +void +x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f) +{ + x86_2386_opcodes = opcodes; + x86_2386_opcodes_0f = opcodes_0f; +} + void cpu_update_waitstates(void) { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 029794bd6e..16a9eba10e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -86,42 +86,33 @@ enum { }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_386SX = (1 << 6), - CPU_PKG_386DX = (1 << 7), - CPU_PKG_M6117 = (1 << 8), - CPU_PKG_386SLC_IBM = (1 << 9), - CPU_PKG_486SLC = (1 << 10), - CPU_PKG_486SLC_IBM = (1 << 11), - CPU_PKG_486BL = (1 << 12), - CPU_PKG_486DLC = (1 << 13), - CPU_PKG_SOCKET1 = (1 << 14), - CPU_PKG_SOCKET3 = (1 << 15), - CPU_PKG_SOCKET3_PC330 = (1 << 16), - CPU_PKG_STPC = (1 << 17), - CPU_PKG_SOCKET4 = (1 << 18), - CPU_PKG_SOCKET5_7 = (1 << 19), - CPU_PKG_SOCKET8 = (1 << 20), - CPU_PKG_SLOT1 = (1 << 21), - CPU_PKG_SLOT2 = (1 << 22), - CPU_PKG_SLOTA = (1 << 23), - CPU_PKG_SOCKET370 = (1 << 24), - CPU_PKG_SOCKETA = (1 << 25), - CPU_PKG_EBGA368 = (1 << 26) + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_188 = (1 << 3), + CPU_PKG_186 = (1 << 4), + CPU_PKG_286 = (1 << 5), + CPU_PKG_386SX = (1 << 6), + CPU_PKG_386DX = (1 << 7), + CPU_PKG_386DX_DESKPRO386 = (1 << 8), + CPU_PKG_M6117 = (1 << 9), + CPU_PKG_386SLC_IBM = (1 << 10), + CPU_PKG_486SLC = (1 << 11), + CPU_PKG_486SLC_IBM = (1 << 12), + CPU_PKG_486BL = (1 << 13), + CPU_PKG_486DLC = (1 << 14), + CPU_PKG_SOCKET1 = (1 << 15), + CPU_PKG_SOCKET3 = (1 << 16), + CPU_PKG_SOCKET3_PC330 = (1 << 17), + CPU_PKG_STPC = (1 << 18), + CPU_PKG_SOCKET4 = (1 << 19), + CPU_PKG_SOCKET5_7 = (1 << 20), + CPU_PKG_SOCKET8 = (1 << 21), + CPU_PKG_SLOT1 = (1 << 22), + CPU_PKG_SLOT2 = (1 << 23), + CPU_PKG_SOCKET370 = (1 << 24) }; -#define MANU_INTEL 0 -#define MANU_AMD 1 -#define MANU_CYRIX 2 -#define MANU_IDT 3 -#define MANU_NEC 4 -#define MANU_IBM 5 - #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 #define CPU_ALTERNATE_XTAL 4 @@ -133,25 +124,27 @@ enum { # define LOOKUP_INV -1 #endif -typedef struct { +typedef struct fpu_t { const char *name; const char *internal_name; const int type; } FPU; -typedef struct { +typedef struct cpu_t { const char *name; uint64_t cpu_type; const FPU *fpus; - int rspeed; + uint32_t rspeed; double multi; uint16_t voltage; uint32_t edx_reset; uint32_t cpuid_model; uint16_t cyrix_id; uint8_t cpu_flags; - int8_t mem_read_cycles, mem_write_cycles; - int8_t cache_read_cycles, cache_write_cycles; + int8_t mem_read_cycles; + int8_t mem_write_cycles; + int8_t cache_read_cycles; + int8_t cache_write_cycles; int8_t atclk_div; } CPU; @@ -163,17 +156,6 @@ typedef struct { const CPU *cpus; } cpu_family_t; -typedef struct { - const char *family; - const int rspeed; - const double multi; -} cpu_legacy_table_t; - -typedef struct { - const char *machine; - const cpu_legacy_table_t **tables; -} cpu_legacy_machine_t; - #define C_FLAG 0x0001 #define P_FLAG 0x0004 #define A_FLAG 0x0010 @@ -192,6 +174,7 @@ typedef struct { #define VIP_FLAG 0x0010 /* in EFLAGS */ #define VID_FLAG 0x0020 /* in EFLAGS */ +#define EM_FLAG 0x00004 /* in CR0 */ #define WP_FLAG 0x10000 /* in CR0 */ #define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */ @@ -215,17 +198,19 @@ typedef union { uint32_t l; uint16_t w; struct { - uint8_t l, - h; + uint8_t l; + uint8_t h; } b; } x86reg; typedef struct { uint32_t base; uint32_t limit; - uint8_t access, ar_high; + uint8_t access; + uint8_t ar_high; uint16_t seg; - uint32_t limit_low, limit_high; + uint32_t limit_low; + uint32_t limit_high; int checked; /*Non-zero if selector is known to be valid*/ } x86seg; @@ -242,98 +227,97 @@ typedef union { } MMX_REG; typedef struct { - /* IDT WinChip and WinChip 2 MSR's */ - uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */ - uint32_t cesr; /* 0x00000011 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ - uint64_t ecx79; /* 0x00000079 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ - - /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ - uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ - uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx116; /* 0x00000116 */ - uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ - uint64_t ecx11e; /* 0x0000011e */ - - /* Pentium II Klamath and Pentium II Deschutes MSR's */ - uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ - uint64_t ecx1e0; /* 0x000001e0 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + /* IBM 386SLC/486SLC/486BL MSRs */ + uint64_t ibm_por; /* 0x00001000 - 386SLC and later */ + uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */ + uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */ + uint64_t ibm_pcr; /* 0x00001004 - 486BL3 */ + + /* IDT WinChip C6/2/VIA Cyrix III MSRs */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint64_t mcr[8]; /* 0x00000110 - 0x00000117 (IDT) */ + uint32_t mcr_ctrl; /* 0x00000120 (IDT) */ + + /* AMD K5/K6 MSRs */ + uint64_t amd_aar; /* 0x00000082 - all K5 */ + uint64_t amd_hwcr; /* 0x00000083 - all K5 and all K6 */ + uint64_t amd_watmcr; /* 0x00000085 - K5 Model 1 and later */ + uint64_t amd_wapmrr; /* 0x00000086 - K5 Model 1 and later */ + + uint64_t amd_efer; /* 0xc0000080 - all K5 and all K6 */ + uint64_t amd_star; /* 0xc0000081 - K6-2 and later */ + uint64_t amd_whcr; /* 0xc0000082 - all K5 and all K6 */ + uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */ + uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */ + uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */ + uint64_t amd_pfir; /* 0xc0000088 - K6-2C and later */ + uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */ + + /* Pentium/Pentium MMX MSRs */ + uint64_t mcar; /* 0x00000000 - also on K5 and (R/W) K6 */ + uint64_t mctr; /* 0x00000001 - also on K5 and (R/W) K6 */ + uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */ + uint32_t tr2; /* 0x00000004 - reserved on PMMX */ + uint32_t tr3; /* 0x00000005 */ + uint32_t tr4; /* 0x00000006 */ + uint32_t tr5; /* 0x00000007 */ + uint32_t tr6; /* 0x00000008 */ + uint32_t tr7; /* 0x00000009 */ + uint32_t tr9; /* 0x0000000b */ + uint32_t tr10; /* 0x0000000c */ + uint32_t tr11; /* 0x0000000d */ + uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 and K6 */ + uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 and Cx6x86MX */ + uint64_t pmc[2]; /* 0x00000012, 0x00000013 - also on WinChip C6/2 and Cx6x86MX */ + uint32_t fp_last_xcpt; /* 0x8000001b - undocumented */ + uint32_t probe_ctl; /* 0x8000001d - undocumented */ + uint32_t ecx8000001e; /* 0x8000001e - undocumented */ + uint32_t ecx8000001f; /* 0x8000001f - undocumented */ + + /* Pentium Pro/II MSRs */ + uint64_t apic_base; /* 0x0000001b */ + uint32_t test_ctl; /* 0x00000033 */ + uint64_t bios_updt; /* 0x00000079 */ + + uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */ + uint64_t perfctr[2]; /* 0x000000c1, 0x000000c2 */ + uint64_t mtrr_cap; /* 0x000000fe */ + + uint64_t bbl_cr_addr; /* 0x00000116 */ + uint64_t bbl_cr_decc; /* 0x00000118 */ + uint64_t bbl_cr_ctl; /* 0x00000119 */ + uint64_t bbl_cr_trig; /* 0x0000011a */ + uint64_t bbl_cr_busy; /* 0x0000011b */ + uint64_t bbl_cr_ctl3; /* 0x0000011e */ + + uint16_t sysenter_cs; /* 0x00000174 - Pentium II and later */ + uint32_t sysenter_esp; /* 0x00000175 - Pentium II and later */ + uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */ + + uint64_t mcg_ctl; /* 0x0000017b */ + uint64_t evntsel[2]; /* 0x00000186, 0x00000187 */ + + uint32_t debug_ctl; /* 0x000001d9 */ + uint32_t rob_cr_bkuptmpdr6; /* 0x000001e0 */ + + /* MTTR-related MSRs also present on the VIA Cyrix III */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */ uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ uint64_t mtrr_fix64k_8000; /* 0x00000250 */ uint64_t mtrr_fix16k_8000; /* 0x00000258 */ uint64_t mtrr_fix16k_a000; /* 0x00000259 */ uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + uint64_t mtrr_deftype; /* 0x000002ff */ - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t pat; /* 0x00000277 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also - on the VIA Cyrix III */ - uint64_t mtrr_deftype; /* 0x000002ff */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ + uint64_t pat; /* 0x00000277 - Pentium II Deschutes and later */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 */ uint64_t ecx570; /* 0x00000570 */ - /* IBM 386SLC, 486SLC, and 486BL MSR's */ - uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ - uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ - - /* IBM 486SLC and 486BL MSR's */ - uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_efer; /* 0xc0000080 */ - - /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t star; /* 0xc0000081 */ - - /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_whcr; /* 0xc0000082 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_uwccr; /* 0xc0000085 */ - - /* AMD K6-2P and K6-3P MSR's */ - uint64_t amd_epmr; /* 0xc0000086 */ - - /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */ - - /* K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_l2aar; /* 0xc0000089 */ - - /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ - uint64_t ecxf0f00258; /* 0xf0f00258 */ - uint64_t ecxf0f00259; /* 0xf0f00259 */ + /* Other/Unclassified MSRs */ + uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits + like a real Deschutes does. */ } msr_t; typedef struct { @@ -345,33 +329,38 @@ typedef struct { uint32_t eaaddr; int flags_op; - uint32_t flags_res, - flags_op1, flags_op2; + uint32_t flags_res; + uint32_t flags_op1; + uint32_t flags_op2; - uint32_t pc, - oldpc, op32; + uint32_t pc; + uint32_t oldpc; + uint32_t op32; int TOP; union { struct { - int8_t rm, - mod, - reg; + int8_t rm; + int8_t mod; + int8_t reg; } rm_mod_reg; int32_t rm_mod_reg_data; } rm_data; - uint8_t ssegs, ismmx, - abrt, _smi_line; + uint8_t ssegs; + uint8_t ismmx; + uint8_t abrt; + uint8_t _smi_line; + int _cycles; #ifdef FPU_CYCLES - int _cycles, _fpu_cycles, _in_smm; -#else - int _cycles, _in_smm; + int _fpu_cycles; #endif + int _in_smm; - uint16_t npxs, npxc; + uint16_t npxs; + uint16_t npxc; double ST[8]; @@ -380,42 +369,57 @@ typedef struct { MMX_REG MM[8]; #ifdef USE_NEW_DYNAREC - uint32_t old_fp_control, new_fp_control; +# if defined(__APPLE__) && defined(__aarch64__) + uint64_t old_fp_control; + uint64_t new_fp_control; +# else + uint32_t old_fp_control; + uint32_t new_fp_control; +# endif # if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 - uint16_t old_fp_control2, new_fp_control2; + uint16_t old_fp_control2; + uint16_t new_fp_control2; # endif # if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64 - uint32_t trunc_fp_control; + uint32_t trunc_fp_control; # endif #else - uint16_t old_npxc, new_npxc; + uint16_t old_npxc; + uint16_t new_npxc; #endif - x86seg seg_cs, seg_ds, seg_es, seg_ss, - seg_fs, seg_gs; + x86seg seg_cs; + x86seg seg_ds; + x86seg seg_es; + x86seg seg_ss; + x86seg seg_fs; + x86seg seg_gs; union { uint32_t l; uint16_t w; } CR0; - uint16_t flags, eflags; + uint16_t flags; + uint16_t eflags; uint32_t _smbase; } cpu_state_t; typedef struct { - uint16_t cwd; - uint16_t swd; - uint16_t tag; - uint16_t foo; - uint32_t fip; - uint32_t fdp; - uint16_t fcs; - uint16_t fds; - floatx80 st_space[8]; + uint16_t cwd; + uint16_t swd; + uint16_t tag; + uint16_t foo; + uint32_t fip; + uint32_t fdp; + uint16_t fcs; + uint16_t fds; + floatx80 st_space[8]; unsigned char tos; - unsigned char align1, align2, align3; + unsigned char align1; + unsigned char align2; + unsigned char align3; } fpu_state_t; #define in_smm cpu_state._in_smm @@ -431,9 +435,9 @@ typedef struct { #define CPU_STATUS_V86 (1 << 3) #define CPU_STATUS_SMM (1 << 4) #ifdef USE_NEW_DYNAREC -#define CPU_STATUS_FLAGS 0xff +# define CPU_STATUS_FLAGS 0xff #else -#define CPU_STATUS_FLAGS 0xffff +# define CPU_STATUS_FLAGS 0xffff #endif /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. @@ -501,24 +505,36 @@ extern cpu_state_t cpu_state; extern fpu_state_t fpu_state; extern const cpu_family_t cpu_families[]; -extern const cpu_legacy_machine_t cpu_legacy_table[]; extern cpu_family_t *cpu_f; extern CPU *cpu_s; extern int cpu_override; extern int cpu_isintel; extern int cpu_iscyrix; -extern int cpu_16bitbus, cpu_64bitbus; +extern int cpu_16bitbus; +extern int cpu_64bitbus; extern int cpu_pci_speed; extern int cpu_multi; extern double cpu_dmulti; extern double fpu_multi; extern double cpu_busspeed; -extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment - penalties when crossing 8-byte boundaries*/ - -extern int is8086, is186, is286, is386, is6117, is486; -extern int is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm; +extern int cpu_cyrix_alignment; /* Cyrix 5x86/6x86 only has data misalignment + penalties when crossing 8-byte boundaries. */ +extern int cpu_cpurst_on_sr; /* SiS 551x and 5571: Issue CPURST on soft reset. */ + +extern int is8086; +extern int is186; +extern int is286; +extern int is386; +extern int is6117; +extern int is486; +extern int is_am486; +extern int is_am486dxl; +extern int is_pentium; +extern int is_k5; +extern int is_k6; +extern int is_p6; +extern int is_cxsmm; extern int hascache; extern int isibm486; extern int is_nec; @@ -536,7 +552,8 @@ extern int hasfpu; extern uint32_t cpu_features; -extern int smi_latched, smm_in_hlt; +extern int smi_latched; +extern int smm_in_hlt; extern int smi_block; #ifdef USE_NEW_DYNAREC @@ -548,30 +565,40 @@ extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; extern uint8_t opcode; -extern int cgate16; extern int cpl_override; extern int CPUID; extern uint64_t xt_cpu_multi; -extern int isa_cycles, cpu_inited; -extern uint32_t oldds, oldss, olddslimit, oldsslimit, olddslimitw, oldsslimitw; +extern int isa_cycles; +extern int cpu_inited; +extern uint32_t oldds; +extern uint32_t oldss; +extern uint32_t olddslimit; +extern uint32_t oldsslimit; +extern uint32_t olddslimitw; +extern uint32_t oldsslimitw; extern uint32_t pccache; extern uint8_t *pccache2; -extern double bus_timing, isa_timing, pci_timing, agp_timing; -extern uint64_t pmc[2]; +extern double bus_timing; +extern double isa_timing; +extern double pci_timing; +extern double agp_timing; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; extern uint32_t esp_msr; extern uint32_t eip_msr; /* For the AMD K6. */ -extern uint64_t amd_efer, star; +extern uint64_t amd_efer; +extern uint64_t star; #define FPU_CW_Reserved_Bits (0xe0c0) #define cr0 cpu_state.CR0.l #define msw cpu_state.CR0.w -extern uint32_t cr2, cr3, cr4; +extern uint32_t cr2; +extern uint32_t cr3; +extern uint32_t cr4; extern uint32_t dr[8]; extern uint32_t _tr[8]; extern uint32_t cache_index; @@ -581,7 +608,10 @@ extern uint8_t _cache[2048]; _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data cs,ds,es,ss are defines to the bases*/ -extern x86seg gdt, ldt, idt, tr; +extern x86seg gdt; +extern x86seg ldt; +extern x86seg idt; +extern x86seg tr; extern x86seg _oldds; #define CS cpu_state.seg_cs.seg #define DS cpu_state.seg_ds.seg @@ -598,51 +628,72 @@ extern x86seg _oldds; #define ISA_CYCLES(x) (x * isa_cycles) -extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; -extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; +extern int cpu_cycles_read; +extern int cpu_cycles_read_l; +extern int cpu_cycles_write; +extern int cpu_cycles_write_l; +extern int cpu_prefetch_cycles; +extern int cpu_prefetch_width; +extern int cpu_mem_prefetch_cycles; +extern int cpu_rom_prefetch_cycles; extern int cpu_waitstates; -extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; -extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed; +extern int cpu_cache_int_enabled; +extern int cpu_cache_ext_enabled; +extern int cpu_isa_speed; +extern int cpu_pci_speed; +extern int cpu_agp_speed; extern int timing_rr; -extern int timing_mr, timing_mrl; -extern int timing_rm, timing_rml; -extern int timing_mm, timing_mml; -extern int timing_bt, timing_bnt; -extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm; -extern int timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm; -extern int timing_iret_pm_outer, timing_call_rm, timing_call_pm; -extern int timing_call_pm_gate, timing_call_pm_gate_inner; -extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +extern int timing_mr; +extern int timing_mrl; +extern int timing_rm; +extern int timing_rml; +extern int timing_mm; +extern int timing_mml; +extern int timing_bt; +extern int timing_bnt; +extern int timing_int; +extern int timing_int_rm; +extern int timing_int_v86; +extern int timing_int_pm; +extern int timing_int_pm_outer; +extern int timing_iret_rm; +extern int timing_iret_v86; +extern int timing_iret_pm; +extern int timing_iret_pm_outer; +extern int timing_call_rm; +extern int timing_call_pm; +extern int timing_call_pm_gate; +extern int timing_call_pm_gate_inner; +extern int timing_retf_rm; +extern int timing_retf_pm; +extern int timing_retf_pm_outer; +extern int timing_jmp_rm; +extern int timing_jmp_pm; +extern int timing_jmp_pm_gate; extern int timing_misaligned; -extern int in_sys, unmask_a20_in_smm; +extern int in_sys; +extern int unmask_a20_in_smm; extern int cycles_main; extern uint32_t old_rammask; #ifdef USE_ACYCS extern int acycs; #endif -extern int pic_pending, is_vpc; -extern int soft_reset_mask, alt_access; +extern int pic_pending; +extern int is_vpc; +extern int soft_reset_mask; +extern int alt_access; extern int cpu_end_block_after_ins; -extern uint16_t cpu_fast_off_count, cpu_fast_off_val; +extern uint16_t cpu_fast_off_count; +extern uint16_t cpu_fast_off_val; extern uint32_t cpu_fast_off_flags; /* Functions. */ extern int cpu_has_feature(int feature); -#ifdef USE_NEW_DYNAREC -extern void loadseg_dynarec(uint16_t seg, x86seg *s); -extern int loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); -#else -extern void loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); -#endif - extern char *cpu_current_pc(char *bufp); extern void cpu_update_waitstates(void); @@ -662,26 +713,14 @@ extern void codegen_block_end(void); extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); -extern void execx86(int cycs); +extern void execx86(int32_t cycs); extern void enter_smm(int in_hlt); extern void enter_smm_check(int in_hlt); extern void leave_smm(void); -extern void exec386(int cycs); -extern void exec386_dynarec(int cycs); +extern void exec386_2386(int32_t cycs); +extern void exec386(int32_t cycs); +extern void exec386_dynarec(int32_t cycs); extern int idivl(int32_t val); -#ifdef USE_NEW_DYNAREC -extern void loadcscall(uint16_t seg, uint32_t old_pc); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); -#else -extern void loadcscall(uint16_t seg); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); -#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); @@ -691,11 +730,6 @@ extern void hardresetx86(void); extern void x86_int(int num); extern void x86_int_sw(int num); extern int x86_int_sw_rm(int num); -extern void x86de(char *s, uint16_t error); -extern void x86gpf(char *s, uint16_t error); -extern void x86np(char *s, uint16_t error); -extern void x86ss(char *s, uint16_t error); -extern void x86ts(char *s, uint16_t error); #ifdef ENABLE_808X_LOG extern void dumpregs(int __force); @@ -703,7 +737,8 @@ extern void x87_dumpregs(void); extern void x87_reset(void); #endif -extern int cpu_effective, cpu_alt_reset; +extern int cpu_effective; +extern int cpu_alt_reset; extern void cpu_dynamic_switch(int new_cpu); extern void cpu_ven_reset(void); @@ -728,30 +763,40 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); #define SMHR_VALID (1 << 0) #define SMHR_ADDR_MASK (0xfffffffc) -typedef struct -{ - struct - { +typedef union { + uint32_t fd; + uint8_t b[4]; +} fetch_dat_t; + +typedef struct { + struct { uint32_t base; uint64_t size; } arr[8]; uint32_t smhr; } cyrix_t; -extern uint32_t addr64, addr64_2; -extern uint32_t addr64a[8], addr64a_2[8]; +extern uint32_t addr64; +extern uint32_t addr64_2; +extern uint32_t addr64a[8]; +extern uint32_t addr64a_2[8]; extern int soft_reset_pci; -extern int reset_on_hlt, hlt_reset_pending; +extern int reset_on_hlt; +extern int hlt_reset_pending; extern cyrix_t cyrix; +extern int prefetch_prefixes; +extern int cpu_use_exec; + extern uint8_t use_custom_nmi_vector; extern uint32_t custom_nmi_vector; -extern void (*cpu_exec)(int cycs); -extern uint8_t do_translate, do_translate2; +extern void (*cpu_exec)(int32_t cycs); +extern uint8_t do_translate; +extern uint8_t do_translate2; extern void SF_FPU_reset(void); @@ -766,4 +811,26 @@ extern void cpu_fast_off_reset(void); extern void smi_raise(void); extern void nmi_raise(void); +extern MMX_REG *MMP[8]; +extern uint16_t *MMEP[8]; + +extern int cpu_block_end; +extern int cpu_override_dynarec; + +extern void mmx_init(void); +extern void prefetch_flush(void); + +extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32); + +extern int lock_legal[256]; +extern int lock_legal_0f[256]; +extern int lock_legal_ba[8]; +extern int lock_legal_80[8]; +extern int lock_legal_f6[8]; +extern int lock_legal_fe[8]; + +extern int in_lock; + +extern int is_lock_legal(uint32_t fetchdat); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 3afaf055e4..502b2c86e3 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -33,39 +33,39 @@ #include <86box/machine.h> FPU fpus_none[] = { - {"None", "none", FPU_NONE}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_8088[] = { - {"None", "none", FPU_NONE}, - { "8087", "8087", FPU_8087}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "8087", .internal_name = "8087", .type = FPU_8087 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80186[] = { - {"None", "none", FPU_NONE }, - { "8087", "8087", FPU_8087 }, - { "80187", "80187", FPU_80187}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "8087", .internal_name = "8087", .type = FPU_8087 }, + { .name = "80187", .internal_name = "80187", .type = FPU_80187 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80286[] = { - {"None", "none", FPU_NONE }, - { "287", "287", FPU_287 }, - { "287XL", "287xl", FPU_287XL}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "287", .internal_name = "287", .type = FPU_287 }, + { .name = "287XL", .internal_name = "287xl", .type = FPU_287XL }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80386[] = { - {"None", "none", FPU_NONE}, - { "387", "387", FPU_387 }, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "387", .internal_name = "387", .type = FPU_387 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_486sx[] = { - {"None", "none", FPU_NONE }, - { "487SX", "487sx", FPU_487SX}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "487SX", .internal_name = "487sx", .type = FPU_487SX }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_internal[] = { - {"Internal", "internal", FPU_INTERNAL}, - { NULL, NULL, 0 } + { .name = "Internal", .internal_name = "internal", .type = FPU_INTERNAL }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; const cpu_family_t cpu_families[] = { @@ -76,14 +76,128 @@ const cpu_family_t cpu_families[] = { .name = "8088", .internal_name = "8088", .cpus = (const CPU[]) { - {"4.77", CPU_8088, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_8088, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8", CPU_8088, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, -// {"9.54", CPU_8088, fpus_8088, 9545456, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_8088, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_8088, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_8088, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, +#if 0 + { + .name = "9.54", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, +#endif + { + .name = "10", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8088_EUROPC, @@ -91,10 +205,58 @@ const cpu_family_t cpu_families[] = { .name = "8088", .internal_name = "8088_europc", .cpus = (const CPU[]) { - {"4.77", CPU_8088, fpus_8088, 4772728, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"7.16", CPU_8088, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"9.54", CPU_8088, fpus_8088, 9545456, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8086, @@ -102,13 +264,109 @@ const cpu_family_t cpu_families[] = { .name = "8086", .internal_name = "8086", .cpus = (const CPU[]) { - {"7.16", CPU_8086, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_8086, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_8086, fpus_8088, 9545456, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_8086, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_8086, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_8086, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "7.16", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_188, @@ -116,16 +374,160 @@ const cpu_family_t cpu_families[] = { .name = "80188", .internal_name = "80188", .cpus = (const CPU[]) { - {"6", CPU_188, fpus_8088, 6000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_188, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_188, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_188, fpus_8088, 9545456, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_188, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_188, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_188, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"20", CPU_188, fpus_8088, 20000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3}, - {"25", CPU_188, fpus_8088, 25000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8088, @@ -133,12 +535,92 @@ const cpu_family_t cpu_families[] = { .name = "V20", .internal_name = "necv20", .cpus = (const CPU[]) { - {"4.77", CPU_V20, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_V20, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_V20, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_V20, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_V20, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_186, @@ -146,16 +628,160 @@ const cpu_family_t cpu_families[] = { .name = "80186", .internal_name = "80186", .cpus = (const CPU[]) { - {"6", CPU_186, fpus_80186, 6000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_186, fpus_80186, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_186, fpus_80186, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_186, fpus_80186, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_186, fpus_80186, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_186, fpus_80186, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_186, fpus_80186, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, - {"20", CPU_186, fpus_80186, 20000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3}, - {"25", CPU_186, fpus_80186, 25000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 6000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 7159092, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 8000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 9545456, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 10000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 12000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 16000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 20000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 25000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8086, @@ -163,12 +789,92 @@ const cpu_family_t cpu_families[] = { .name = "V30", .internal_name = "necv30", .cpus = (const CPU[]) { - {"5", CPU_V30, fpus_80186, 5000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8", CPU_V30, fpus_80186, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_V30, fpus_80186, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_V30, fpus_80186, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_V30, fpus_80186, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "5", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 5000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_286, @@ -176,14 +882,126 @@ const cpu_family_t cpu_families[] = { .name = "80286", .internal_name = "286", .cpus = (const CPU[]) { - {"6", CPU_286, fpus_80286, 6000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"8", CPU_286, fpus_80286, 8000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"10", CPU_286, fpus_80286, 10000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"12", CPU_286, fpus_80286, 12500000, 1, 5000, 0, 0, 0, 0, 3,3,3,3, 2}, - {"16", CPU_286, fpus_80286, 16000000, 1, 5000, 0, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_286, fpus_80286, 20000000, 1, 5000, 0, 0, 0, 0, 4,4,4,4, 3}, - {"25", CPU_286, fpus_80286, 25000000, 1, 5000, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 12500000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "16", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 4, + .cache_write_cycles = 4, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 4, + .cache_write_cycles = 4, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386SX, @@ -225,6 +1043,17 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { + .package = CPU_PKG_386DX_DESKPRO386, + .manufacturer = "Intel", + .name = "i386DX", + .internal_name = "i386dx_deskpro386", + .cpus = (const CPU[]) { + {"16", CPU_386DX, fpus_80286, 16000000, 1, 5000, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"20", CPU_386DX, fpus_80386, 20000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"25", CPU_386DX, fpus_80386, 25000000, 1, 5000, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"", 0} + } + }, { .package = CPU_PKG_386DX, .manufacturer = "Intel", .name = "RapidCAD", @@ -252,8 +1081,8 @@ const cpu_family_t cpu_families[] = { .name = "M6117", .internal_name = "m6117", .cpus = (const CPU[]) { /* All timings and edx_reset values assumed. */ - {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"33", CPU_386SX, fpus_none, 33333333, 1, 5000, 0x2309, 0, 0, 0, 6,6,3,3, 4}, + {"40", CPU_386SX, fpus_none, 40000000, 1, 5000, 0x2309, 0, 0, 0, 7,7,3,3, 5}, {"", 0} } }, { @@ -378,7 +1207,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486SX (SL-Enhanced)", + .name = "i486SX-S", .internal_name = "i486sx_slenh", .cpus = (const CPU[]) { {"25", CPU_i486SX_SLENH, fpus_486sx, 25000000, 1, 5000, 0x423, 0x423, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, @@ -409,7 +1238,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486DX (SL-Enhanced)", + .name = "i486DX-S", .internal_name = "i486dx_slenh", .cpus = (const CPU[]) { {"33", CPU_i486DX_SLENH, fpus_internal, 33333333, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, @@ -430,7 +1259,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486DX2 (SL-Enhanced)", + .name = "i486DX2-S", .internal_name = "i486dx2_slenh", .cpus = (const CPU[]) { {"40", CPU_i486DX_SLENH, fpus_internal, 40000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, @@ -439,13 +1268,13 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, { - .package = CPU_PKG_SOCKET3_PC330, + .package = CPU_PKG_SOCKET1 | CPU_PKG_SOCKET3_PC330, .manufacturer = "Intel", - .name = "i486DX2", + .name = "i486DX2 WB", .internal_name = "i486dx2_pc330", .cpus = (const CPU[]) { - {"50", CPU_i486DX_SLENH, fpus_internal, 50000000, 2, 5000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"66", CPU_i486DX_SLENH, fpus_internal, 66666666, 2, 5000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"50", CPU_i486DX_SLENH, fpus_internal, 50000000, 2, 5000, 0x436, 0x436, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"66", CPU_i486DX_SLENH, fpus_internal, 66666666, 2, 5000, 0x436, 0x436, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, {"", 0} } }, { @@ -569,9 +1398,9 @@ const cpu_family_t cpu_families[] = { .name = "Am5x86", .internal_name = "am5x86", .cpus = (const CPU[]) { - {"P75", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"P75+", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ - {"P90", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"133 (P75)", CPU_ENH_Am486DX, fpus_internal, 133333333, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"150 (P75+)", CPU_ENH_Am486DX, fpus_internal, 150000000, 3.0, 5000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"160 (P90)", CPU_ENH_Am486DX, fpus_internal, 160000000, 4.0, 5000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ {"", 0} } }, { @@ -786,28 +1615,25 @@ const cpu_family_t cpu_families[] = { { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", - .name = "K5 (5k86)", - .internal_name = "k5_5k86", + .name = "K5 (Model 0)", + .internal_name = "k5_ssa5", .cpus = (const CPU[]) { - {"75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, {"", 0} } }, { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", - .name = "K5 (SSA/5)", - .internal_name = "k5_ssa5", + .name = "K5 (Model 1/2/3)", + .internal_name = "k5_5k86", .cpus = (const CPU[]) { - {"75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 3520, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 3520, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 3520, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"116.7 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 3520, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 3520, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, {"", 0} } }, @@ -945,12 +1771,12 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86", .internal_name = "cx6x86", .cpus = (const CPU[]) { - {"P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"80 (PR90+)", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"100 (PR120+)", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"110 (PR133+)", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 3520, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -959,10 +1785,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86L", .internal_name = "cx6x86l", .cpus = (const CPU[]) { - {"PR133+", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"PR150+", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"PR166+", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200+", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"110 (PR133+)", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"120 (PR150+)", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"133 (PR166+)", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"150 (PR200+)", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 2800, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, {"", 0} } }, { @@ -971,10 +1797,10 @@ const cpu_family_t cpu_families[] = { .name = "Cx6x86MX", .internal_name = "cx6x86mx", .cpus = (const CPU[]) { - {"PR166", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"PR200", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"PR233", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, - {"PR266", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"133 (PR166)", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 2900, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"166 (PR200)", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"187.5 (PR233)", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 2900, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"208.3 (PR266)", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 2700, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, {"", 0} } }, { @@ -983,11 +1809,11 @@ const cpu_family_t cpu_families[] = { .name = "MII", .internal_name = "mii", .cpus = (const CPU[]) { - {"PR300", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, - {"PR333", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, - {"PR366", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, - {"PR400", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, - {"PR433", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"233 (PR300)", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 2900, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"250/83 (PR333)", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"250/100 (PR366)", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"285 (PR400)", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"300 (PR433)", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 2900, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, {"", 0} } }, @@ -1154,956 +1980,3 @@ const cpu_family_t cpu_families[] = { } // clang-format on }; - -/* Legacy CPU tables for backwards compatibility. */ - -static const cpu_legacy_table_t cpus_8088[] = { - {"8088", 4772728, 1}, - { "8088", 7159092, 1}, - { "8088", 8000000, 1}, - { "8088", 10000000, 1}, - { "8088", 12000000, 1}, - { "8088", 16000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_pcjr[] = { - {"8088", 4772728, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_europc[] = { - {"8088_europc", 4772728, 1}, - { "8088_europc", 7159092, 1}, - { "8088_europc", 9545456, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_8086[] = { - {"8086", 7159092, 1}, - { "8086", 8000000, 1}, - { "8086", 9545456, 1}, - { "8086", 10000000, 1}, - { "8086", 12000000, 1}, - { "8086", 16000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_pc1512[] = { - {"8086", 8000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_286[] = { - {"286", 6000000, 1}, - { "286", 8000000, 1}, - { "286", 10000000, 1}, - { "286", 12500000, 1}, - { "286", 16000000, 1}, - { "286", 20000000, 1}, - { "286", 25000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ibmat[] = { - {"286", 6000000, 1}, - { "286", 8000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ibmxt286[] = { - {"286", 6000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ps1_m2011[] = { - {"286", 10000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ps2_m30_286[] = { - {"286", 10000000, 1}, - { "286", 12500000, 1}, - { "286", 16000000, 1}, - { "286", 20000000, 1}, - { "286", 25000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i386SX[] = { - {"i386sx", 16000000, 1}, - { "i386sx", 20000000, 1}, - { "i386sx", 25000000, 1}, - { "i386sx", 33333333, 1}, - { "i386sx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i386DX[] = { - {"i386dx", 16000000, 1}, - { "i386dx", 20000000, 1}, - { "i386dx", 25000000, 1}, - { "i386dx", 33333333, 1}, - { "i386dx", 40000000, 1}, - { "rapidcad", 25000000, 1}, - { "rapidcad", 33333333, 1}, - { "rapidcad", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am386SX[] = { - {"am386sx", 16000000, 1}, - { "am386sx", 20000000, 1}, - { "am386sx", 25000000, 1}, - { "am386sx", 33333333, 1}, - { "am386sx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am386DX[] = { - {"am386dx", 25000000, 1}, - { "am386dx", 33333333, 1}, - { "am386dx", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_ALiM6117[] = { - {"m6117", 33333333, 1}, - { "m6117", 40000000, 1}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_486SLC[] = { - {"cx486slc", 20000000, 1}, - { "cx486slc", 25000000, 1}, - { "cx486slc", 33333333, 1}, - { "cx486srx2", 32000000, 2}, - { "cx486srx2", 40000000, 2}, - { "cx486srx2", 50000000, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_IBM486SLC[] = { - {"ibm486slc", 33333333, 1}, - { "ibm486slc2", 40000000, 2}, - { "ibm486slc2", 50000000, 2}, - { "ibm486slc2", 66666666, 2}, - { "ibm486slc3", 60000000, 3}, - { "ibm486slc3", 75000000, 3}, - { "ibm486slc3", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_IBM486BL[] = { - {"ibm486bl2", 50000000, 2}, - { "ibm486bl2", 66666666, 2}, - { "ibm486bl3", 75000000, 3}, - { "ibm486bl3", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_486DLC[] = { - {"cx486dlc", 25000000, 1}, - { "cx486dlc", 33333333, 1}, - { "cx486dlc", 40000000, 1}, - { "cx486drx2", 32000000, 2}, - { "cx486drx2", 40000000, 2}, - { "cx486drx2", 50000000, 2}, - { "cx486drx2", 66666666, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_i486S1[] = { - {"i486sx", 16000000, 1}, - { "i486sx", 20000000, 1}, - { "i486sx", 25000000, 1}, - { "i486sx", 33333333, 1}, - { "i486sx2", 50000000, 2}, - { "i486sx2", 66666666, 2}, - { "i486dx", 25000000, 1}, - { "i486dx", 33333333, 1}, - { "i486dx", 50000000, 1}, - { "i486dx2", 40000000, 2}, - { "i486dx2", 50000000, 2}, - { "i486dx2", 66666666, 2}, - { "idx4_od", 75000000, 3}, - { "idx4_od", 100000000, 3}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Am486S1[] = { - {"am486sx", 33333333, 1}, - { "am486sx", 40000000, 1}, - { "am486sx2", 50000000, 2}, - { "am486sx2", 66666666, 2}, - { "am486dx", 33333333, 1}, - { "am486dx", 40000000, 1}, - { "am486dx2", 50000000, 2}, - { "am486dx2", 66666666, 2}, - { "am486dx2", 80000000, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_Cx486S1[] = { - {"cx486s", 25000000, 1.0}, - { "cx486s", 33333333, 1.0}, - { "cx486s", 40000000, 1.0}, - { "cx486dx", 33333333, 1.0}, - { "cx486dx", 40000000, 1.0}, - { "cx486dx2", 50000000, 2.0}, - { "cx486dx2", 66666666, 2.0}, - { "cx486dx2", 80000000, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_i486[] = { - {"i486sx", 16000000, 1.0}, - { "i486sx", 20000000, 1.0}, - { "i486sx", 25000000, 1.0}, - { "i486sx", 33333333, 1.0}, - { "i486sx2", 50000000, 2.0}, - { "i486sx2", 66666666, 2.0}, - { "i486dx", 25000000, 1.0}, - { "i486dx", 33333333, 1.0}, - { "i486dx", 50000000, 1.0}, - { "i486dx2", 40000000, 2.0}, - { "i486dx2", 50000000, 2.0}, - { "i486dx2", 66666666, 2.0}, - { "idx4", 75000000, 3.0}, - { "idx4", 100000000, 3.0}, - { "idx4_od", 75000000, 3.0}, - { "idx4_od", 100000000, 3.0}, - { "pentium_p24t", 62500000, 2.5}, - { "pentium_p24t", 83333333, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_i486_PC330[] = { - {"i486dx2", 50000000, 2.0}, - { "i486dx2", 66666666, 2.0}, - { "idx4", 75000000, 3.0}, - { "idx4", 100000000, 3.0}, - { "pentium_p24t", 62500000, 2.5}, - { "pentium_p24t", 83333333, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Am486[] = { - {"am486sx", 33333333, 1.0}, - { "am486sx", 40000000, 1.0}, - { "am486sx2", 50000000, 2.0}, - { "am486sx2", 66666666, 2.0}, - { "am486dx", 33333333, 1.0}, - { "am486dx", 40000000, 1.0}, - { "am486dx2", 50000000, 2.0}, - { "am486dx2", 66666666, 2.0}, - { "am486dx2", 80000000, 2.0}, - { "am486dx4", 75000000, 3.0}, - { "am486dx4", 90000000, 3.0}, - { "am486dx4", 100000000, 3.0}, - { "am486dx4", 120000000, 3.0}, - { "am5x86", 133333333, 4.0}, - { "am5x86", 150000000, 3.0}, - { "am5x86", 160000000, 4.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Cx486[] = { - {"cx486s", 25000000, 1.0}, - { "cx486s", 33333333, 1.0}, - { "cx486s", 40000000, 1.0}, - { "cx486dx", 33333333, 1.0}, - { "cx486dx", 40000000, 1.0}, - { "cx486dx2", 50000000, 2.0}, - { "cx486dx2", 66666666, 2.0}, - { "cx486dx2", 80000000, 2.0}, - { "cx486dx4", 75000000, 3.0}, - { "cx486dx4", 100000000, 3.0}, - { "cx5x86", 80000000, 2.0}, - { "cx5x86", 100000000, 3.0}, - { "cx5x86", 120000000, 3.0}, - { "cx5x86", 133333333, 4.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_STPCDX[] = { - {"stpc_dx", 66666666, 1.0}, - { "stpc_dx", 75000000, 1.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_STPCDX2[] = { - {"stpc_dx2", 133333333, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x863V[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x86[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { "cx6x86l", 110000000, 2.0}, - { "cx6x86l", 120000000, 2.0}, - { "cx6x86l", 133333333, 2.0}, - { "cx6x86l", 150000000, 2.0}, - { "cx6x86mx", 133333333, 2.0}, - { "cx6x86mx", 166666666, 2.5}, - { "cx6x86mx", 187500000, 2.5}, - { "cx6x86mx", 208333333, 2.5}, - { "mii", 233333333, 3.5}, - { "mii", 250000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_6x86SS7[] = { - {"cx6x86", 80000000, 2.0}, - { "cx6x86", 100000000, 2.0}, - { "cx6x86", 110000000, 2.0}, - { "cx6x86", 120000000, 2.0}, - { "cx6x86", 133333333, 2.0}, - { "cx6x86", 150000000, 2.0}, - { "cx6x86l", 110000000, 2.0}, - { "cx6x86l", 120000000, 2.0}, - { "cx6x86l", 133333333, 2.0}, - { "cx6x86l", 150000000, 2.0}, - { "cx6x86mx", 133333333, 2.0}, - { "cx6x86mx", 166666666, 2.5}, - { "cx6x86mx", 187500000, 2.5}, - { "cx6x86mx", 208333333, 2.5}, - { "mii", 233333333, 3.5}, - { "mii", 250000000, 3.0}, - { "mii", 250000000, 2.5}, - { "mii", 285000000, 3.0}, - { "mii", 300000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_WinChip[] = { - {"winchip", 75000000, 1.5}, - { "winchip", 90000000, 1.5}, - { "winchip", 100000000, 1.5}, - { "winchip", 120000000, 2.0}, - { "winchip", 133333333, 2.0}, - { "winchip", 150000000, 2.5}, - { "winchip", 166666666, 2.5}, - { "winchip", 180000000, 3.0}, - { "winchip", 200000000, 3.0}, - { "winchip", 225000000, 3.0}, - { "winchip", 240000000, 4.0}, - { "winchip2", 200000000, 3.0}, - { "winchip2", 225000000, 3.0}, - { "winchip2", 240000000, 4.0}, - { "winchip2", 250000000, 3.0}, - { "winchip2a", 200000000, 3.0}, - { "winchip2a", 233333333, 3.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_WinChip_SS7[] = { - {"winchip", 75000000, 1.5}, - { "winchip", 90000000, 1.5}, - { "winchip", 100000000, 1.5}, - { "winchip", 120000000, 2.0}, - { "winchip", 133333333, 2.0}, - { "winchip", 150000000, 2.5}, - { "winchip", 166666666, 2.5}, - { "winchip", 180000000, 3.0}, - { "winchip", 200000000, 3.0}, - { "winchip", 225000000, 3.0}, - { "winchip", 240000000, 4.0}, - { "winchip2", 200000000, 3.0}, - { "winchip2", 225000000, 3.0}, - { "winchip2", 240000000, 4.0}, - { "winchip2", 250000000, 3.0}, - { "winchip2a", 200000000, 3.0}, - { "winchip2a", 233333333, 3.5}, - { "winchip2a", 233333333, 7.0}, - { "winchip2a", 250000000, 2.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium5V[] = { - {"pentium_p5", 60000000, 1}, - { "pentium_p5", 66666666, 1}, - { "pentium_p54c_od5v", 120000000, 2}, - { "pentium_p54c_od5v", 133333333, 2}, - { NULL, 0, 0} -}; - -static const cpu_legacy_table_t cpus_PentiumS5[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c_od3v", 125000000, 3.0}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium3V[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c", 150000000, 2.5}, - { "pentium_p54c", 166666666, 2.5}, - { "pentium_p54c", 200000000, 3.0}, - { "pentium_p54c_od3v", 125000000, 2.5}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Pentium[] = { - {"pentium_p54c", 75000000, 1.5}, - { "pentium_p55c_od", 75000000, 1.5}, - { "pentium_p54c", 90000000, 1.5}, - { "pentium_p54c", 100000000, 2.0}, - { "pentium_p54c", 100000000, 1.5}, - { "pentium_p54c", 120000000, 2.0}, - { "pentium_p54c", 133333333, 2.0}, - { "pentium_p54c", 150000000, 2.5}, - { "pentium_p54c", 166666666, 2.5}, - { "pentium_p54c", 200000000, 3.0}, - { "pentium_p55c", 166666666, 2.5}, - { "pentium_p55c", 200000000, 3.0}, - { "pentium_p55c", 233333333, 3.5}, - { "pentium_tillamook", 120000000, 2.0}, - { "pentium_tillamook", 133333333, 2.0}, - { "pentium_tillamook", 150000000, 2.5}, - { "pentium_tillamook", 166666666, 2.5}, - { "pentium_tillamook", 200000000, 3.0}, - { "pentium_tillamook", 233333333, 3.5}, - { "pentium_tillamook", 266666666, 4.0}, - { "pentium_tillamook", 300000000, 4.5}, - { "pentium_p54c_od3v", 125000000, 2.5}, - { "pentium_p54c_od3v", 150000000, 2.5}, - { "pentium_p54c_od3v", 166666666, 2.5}, - { "pentium_p55c_od", 125000000, 2.5}, - { "pentium_p55c_od", 150000000, 2.5}, - { "pentium_p55c_od", 166000000, 2.5}, - { "pentium_p55c_od", 180000000, 3.0}, - { "pentium_p55c_od", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K5[] = { - {"k5_5k86", 75000000, 1.5}, - { "k5_ssa5", 75000000, 1.5}, - { "k5_5k86", 90000000, 1.5}, - { "k5_ssa5", 90000000, 1.5}, - { "k5_5k86", 100000000, 1.5}, - { "k5_ssa5", 100000000, 1.5}, - { "k5_5k86", 120000000, 2.0}, - { "k5_5k86", 133333333, 2.0}, - { "k5_5k86", 150000000, 2.5}, - { "k5_5k86", 166666666, 2.5}, - { "k5_5k86", 200000000, 3.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K56[] = { - {"k6_m6", 66666666, 1.0}, - { "k6_m6", 100000000, 1.5}, - { "k6_m6", 133333333, 2.0}, - { "k6_m6", 166666666, 2.5}, - { "k6_m6", 200000000, 3.0}, - { "k6_m6", 233333333, 3.5}, - { "k6_m7", 100000000, 1.5}, - { "k6_m7", 133333333, 2.0}, - { "k6_m7", 166666666, 2.5}, - { "k6_m7", 200000000, 3.0}, - { "k6_m7", 233333333, 3.5}, - { "k6_m7", 266666666, 4.0}, - { "k6_m7", 300000000, 4.5}, - { "k6_2", 100000000, 1.5}, - { "k6_2", 133333333, 2.0}, - { "k6_2", 166666666, 2.5}, - { "k6_2", 200000000, 3.0}, - { "k6_2", 233333333, 3.5}, - { "k6_2", 266666666, 4.0}, - { "k6_2", 300000000, 4.5}, - { "k6_2", 366666666, 5.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_K56_SS7[] = { - {"k6_m6", 66666666, 1.0}, - { "k6_m6", 100000000, 1.5}, - { "k6_m6", 133333333, 2.0}, - { "k6_m6", 166666666, 2.5}, - { "k6_m6", 200000000, 3.0}, - { "k6_m6", 233333333, 3.5}, - { "k6_m7", 100000000, 1.5}, - { "k6_m7", 133333333, 2.0}, - { "k6_m7", 166666666, 2.5}, - { "k6_m7", 200000000, 3.0}, - { "k6_m7", 233333333, 3.5}, - { "k6_m7", 266666666, 4.0}, - { "k6_m7", 300000000, 4.5}, - { "k6_2", 100000000, 1.5}, - { "k6_2", 133333333, 2.0}, - { "k6_2", 166666666, 2.5}, - { "k6_2", 200000000, 3.0}, - { "k6_2", 233333333, 3.5}, - { "k6_2", 266666666, 4.0}, - { "k6_2", 300000000, 3.0}, - { "k6_2", 332500000, 3.5}, - { "k6_2", 350000000, 3.5}, - { "k6_2", 366666666, 5.5}, - { "k6_2", 380000000, 4.0}, - { "k6_2", 400000000, 4.0}, - { "k6_2", 450000000, 4.5}, - { "k6_2", 475000000, 5.0}, - { "k6_2", 500000000, 5.0}, - { "k6_2", 533333333, 5.5}, - { "k6_2", 550000000, 5.5}, - { "k6_2p", 100000000, 1.5}, - { "k6_2p", 133333333, 2.0}, - { "k6_2p", 166666666, 2.5}, - { "k6_2p", 200000000, 3.0}, - { "k6_2p", 233333333, 3.5}, - { "k6_2p", 266666666, 4.0}, - { "k6_2p", 300000000, 3.0}, - { "k6_2p", 332500000, 3.5}, - { "k6_2p", 350000000, 3.5}, - { "k6_2p", 366666666, 5.5}, - { "k6_2p", 380000000, 4.0}, - { "k6_2p", 400000000, 4.0}, - { "k6_2p", 450000000, 4.5}, - { "k6_2p", 475000000, 5.0}, - { "k6_2p", 500000000, 5.0}, - { "k6_2p", 533333333, 5.5}, - { "k6_2p", 550000000, 5.5}, - { "k6_3", 100000000, 1.5}, - { "k6_3", 133333333, 2.0}, - { "k6_3", 166666666, 2.5}, - { "k6_3", 200000000, 3.0}, - { "k6_3", 233333333, 3.5}, - { "k6_3", 266666666, 4.0}, - { "k6_3", 300000000, 3.0}, - { "k6_3", 332500000, 3.5}, - { "k6_3", 350000000, 3.5}, - { "k6_3", 366666666, 5.5}, - { "k6_3", 380000000, 4.0}, - { "k6_3", 400000000, 4.0}, - { "k6_3", 450000000, 4.5}, - { "k6_3p", 75000000, 1.5}, - { "k6_3p", 100000000, 1.5}, - { "k6_3p", 133333333, 2.0}, - { "k6_3p", 166666666, 2.5}, - { "k6_3p", 200000000, 3.0}, - { "k6_3p", 233333333, 3.5}, - { "k6_3p", 266666666, 4.0}, - { "k6_3p", 300000000, 3.0}, - { "k6_3p", 332500000, 3.5}, - { "k6_3p", 350000000, 3.5}, - { "k6_3p", 366666666, 5.5}, - { "k6_3p", 380000000, 4.0}, - { "k6_3p", 400000000, 4.0}, - { "k6_3p", 450000000, 4.5}, - { "k6_3p", 475000000, 5.0}, - { "k6_3p", 500000000, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumPro[] = { - {"pentiumpro", 50000000, 1.0}, - { "pentiumpro", 60000000, 1.0}, - { "pentiumpro", 66666666, 1.0}, - { "pentiumpro", 75000000, 1.5}, - { "pentiumpro", 150000000, 2.5}, - { "pentiumpro", 166666666, 2.5}, - { "pentiumpro", 180000000, 3.0}, - { "pentiumpro", 200000000, 3.0}, - { "pentium2_od", 50000000, 1.0}, - { "pentium2_od", 60000000, 1.0}, - { "pentium2_od", 66666666, 1.0}, - { "pentium2_od", 75000000, 1.5}, - { "pentium2_od", 210000000, 3.5}, - { "pentium2_od", 233333333, 3.5}, - { "pentium2_od", 240000000, 4.0}, - { "pentium2_od", 266666666, 4.0}, - { "pentium2_od", 270000000, 4.5}, - { "pentium2_od", 300000000, 4.5}, - { "pentium2_od", 300000000, 5.0}, - { "pentium2_od", 333333333, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumII66[] = { - {"pentium2_klamath", 50000000, 1.0}, - { "pentium2_klamath", 60000000, 1.0}, - { "pentium2_klamath", 66666666, 1.0}, - { "pentium2_klamath", 75000000, 1.5}, - { "pentium2_klamath", 233333333, 3.5}, - { "pentium2_klamath", 266666666, 4.0}, - { "pentium2_klamath", 300000000, 4.5}, - { "pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumII[] = { - {"pentium2_klamath", 50000000, 1.0}, - { "pentium2_klamath", 60000000, 1.0}, - { "pentium2_klamath", 66666666, 1.0}, - { "pentium2_klamath", 75000000, 1.5}, - { "pentium2_klamath", 233333333, 3.5}, - { "pentium2_klamath", 266666666, 4.0}, - { "pentium2_klamath", 300000000, 4.5}, - { "pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { "pentium2_deschutes", 350000000, 3.5}, - { "pentium2_deschutes", 400000000, 4.0}, - { "pentium2_deschutes", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Xeon[] = { - {"pentium2_xeon", 75000000, 1.5}, - { "pentium2_xeon", 100000000, 1.5}, - { "pentium2_xeon", 133333333, 2.0}, - { "pentium2_xeon", 166666666, 2.5}, - { "pentium2_xeon", 400000000, 4.0}, - { "pentium2_xeon", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Celeron[] = { - {"celeron_mendocino", 66666666, 1.0}, - { "celeron_mendocino", 100000000, 1.5}, - { "celeron_mendocino", 133333333, 2.0}, - { "celeron_mendocino", 166666666, 2.5}, - { "celeron_mendocino", 300000000, 4.5}, - { "celeron_mendocino", 333333333, 5.0}, - { "celeron_mendocino", 366666666, 5.5}, - { "celeron_mendocino", 400000000, 6.0}, - { "celeron_mendocino", 433333333, 6.5}, - { "celeron_mendocino", 466666666, 7.0}, - { "celeron_mendocino", 500000000, 7.5}, - { "celeron_mendocino", 533333333, 8.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_PentiumIID[] = { - {"pentium2_deschutes", 50000000, 1.0}, - { "pentium2_deschutes", 60000000, 1.0}, - { "pentium2_deschutes", 66666666, 1.0}, - { "pentium2_deschutes", 75000000, 1.5}, - { "pentium2_deschutes", 266666666, 4.0}, - { "pentium2_deschutes", 300000000, 4.5}, - { "pentium2_deschutes", 333333333, 5.0}, - { "pentium2_deschutes", 350000000, 3.5}, - { "pentium2_deschutes", 400000000, 4.0}, - { "pentium2_deschutes", 450000000, 4.5}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t cpus_Cyrix3[] = { - {"c3_samuel", 66666666, 1.0}, - { "c3_samuel", 233333333, 3.5}, - { "c3_samuel", 266666666, 4.0}, - { "c3_samuel", 300000000, 4.5}, - { "c3_samuel", 333333333, 5.0}, - { "c3_samuel", 350000000, 3.5}, - { "c3_samuel", 400000000, 4.0}, - { "c3_samuel", 450000000, 4.5}, - { "c3_samuel", 500000000, 5.0}, - { "c3_samuel", 550000000, 5.5}, - { "c3_samuel", 600000000, 6.0}, - { "c3_samuel", 650000000, 6.5}, - { "c3_samuel", 700000000, 7.0}, - { NULL, 0, 0 } -}; - -static const cpu_legacy_table_t *cputables_8088[4] = { cpus_8088 }; -static const cpu_legacy_table_t *cputables_pcjr[4] = { cpus_pcjr }; -static const cpu_legacy_table_t *cputables_europc[4] = { cpus_europc }; -static const cpu_legacy_table_t *cputables_pc1512[4] = { cpus_pc1512 }; -static const cpu_legacy_table_t *cputables_8086[4] = { cpus_8086 }; -static const cpu_legacy_table_t *cputables_286[4] = { cpus_286 }; -static const cpu_legacy_table_t *cputables_ibmat[4] = { cpus_ibmat }; -static const cpu_legacy_table_t *cputables_ps1_m2011[4] = { cpus_ps1_m2011 }; -static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = { cpus_ps2_m30_286, cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_ibmxt286[4] = { cpus_ibmxt286 }; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC }; -static const cpu_legacy_table_t *cputables_ALiM6117[4] = { cpus_ALiM6117 }; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC }; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL }; -static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = { cpus_i486, cpus_Am486, cpus_Cx486 }; -static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = { cpus_i486S1, cpus_Am486S1, cpus_Cx486S1 }; -static const cpu_legacy_table_t *cputables_IBM486SLC[4] = { cpus_IBM486SLC }; -static const cpu_legacy_table_t *cputables_i486_PC330[4] = { cpus_i486_PC330 }; -static const cpu_legacy_table_t *cputables_STPCDX[4] = { cpus_STPCDX }; -static const cpu_legacy_table_t *cputables_STPCDX2[4] = { cpus_STPCDX2 }; -static const cpu_legacy_table_t *cputables_Pentium5V[4] = { cpus_Pentium5V }; -static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = { cpus_PentiumS5, cpus_WinChip, cpus_K5 }; -static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = { cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V }; -static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = { cpus_Pentium3V, cpus_K5 }; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = { cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86 }; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = { cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7 }; -static const cpu_legacy_table_t *cputables_PentiumPro[4] = { cpus_PentiumPro }; -static const cpu_legacy_table_t *cputables_PentiumII66[4] = { cpus_PentiumII66 }; -static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = { cpus_PentiumII, cpus_Celeron, cpus_Cyrix3 }; -static const cpu_legacy_table_t *cputables_Xeon[4] = { cpus_Xeon }; -static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = { cpus_Celeron, cpus_Cyrix3 }; -static const cpu_legacy_table_t *cputables_Celeron[4] = { cpus_Celeron }; -static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = { cpus_PentiumIID, cpus_Celeron }; - -const cpu_legacy_machine_t cpu_legacy_table[] = { - {"ibmpc", cputables_8088 }, - { "ibmpc82", cputables_8088 }, - { "ibmpcjr", cputables_pcjr }, - { "ibmxt", cputables_8088 }, - { "ibmxt86", cputables_8088 }, - { "americxt", cputables_8088 }, - { "amixt", cputables_8088 }, - { "portable", cputables_8088 }, - { "dtk", cputables_8088 }, - { "genxt", cputables_8088 }, - { "jukopc", cputables_8088 }, - { "openxt", cputables_8088 }, - { "pxxt", cputables_8088 }, - { "europc", cputables_europc }, - { "tandy", cputables_europc }, - { "tandy1000hx", cputables_europc }, - { "t1000", cputables_8088 }, - { "ltxt", cputables_8088 }, - { "xi8088", cputables_8088 }, - { "zdsupers", cputables_8088 }, - { "pc1512", cputables_pc1512 }, - { "pc1640", cputables_8086 }, - { "pc2086", cputables_8086 }, - { "pc3086", cputables_8086 }, - { "pc200", cputables_8086 }, - { "ppc512", cputables_8086 }, - { "deskpro", cputables_8086 }, - { "m24", cputables_8086 }, - { "iskra3104", cputables_8086 }, - { "tandy1000sl2", cputables_8086 }, - { "t1200", cputables_8086 }, - { "lxt3", cputables_8086 }, - { "hed919", cputables_286 }, - { "ibmat", cputables_ibmat }, - { "ibmps1es", cputables_ps1_m2011 }, - { "ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC }, - { "ibmxt286", cputables_ibmxt286 }, - { "ibmatami", cputables_ibmat }, - { "cmdpc30", cputables_286 }, - { "portableii", cputables_286 }, - { "portableiii", cputables_286 }, - { "mr286", cputables_286 }, - { "open_at", cputables_286 }, - { "ibmatpx", cputables_ibmat }, - { "ibmatquadtel", cputables_ibmat }, - { "siemens", cputables_286 }, - { "t3100e", cputables_286 }, - { "quadt286", cputables_286 }, - { "tg286m", cputables_286 }, - { "ami286", cputables_286 }, - { "px286", cputables_286 }, - { "award286", cputables_286 }, - { "gw286ct", cputables_286 }, - { "gdc212m", cputables_286 }, - { "super286tr", cputables_286 }, - { "spc4200p", cputables_286 }, - { "spc4216p", cputables_286 }, - { "deskmaster286", cputables_286 }, - { "ibmps2_m50", cputables_ps2_m30_286_IBM486SLC }, - { "ibmps1_2121", cputables_i386SX_Am386SX_486SLC }, - { "ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC }, - { "arb1375", cputables_ALiM6117 }, - { "pja511m", cputables_ALiM6117 }, - { "ama932j", cputables_i386SX_Am386SX_486SLC }, - { "adi386sx", cputables_i386SX_Am386SX_486SLC }, - { "shuttle386sx", cputables_i386SX_Am386SX_486SLC }, - { "dtk386", cputables_i386SX_Am386SX_486SLC }, - { "awardsx", cputables_i386SX_Am386SX_486SLC }, - { "cmdsl386sx25", cputables_i386SX_Am386SX_486SLC }, - { "kmxc02", cputables_i386SX_Am386SX_486SLC }, - { "megapc", cputables_i386SX_Am386SX_486SLC }, - { "ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC }, - { "acc386", cputables_i386DX_Am386DX_486DLC }, - { "ecs386", cputables_i386DX_Am386DX_486DLC }, - { "portableiii386", cputables_i386DX_Am386DX_486DLC }, - { "micronics386", cputables_i386DX_Am386DX_486DLC }, - { "asus386", cputables_i386DX_Am386DX_486DLC }, - { "ustechnologies386", cputables_i386DX_Am386DX_486DLC }, - { "award386dx", cputables_i386DX_Am386DX_486DLC }, - { "ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL }, - { "ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL }, - { "pb410a", cputables_i486_Am486_Cx486 }, - { "acera1g", cputables_i486_Am486_Cx486 }, - { "win486", cputables_i486_Am486_Cx486 }, - { "ali1429", cputables_i486S1_Am486S1_Cx486S1 }, - { "cs4031", cputables_i486S1_Am486S1_Cx486S1 }, - { "rycleopardlx", cputables_IBM486SLC }, - { "award486", cputables_i486S1_Am486S1_Cx486S1 }, - { "ami486", cputables_i486S1_Am486S1_Cx486S1 }, - { "mr486", cputables_i486_Am486_Cx486 }, - { "pc330_6571", cputables_i486_PC330 }, - { "403tg", cputables_i486_Am486_Cx486 }, - { "sis401", cputables_i486_Am486_Cx486 }, - { "valuepoint433", cputables_i486_Am486_Cx486 }, - { "ami471", cputables_i486_Am486_Cx486 }, - { "win471", cputables_i486_Am486_Cx486 }, - { "vi15g", cputables_i486_Am486_Cx486 }, - { "vli486sv2g", cputables_i486_Am486_Cx486 }, - { "dtk486", cputables_i486_Am486_Cx486 }, - { "px471", cputables_i486_Am486_Cx486 }, - { "486vchd", cputables_i486S1_Am486S1_Cx486S1 }, - { "ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1 }, - { "vect486vl", cputables_i486S1_Am486S1_Cx486S1 }, - { "ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1 }, - { "abpb4", cputables_i486_Am486_Cx486 }, - { "486ap4", cputables_i486_Am486_Cx486 }, - { "486sp3g", cputables_i486_Am486_Cx486 }, - { "alfredo", cputables_i486_Am486_Cx486 }, - { "ls486e", cputables_i486_Am486_Cx486 }, - { "m4li", cputables_i486_Am486_Cx486 }, - { "r418", cputables_i486_Am486_Cx486 }, - { "4sa2", cputables_i486_Am486_Cx486 }, - { "4dps", cputables_i486_Am486_Cx486 }, - { "itoxstar", cputables_STPCDX }, - { "arb1479", cputables_STPCDX2 }, - { "pcm9340", cputables_STPCDX2 }, - { "pcm5330", cputables_STPCDX2 }, - { "486vipio2", cputables_i486_Am486_Cx486 }, - { "p5mp3", cputables_Pentium5V }, - { "dellxp60", cputables_Pentium5V }, - { "opti560l", cputables_Pentium5V }, - { "ambradp60", cputables_Pentium5V }, - { "valuepointp60", cputables_Pentium5V }, - { "revenge", cputables_Pentium5V }, - { "586mc1", cputables_Pentium5V }, - { "pb520r", cputables_Pentium5V }, - { "excalibur", cputables_Pentium5V }, - { "plato", cputables_PentiumS5_WinChip_K5 }, - { "ambradp90", cputables_PentiumS5_WinChip_K5 }, - { "430nx", cputables_PentiumS5_WinChip_K5 }, - { "acerv30", cputables_PentiumS5_WinChip_K5 }, - { "apollo", cputables_PentiumS5_WinChip_K5 }, - { "vectra54", cputables_PentiumS5_WinChip_K5 }, - { "zappa", cputables_PentiumS5_WinChip_K5 }, - { "powermate_v", cputables_PentiumS5_WinChip_K5 }, - { "mb500n", cputables_PentiumS5_WinChip_K5 }, - { "p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V }, - { "mr586", cputables_Pentium3V_WinChip_K5_6x863V }, - { "gw2katx", cputables_Pentium3V_WinChip_K5_6x863V }, - { "thor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "mrthor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "endeavor", cputables_Pentium3V_WinChip_K5_6x863V }, - { "pb640", cputables_Pentium3V_WinChip_K5_6x863V }, - { "chariot", cputables_Pentium3V_K5 }, - { "acerm3a", cputables_Pentium3V_WinChip_K5_6x863V }, - { "ap53", cputables_Pentium3V_WinChip_K5_6x863V }, - { "8500tuc", cputables_Pentium3V_WinChip_K5_6x863V }, - { "p55t2s", cputables_Pentium3V_WinChip_K5_6x863V }, - { "acerv35n", cputables_Pentium_WinChip_K56_6x86 }, - { "p55t2p4", cputables_Pentium_WinChip_K56_6x86 }, - { "m7shi", cputables_Pentium_WinChip_K56_6x86 }, - { "tc430hx", cputables_Pentium_WinChip_K56_6x86 }, - { "equium5200", cputables_Pentium_WinChip_K56_6x86 }, - { "pcv240", cputables_Pentium_WinChip_K56_6x86 }, - { "p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86 }, - { "p55tvp4", cputables_Pentium_WinChip_K56_6x86 }, - { "8500tvxa", cputables_Pentium_WinChip_K56_6x86 }, - { "presario4500", cputables_Pentium_WinChip_K56_6x86 }, - { "p55va", cputables_Pentium_WinChip_K56_6x86 }, - { "gw2kte", cputables_Pentium_WinChip_K56_6x86 }, - { "brio80xx", cputables_Pentium_WinChip_K56_6x86 }, - { "pb680", cputables_Pentium_WinChip_K56_6x86 }, - { "430vx", cputables_Pentium_WinChip_K56_6x86 }, - { "nupro592", cputables_Pentium_WinChip_K56_6x86 }, - { "tx97", cputables_Pentium_WinChip_K56_6x86 }, - { "an430tx", cputables_Pentium_WinChip_K56_6x86 }, - { "ym430tx", cputables_Pentium_WinChip_K56_6x86 }, - { "mb540n", cputables_Pentium_WinChip_K56_6x86 }, - { "p5mms98", cputables_Pentium_WinChip_K56_6x86 }, - { "ficva502", cputables_Pentium_WinChip_K56_6x86 }, - { "ficpa2012", cputables_Pentium_WinChip_K56_6x86 }, - { "ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - { "v60n", cputables_PentiumPro }, - { "p65up5_cp6nd", cputables_PentiumPro }, - { "8600ttc", cputables_PentiumPro }, - { "686nx", cputables_PentiumPro }, - { "ap440fx", cputables_PentiumPro }, - { "vs440fx", cputables_PentiumPro }, - { "m6mi", cputables_PentiumPro }, - { "mb600n", cputables_PentiumPro }, - { "p65up5_cpknd", cputables_PentiumII66 }, - { "kn97", cputables_PentiumII66 }, - { "lx6", cputables_PentiumII66 }, - { "spitfire", cputables_PentiumII66 }, - { "p6i440e2", cputables_PentiumII66 }, - { "p2bls", cputables_PentiumII_Celeron_Cyrix3 }, - { "p3bf", cputables_PentiumII_Celeron_Cyrix3 }, - { "bf6", cputables_PentiumII_Celeron_Cyrix3 }, - { "ax6bc", cputables_PentiumII_Celeron_Cyrix3 }, - { "atc6310bxii", cputables_PentiumII_Celeron_Cyrix3 }, - { "686bx", cputables_PentiumII_Celeron_Cyrix3 }, - { "tsunamiatx", cputables_PentiumII_Celeron_Cyrix3 }, - { "p6sba", cputables_PentiumII_Celeron_Cyrix3 }, - { "ergox365", cputables_PentiumII_Celeron_Cyrix3 }, - { "ficka6130", cputables_PentiumII_Celeron_Cyrix3 }, - { "6gxu", cputables_Xeon }, - { "fw6400gx", cputables_Xeon }, - { "s2dge", cputables_Xeon }, - { "s370slm", cputables_Celeron_Cyrix3 }, - { "awo671r", cputables_Celeron_Cyrix3 }, - { "cubx", cputables_Celeron_Cyrix3 }, - { "atc7020bxii", cputables_Celeron_Cyrix3 }, - { "ambx133", cputables_Celeron_Cyrix3 }, - { "trinity371", cputables_Celeron }, - { "63a", cputables_Celeron_Cyrix3 }, - { "apas3", cputables_Celeron_Cyrix3 }, - { "wcf681", cputables_Celeron_Cyrix3 }, - { "6via90ap", cputables_Celeron_Cyrix3 }, - { "p6bap", cputables_Celeron_Cyrix3 }, - { "603tcf", cputables_Celeron_Cyrix3 }, - { "vpc2007", cputables_PentiumIID_Celeron }, - { NULL, NULL } -}; diff --git a/src/cpu/softfloat/config.h b/src/cpu/softfloat/config.h index 3889b5c021..9e39c2d29c 100644 --- a/src/cpu/softfloat/config.h +++ b/src/cpu/softfloat/config.h @@ -1,3 +1,6 @@ +#ifndef EMU_SF_CONFIG_H +#define EMU_SF_CONFIG_H + #include typedef int8_t flag; @@ -44,3 +47,5 @@ typedef int64_t Bit64s; *----------------------------------------------------------------------------*/ #define BX_CONST64(a) a##LL #define BX_CPP_INLINE static __inline + +#endif /*EMU_SF_CONFIG_H*/ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 76101c344f..cf2867182a 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -25,6 +25,8 @@ #include <86box/86box.h> #include "cpu.h" #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include <86box/machine.h> #include <86box/device.h> #include <86box/dma.h> @@ -59,10 +61,12 @@ uint32_t rmdat; uint64_t xt_cpu_multi; /* Variables for handling the non-maskable interrupts. */ -int nmi = 0, nmi_auto_clear = 0; +int nmi = 0; +int nmi_auto_clear = 0; /* Was the CPU ever reset? */ -int x86_was_reset = 0, soft_reset_pci = 0; +int x86_was_reset = 0; +int soft_reset_pci = 0; /* Is the TRAP flag on? */ int trap = 0; @@ -71,7 +75,12 @@ int trap = 0; uint32_t easeg; /* This is for the OPTI 283 special reset handling mode. */ -int reset_on_hlt, hlt_reset_pending; +int reset_on_hlt; +int hlt_reset_pending; + +int fpu_cycles = 0; + +int in_lock = 0; #ifdef ENABLE_X86_LOG void dumpregs(int); @@ -80,7 +89,7 @@ int x86_do_log = ENABLE_X86_LOG; int indump = 0; static void -x808x_log(const char *fmt, ...) +x86_log(const char *fmt, ...) { va_list ap; @@ -101,40 +110,42 @@ dumpregs(int force) if (indump || (!force && !dump_on_exit)) return; - x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); - x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); + x86_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", + cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + x85_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); + x86_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_names[c], _opseg[c]->base, _opseg[c]->limit, + _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); } if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); + x86_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high); + x86_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high); + x86_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + x86_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + x86_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + x86_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + x86_log("386 in %s mode: %i-bit data, %-i-bit stack\n", + (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", + (use32) ? 32 : 16, (stack32) ? 32 : 16); + x86_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + x86_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", + EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); + x86_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); + x86_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", + AX, BX, CX, DX, DI, SI, BP, SP); } - x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); + x86_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); x87_dumpregs(); indump = 0; } #else -# define x808x_log(fmt, ...) +# define x86_log(fmt, ...) #endif /* Preparation of the various arrays needed to speed up the MOD and R/M work. */ @@ -171,7 +182,10 @@ makemod1table(void) static void makeznptable(void) { - int c, d, e; + int c; + int d; + int e; + for (c = 0; c < 256; c++) { d = 0; for (e = 0; e < 8; e++) { @@ -182,9 +196,9 @@ makeznptable(void) znptable8[c] = 0; else znptable8[c] = P_FLAG; -#ifdef ENABLE_808X_LOG +#ifdef ENABLE_X86_LOG if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); + x86_log("znp8 b1 = %i %02X\n", d, znptable8[c]); #endif if (!c) znptable8[c] |= Z_FLAG; @@ -202,11 +216,11 @@ makeznptable(void) znptable16[c] = 0; else znptable16[c] = P_FLAG; -#ifdef ENABLE_808X_LOG +#ifdef ENABLE_X86_LOG if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); + x86_log("znp16 b1 = %i %02X\n", d, znptable16[c]); if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); + x86_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); #endif if (!c) znptable16[c] |= Z_FLAG; @@ -219,9 +233,9 @@ makeznptable(void) static void reset_common(int hard) { -#ifdef ENABLE_808X_LOG +#ifdef ENABLE_X86_LOG if (hard) - x808x_log("x86 reset\n"); + x86_log("x86 reset\n"); #endif if (!hard && reset_on_hlt) { @@ -258,16 +272,27 @@ reset_common(int hard) cr0 = 1 << 30; else cr0 = 0; + if (is386 && !is486 && (fpu_type == FPU_387)) + cr0 |= 0x10; cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; cpu_state.eflags = 0; cgate32 = 0; + if (is386 && !is486) { + for (uint8_t i = 0; i < 4; i++) + dr[i] = 0x00000000; + dr[6] = 0xffff1ff0; + dr[7] = 0x00000400; + } if (is286) { - loadcs(0xF000); + if (is486) + loadcs(0xF000); + else + loadcs_2386(0xF000); cpu_state.pc = 0xFFF0; if (hard) { - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; if (is6117) rammask |= 0x03000000; mem_a20_key = mem_a20_alt = mem_a20_state = 0; @@ -327,6 +352,10 @@ reset_common(int hard) if (!is286) reset_808x(hard); + + in_lock = 0; + + cpu_cpurst_on_sr = 0; } /* Hard reset. */ @@ -345,7 +374,7 @@ softresetx86(void) if (soft_reset_mask) return; - if (ibm8514_enabled || xga_enabled) + if (ibm8514_active || xga_active) vga_on = 1; reset_common(0); diff --git a/src/cpu/x86.h b/src/cpu/x86.h index 337619fa47..f52e430ac6 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -1,3 +1,26 @@ +/* + * 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. + * + * Second CPU header. + * + * + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2018 leilei. + * Copyright 2016-2020 Miran Grca. + */ +#ifndef EMU_X86_H +#define EMU_X86_H + #define ABRT_MASK 0x3f /*An 'expected' exception is one that would be expected to occur on every execution of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is @@ -9,30 +32,45 @@ that we don't end up with an unnecessarily short block*/ #define ABRT_EXPECTED 0x80 -extern uint8_t opcode, opcode2; +extern uint8_t opcode; + extern uint8_t flags_p; extern uint8_t znptable8[256]; -extern uint16_t zero, oldcs; -extern uint16_t lastcs, lastpc; +extern uint16_t zero; +extern uint16_t oldcs; +extern uint16_t lastcs; +extern uint16_t lastpc; extern uint16_t *mod1add[2][8]; extern uint16_t znptable16[65536]; -extern int x86_was_reset, trap; -extern int codegen_flat_ss, codegen_flat_ds; -extern int timetolive, keyboardtimer, trap; -extern int optype, stack32; -extern int oldcpl, cgate32, cpl_override; +extern int x86_was_reset; +extern int trap; +extern int codegen_flat_ss; +extern int codegen_flat_ds; +extern int timetolive; +extern int keyboardtimer; +extern int trap; +extern int optype; +extern int stack32; +extern int oldcpl; +extern int cpl_override; extern int nmi_enable; -extern int oddeven, inttype; +extern int oddeven; +extern int inttype; extern uint32_t use32; -extern uint32_t rmdat, easeg; -extern uint32_t oxpc, flags_zn; +extern uint32_t rmdat; +extern uint32_t easeg; +extern uint32_t oxpc; +extern uint32_t flags_zn; extern uint32_t abrt_error; extern uint32_t backupregs[16]; extern uint32_t *mod1seg[8]; -extern uint32_t *eal_r, *eal_w; +extern uint32_t *eal_r; +extern uint32_t *eal_w; + +extern int fpu_cycles; #define fetchdat rmdat @@ -61,24 +99,6 @@ extern uint32_t *eal_r, *eal_w; fetcheal(); \ } -#define JMP 1 -#define CALL 2 -#define IRET 3 -#define OPTYPE_INT 4 - -enum { - ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE, - ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ -}; - -extern void x86_doabrt(int x86_abrt); extern void x86illegal(void); -extern void x86seg_reset(void); -extern void x86gpf(char *s, uint16_t error); -extern void x86gpf_expected(char *s, uint16_t error); + +#endif /*EMU_X86_H*/ diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 0cd4492361..6fb9b7a221 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -44,9 +44,9 @@ typedef int (*OpFn)(uint32_t fetchdat); #ifdef USE_DYNAREC -void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, - const OpFn *dynarec_opcodes_0f); +extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, + const OpFn *dynarec_opcodes, + const OpFn *dynarec_opcodes_0f); extern const OpFn *x86_dynarec_opcodes; extern const OpFn *x86_dynarec_opcodes_0f; @@ -187,10 +187,9 @@ extern const OpFn dynarec_ops_REPNE[1024]; extern const OpFn dynarec_ops_3DNOW[256]; extern const OpFn dynarec_ops_3DNOWE[256]; #else -void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); +extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); #endif - extern const OpFn *x86_opcodes; extern const OpFn *x86_opcodes_0f; extern const OpFn *x86_opcodes_d8_a16; @@ -330,6 +329,111 @@ extern const OpFn ops_REPNE[1024]; extern const OpFn ops_3DNOW[256]; extern const OpFn ops_3DNOWE[256]; +extern void x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f); + +extern const OpFn *x86_2386_opcodes; +extern const OpFn *x86_2386_opcodes_0f; +extern const OpFn *x86_2386_opcodes_d8_a16; +extern const OpFn *x86_2386_opcodes_d8_a32; +extern const OpFn *x86_2386_opcodes_d9_a16; +extern const OpFn *x86_2386_opcodes_d9_a32; +extern const OpFn *x86_2386_opcodes_da_a16; +extern const OpFn *x86_2386_opcodes_da_a32; +extern const OpFn *x86_2386_opcodes_db_a16; +extern const OpFn *x86_2386_opcodes_db_a32; +extern const OpFn *x86_2386_opcodes_dc_a16; +extern const OpFn *x86_2386_opcodes_dc_a32; +extern const OpFn *x86_2386_opcodes_dd_a16; +extern const OpFn *x86_2386_opcodes_dd_a32; +extern const OpFn *x86_2386_opcodes_de_a16; +extern const OpFn *x86_2386_opcodes_de_a32; +extern const OpFn *x86_2386_opcodes_df_a16; +extern const OpFn *x86_2386_opcodes_df_a32; +extern const OpFn *x86_2386_opcodes_REPE; +extern const OpFn *x86_2386_opcodes_REPNE; + +extern const OpFn ops_2386_186[1024]; +extern const OpFn ops_2386_186_0f[1024]; + +extern const OpFn ops_2386_286[1024]; +extern const OpFn ops_2386_286_0f[1024]; + +extern const OpFn ops_2386_386[1024]; +extern const OpFn ops_2386_386_0f[1024]; + +extern const OpFn ops_2386_486_0f[1024]; +extern const OpFn ops_2386_ibm486_0f[1024]; + +extern const OpFn ops_2386_sf_fpu_287_d9_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_d9_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_da_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_da_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_db_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_db_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_dc_a16[32]; +extern const OpFn ops_2386_sf_fpu_287_dc_a32[32]; +extern const OpFn ops_2386_sf_fpu_287_dd_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_dd_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_de_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_de_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_df_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_df_a32[256]; + +extern const OpFn ops_2386_sf_fpu_d8_a16[32]; +extern const OpFn ops_2386_sf_fpu_d8_a32[32]; +extern const OpFn ops_2386_sf_fpu_d9_a16[256]; +extern const OpFn ops_2386_sf_fpu_d9_a32[256]; +extern const OpFn ops_2386_sf_fpu_da_a16[256]; +extern const OpFn ops_2386_sf_fpu_da_a32[256]; +extern const OpFn ops_2386_sf_fpu_db_a16[256]; +extern const OpFn ops_2386_sf_fpu_db_a32[256]; +extern const OpFn ops_2386_sf_fpu_dc_a16[32]; +extern const OpFn ops_2386_sf_fpu_dc_a32[32]; +extern const OpFn ops_2386_sf_fpu_dd_a16[256]; +extern const OpFn ops_2386_sf_fpu_dd_a32[256]; +extern const OpFn ops_2386_sf_fpu_de_a16[256]; +extern const OpFn ops_2386_sf_fpu_de_a32[256]; +extern const OpFn ops_2386_sf_fpu_df_a16[256]; +extern const OpFn ops_2386_sf_fpu_df_a32[256]; + +extern const OpFn ops_2386_fpu_287_d9_a16[256]; +extern const OpFn ops_2386_fpu_287_d9_a32[256]; +extern const OpFn ops_2386_fpu_287_da_a16[256]; +extern const OpFn ops_2386_fpu_287_da_a32[256]; +extern const OpFn ops_2386_fpu_287_db_a16[256]; +extern const OpFn ops_2386_fpu_287_db_a32[256]; +extern const OpFn ops_2386_fpu_287_dc_a16[32]; +extern const OpFn ops_2386_fpu_287_dc_a32[32]; +extern const OpFn ops_2386_fpu_287_dd_a16[256]; +extern const OpFn ops_2386_fpu_287_dd_a32[256]; +extern const OpFn ops_2386_fpu_287_de_a16[256]; +extern const OpFn ops_2386_fpu_287_de_a32[256]; +extern const OpFn ops_2386_fpu_287_df_a16[256]; +extern const OpFn ops_2386_fpu_287_df_a32[256]; + +extern const OpFn ops_2386_fpu_d8_a16[32]; +extern const OpFn ops_2386_fpu_d8_a32[32]; +extern const OpFn ops_2386_fpu_d9_a16[256]; +extern const OpFn ops_2386_fpu_d9_a32[256]; +extern const OpFn ops_2386_fpu_da_a16[256]; +extern const OpFn ops_2386_fpu_da_a32[256]; +extern const OpFn ops_2386_fpu_db_a16[256]; +extern const OpFn ops_2386_fpu_db_a32[256]; +extern const OpFn ops_2386_fpu_dc_a16[32]; +extern const OpFn ops_2386_fpu_dc_a32[32]; +extern const OpFn ops_2386_fpu_dd_a16[256]; +extern const OpFn ops_2386_fpu_dd_a32[256]; +extern const OpFn ops_2386_fpu_de_a16[256]; +extern const OpFn ops_2386_fpu_de_a32[256]; +extern const OpFn ops_2386_fpu_df_a16[256]; +extern const OpFn ops_2386_fpu_df_a32[256]; +extern const OpFn ops_2386_nofpu_a16[256]; +extern const OpFn ops_2386_nofpu_a32[256]; + +extern const OpFn ops_2386_REPE[1024]; +extern const OpFn ops_2386_REPNE[1024]; +extern const OpFn ops_2386_3DNOW[256]; + #define C0 (1 << 8) #define C1 (1 << 9) #define C2 (1 << 10) diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index eb7a35ace0..b72cbc06c4 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -35,201 +35,246 @@ opFEMMS(uint32_t fetchdat) static int opPAVGUSB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + dst->b[0] = (dst->b[0] + src.b[0] + 1) >> 1; + dst->b[1] = (dst->b[1] + src.b[1] + 1) >> 1; + dst->b[2] = (dst->b[2] + src.b[2] + 1) >> 1; + dst->b[3] = (dst->b[3] + src.b[3] + 1) >> 1; + dst->b[4] = (dst->b[4] + src.b[4] + 1) >> 1; + dst->b[5] = (dst->b[5] + src.b[5] + 1) >> 1; + dst->b[6] = (dst->b[6] + src.b[6] + 1) >> 1; + dst->b[7] = (dst->b[7] + src.b[7] + 1) >> 1; + + MMX_SETEXP(cpu_reg); return 0; } static int opPF2ID(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1]; + dst->sl[0] = (int32_t) src.f[0]; + dst->sl[1] = (int32_t) src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPF2IW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0]; - cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1]; + dst->sw[0] = (int32_t) src.f[0]; + dst->sw[1] = (int32_t) src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFACC(uint32_t fetchdat) { - MMX_REG src; - float tempf; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] + dst->f[1]; + dst->f[1] = src.f[0] + src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFNACC(uint32_t fetchdat) { - MMX_REG src; - float tempf; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] - dst->f[1]; + dst->f[1] = src.f[0] - src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFPNACC(uint32_t fetchdat) { - MMX_REG src; - float tempf; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] - dst->f[1]; + dst->f[1] = src.f[0] + src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSWAPD(uint32_t fetchdat) { - MMX_REG src; - float tempf, tempf2; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + float tempf; + float tempf2; MMX_GETSRC(); /* We have to do this in case source and destination overlap. */ - tempf = src.f[0]; - tempf2 = src.f[1]; - cpu_state.MM[cpu_reg].f[1] = tempf; - cpu_state.MM[cpu_reg].f[0] = tempf2; + tempf = src.f[0]; + tempf2 = src.f[1]; + dst->f[1] = tempf; + dst->f[0] = tempf2; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFADD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; + dst->f[0] += src.f[0]; + dst->f[1] += src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFCMPEQ(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] == src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] == src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFCMPGE(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] >= src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] >= src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFCMPGT(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] > src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] > src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFMAX(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] > dst->f[0]) + dst->f[0] = src.f[0]; + if (src.f[1] > dst->f[1]) + dst->f[1] = src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFMIN(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] < dst->f[0]) + dst->f[0] = src.f[0]; + if (src.f[1] < dst->f[1]) + dst->f[1] = src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFMUL(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + dst->f[0] *= src.f[0]; + dst->f[1] *= src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFRCP(uint32_t fetchdat) { + MMX_REG *dst = MMX_GETREGP(cpu_reg); + union { uint32_t i; float f; } src; if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; + src.f = (MMX_GETREG(cpu_rm)).f[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_READ(cpu_state.ea_seg); @@ -239,8 +284,10 @@ opPFRCP(uint32_t fetchdat) CLOCK_CYCLES(2); } - cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + dst->f[0] = 1.0 / src.f; + dst->f[1] = dst->f[0]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -248,37 +295,45 @@ opPFRCP(uint32_t fetchdat) static int opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + dst->f[0] = src.f[0]; + dst->f[1] = src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + dst->f[0] = src.f[0]; + dst->f[1] = src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFRSQRT(uint32_t fetchdat) { + MMX_REG *dst = MMX_GETREGP(cpu_reg); + union { uint32_t i; float f; } src; if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; + src.f = (MMX_GETREG(cpu_rm)).f[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_READ(cpu_state.ea_seg); @@ -288,8 +343,10 @@ opPFRSQRT(uint32_t fetchdat) CLOCK_CYCLES(2); } - cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + dst->f[0] = 1.0 / sqrt(src.f); + dst->f[1] = dst->f[0]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -307,74 +364,92 @@ opPFRSQIT1(uint32_t fetchdat) static int opPFSUB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + dst->f[0] -= src.f[0]; + dst->f[1] -= src.f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPFSUBR(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + dst->f[0] = src.f[0] - dst->f[0]; + dst->f[1] = src.f[1] - dst->f[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPI2FD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1]; + dst->f[0] = (float) src.sl[0]; + dst->f[1] = (float) src.sl[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPI2FW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0]; - cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1]; + dst->f[0] = (float) src.sw[0]; + dst->f[1] = (float) src.sw[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPMULHRW(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + src = MMX_GETREG(cpu_rm); + + dst->w[0] = (((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + dst->w[1] = (((int32_t) dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + dst->w[2] = (((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + dst->w[3] = (((int32_t) dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; CLOCK_CYCLES(1); } else { - MMX_REG src; - SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; + dst->w[0] = ((int32_t) (dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + dst->w[1] = ((int32_t) (dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + dst->w[2] = ((int32_t) (dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + dst->w[3] = ((int32_t) (dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 41c655d096..4e3f74e364 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -340,6 +340,7 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) { uint8_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -359,6 +360,7 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) { uint8_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -379,6 +381,7 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) { uint16_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -398,6 +401,7 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) { uint16_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -418,6 +422,7 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) { uint32_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -437,6 +442,7 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) { uint32_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -457,6 +463,7 @@ static int opCMP_b_rm_a16(uint32_t fetchdat) { uint8_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -472,6 +479,7 @@ static int opCMP_b_rm_a32(uint32_t fetchdat) { uint8_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -488,6 +496,7 @@ static int opCMP_w_rm_a16(uint32_t fetchdat) { uint16_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -503,6 +512,7 @@ static int opCMP_w_rm_a32(uint32_t fetchdat) { uint16_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -519,6 +529,7 @@ static int opCMP_l_rm_a16(uint32_t fetchdat) { uint32_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -534,6 +545,7 @@ static int opCMP_l_rm_a32(uint32_t fetchdat) { uint32_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -550,6 +562,7 @@ static int opCMP_AL_imm(uint32_t fetchdat) { uint8_t src = getbytef(); + setsub8(AL, src); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); @@ -560,6 +573,7 @@ static int opCMP_AX_imm(uint32_t fetchdat) { uint16_t src = getwordf(); + setsub16(AX, src); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); @@ -570,6 +584,7 @@ static int opCMP_EAX_imm(uint32_t fetchdat) { uint32_t src = getlong(); + if (cpu_state.abrt) return 1; setsub32(EAX, src); @@ -581,7 +596,9 @@ opCMP_EAX_imm(uint32_t fetchdat) static int opTEST_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2; + uint8_t temp; + uint8_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -601,7 +618,9 @@ opTEST_b_a16(uint32_t fetchdat) static int opTEST_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2; + uint8_t temp; + uint8_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -622,7 +641,9 @@ opTEST_b_a32(uint32_t fetchdat) static int opTEST_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2; + uint16_t temp; + uint16_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -642,7 +663,9 @@ opTEST_w_a16(uint32_t fetchdat) static int opTEST_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2; + uint16_t temp; + uint16_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -663,7 +686,9 @@ opTEST_w_a32(uint32_t fetchdat) static int opTEST_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2; + uint32_t temp; + uint32_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -683,7 +708,9 @@ opTEST_l_a16(uint32_t fetchdat) static int opTEST_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2; + uint32_t temp; + uint32_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -803,7 +830,8 @@ opTEST_EAX(uint32_t fetchdat) static int op80_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -823,7 +851,8 @@ op80_a16(uint32_t fetchdat) static int op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -843,7 +872,8 @@ op80_a32(uint32_t fetchdat) static int op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -863,7 +893,8 @@ op81_w_a16(uint32_t fetchdat) static int op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -883,7 +914,8 @@ op81_w_a32(uint32_t fetchdat) static int op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -903,7 +935,8 @@ op81_l_a16(uint32_t fetchdat) static int op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -924,7 +957,8 @@ op81_l_a32(uint32_t fetchdat) static int op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -946,7 +980,8 @@ op83_w_a16(uint32_t fetchdat) static int op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -969,7 +1004,8 @@ op83_w_a32(uint32_t fetchdat) static int op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -991,7 +1027,8 @@ op83_l_a16(uint32_t fetchdat) static int op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h index 7c7b409d20..43a3708e0d 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu/x86_ops_atomic.h @@ -1,7 +1,9 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; + uint8_t temp; + uint8_t temp2 = AL; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); @@ -20,7 +22,9 @@ opCMPXCHG_b_a16(uint32_t fetchdat) static int opCMPXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; + uint8_t temp; + uint8_t temp2 = AL; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); @@ -40,7 +44,9 @@ opCMPXCHG_b_a32(uint32_t fetchdat) static int opCMPXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; + uint16_t temp; + uint16_t temp2 = AX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); @@ -59,7 +65,9 @@ opCMPXCHG_w_a16(uint32_t fetchdat) static int opCMPXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; + uint16_t temp; + uint16_t temp2 = AX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); @@ -79,7 +87,9 @@ opCMPXCHG_w_a32(uint32_t fetchdat) static int opCMPXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; + uint32_t temp; + uint32_t temp2 = EAX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -98,7 +108,9 @@ opCMPXCHG_l_a16(uint32_t fetchdat) static int opCMPXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; + uint32_t temp; + uint32_t temp2 = EAX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -115,10 +127,15 @@ opCMPXCHG_l_a32(uint32_t fetchdat) return 0; } +#ifndef OPS_286_386 static int opCMPXCHG8B_a16(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + uint32_t temp; + uint32_t temp_hi; + uint32_t temp2 = EAX; + uint32_t temp2_hi = EDX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -145,7 +162,11 @@ opCMPXCHG8B_a16(uint32_t fetchdat) static int opCMPXCHG8B_a32(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + uint32_t temp; + uint32_t temp_hi; + uint32_t temp2 = EAX; + uint32_t temp2_hi = EDX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -169,13 +190,16 @@ opCMPXCHG8B_a32(uint32_t fetchdat) cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } +#endif /* dest = eab, src = r8 */ static int opXADD_b_a16(uint32_t fetchdat) { uint8_t temp; - uint8_t src, dest; + uint8_t src; + uint8_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = getr8(cpu_reg); @@ -195,7 +219,9 @@ static int opXADD_b_a32(uint32_t fetchdat) { uint8_t temp; - uint8_t src, dest; + uint8_t src; + uint8_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = getr8(cpu_reg); @@ -216,7 +242,9 @@ static int opXADD_w_a16(uint32_t fetchdat) { uint16_t temp; - uint16_t src, dest; + uint16_t src; + uint16_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].w; @@ -236,7 +264,9 @@ static int opXADD_w_a32(uint32_t fetchdat) { uint16_t temp; - uint16_t src, dest; + uint16_t src; + uint16_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].w; @@ -257,7 +287,9 @@ static int opXADD_l_a16(uint32_t fetchdat) { uint32_t temp; - uint32_t src, dest; + uint32_t src; + uint32_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].l; @@ -277,7 +309,9 @@ static int opXADD_l_a32(uint32_t fetchdat) { uint32_t temp; - uint32_t src, dest; + uint32_t src; + uint32_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].l; diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index d3ff97eade..b4779ab3ee 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -19,6 +19,7 @@ static int opAAD(uint32_t fetchdat) { int base = getbytef(); + if (!cpu_isintel) base = 10; AL = (AH * base) + AL; @@ -33,6 +34,7 @@ static int opAAM(uint32_t fetchdat) { int base = getbytef(); + if (!base || !cpu_isintel) base = 10; AH = AL / base; @@ -63,7 +65,9 @@ opAAS(uint32_t fetchdat) static int opDAA(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw; + uint16_t old_AL; + uint16_t old_CF; flags_rebuild(); old_AL = AL; @@ -98,7 +102,9 @@ opDAA(uint32_t fetchdat) static int opDAS(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw; + uint16_t old_AL; + uint16_t old_CF; flags_rebuild(); old_AL = AL; diff --git a/src/cpu/x86_ops_bit.h b/src/cpu/x86_ops_bit.h index 8514e8e1c6..b72142b5a6 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu/x86_ops_bit.h @@ -201,13 +201,17 @@ opBT_l_r_a32(uint32_t fetchdat) return 0; \ } +// clang-format off opBT(C, ^=) - opBT(R, &= ~) - opBT(S, |=) +opBT(R, &= ~) +opBT(S, |=) + // clang-format on - static int opBA_w_a16(uint32_t fetchdat) +static int +opBA_w_a16(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint16_t temp; fetch_ea_16(fetchdat); @@ -258,7 +262,8 @@ opBT(C, ^=) static int opBA_w_a32(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint16_t temp; fetch_ea_32(fetchdat); @@ -310,7 +315,8 @@ opBA_w_a32(uint32_t fetchdat) static int opBA_l_a16(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint32_t temp; fetch_ea_16(fetchdat); @@ -361,7 +367,8 @@ opBA_l_a16(uint32_t fetchdat) static int opBA_l_a32(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint32_t temp; fetch_ea_32(fetchdat); diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 88899cef8b..9d52a27644 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -6,9 +6,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg, old_pc); \ + op_loadcscall(new_seg, old_pc); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -54,9 +54,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg, old_pc); \ + op_loadcscall(new_seg, old_pc); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -103,9 +103,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg); \ + op_loadcscall(new_seg); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -148,9 +148,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg); \ + op_loadcscall(new_seg); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -189,8 +189,10 @@ static int opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; + uint32_t old_cs; + uint32_t old_pc; + uint16_t new_cs; + uint16_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -209,8 +211,10 @@ opCALL_far_w(uint32_t fetchdat) static int opCALL_far_l(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; + uint32_t old_cs; + uint32_t old_pc; + uint32_t new_cs; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -230,8 +234,10 @@ opCALL_far_l(uint32_t fetchdat) static int opFF_w_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -356,14 +362,12 @@ opFF_w_a16(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0); PREFETCH_FLUSH(); @@ -392,8 +396,10 @@ opFF_w_a16(uint32_t fetchdat) static int opFF_w_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -518,14 +524,12 @@ opFF_w_a32(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1); PREFETCH_FLUSH(); @@ -555,8 +559,10 @@ opFF_w_a32(uint32_t fetchdat) static int opFF_l_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -681,14 +687,12 @@ opFF_l_a16(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0); PREFETCH_FLUSH(); @@ -717,8 +721,10 @@ opFF_l_a16(uint32_t fetchdat) static int opFF_l_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -845,14 +851,12 @@ opFF_l_a32(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); PREFETCH_FLUSH(); diff --git a/src/cpu/x86_ops_flag_2386.h b/src/cpu/x86_ops_flag_2386.h new file mode 100644 index 0000000000..ba34ae5e7a --- /dev/null +++ b/src/cpu/x86_ops_flag_2386.h @@ -0,0 +1,323 @@ +static int +opCMC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags ^= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opCLC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opCLD(uint32_t fetchdat) +{ + cpu_state.flags &= ~D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opCLI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags &= ~I_FLAG; + + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSTC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTD(uint32_t fetchdat) +{ + cpu_state.flags |= D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; + + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSAHF(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opLAHF(uint32_t fetchdat) +{ + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opPUSHF(uint32_t fetchdat) +{ + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; + + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.flags); + } + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSHFD(uint32_t fetchdat) +{ + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.flags | (tempw << 16)); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} + +static int +opPOPF_186(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF_286(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint32_t old_esp = ESP; + + tempw = POP_W(); + if (cpu_state.abrt) { + + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPFD(uint32_t fetchdat) +{ + uint32_t templ; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + templ = POP_L(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; + + templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486 || isibm486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; + + flags_extract(); + rf_flag_no_clear = 1; + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index 29e9999417..849e24e3df 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -97,7 +97,9 @@ opWAIT(uint32_t fetchdat) return 1; } - // if (!cpu_use_dynarec && fpu_softfloat) { +#if 0 + if (!cpu_use_dynarec && fpu_softfloat) { +#endif if (fpu_softfloat) { if (fpu_state.swd & FPU_SW_Summary) { if (cr0 & 0x20) { diff --git a/src/cpu/x86_ops_fpu_2386.h b/src/cpu/x86_ops_fpu_2386.h new file mode 100644 index 0000000000..52c24d9958 --- /dev/null +++ b/src/cpu/x86_ops_fpu_2386.h @@ -0,0 +1,113 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +static int +opESCAPE_d8_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_d8_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_d9_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_d9_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_da_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_da_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_db_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_db_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_dc_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); +} +static int +opESCAPE_dc_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); +} + +static int +opESCAPE_dd_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_dd_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_de_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_de_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat); +} + +static int +opESCAPE_df_a16(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat); +} +static int +opESCAPE_df_a32(uint32_t fetchdat) +{ + return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat); +} + +static int +opWAIT(uint32_t fetchdat) +{ + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + +#if 0 + if (!cpu_use_dynarec && fpu_softfloat) { +#endif + if (fpu_softfloat) { + if (fpu_state.swd & FPU_SW_Summary) { + if (cr0 & 0x20) { + x86_int(16); + return 1; + } + } + } + CLOCK_CYCLES(4); + return 0; +} diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 9e00249caa..ab9d02d254 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -43,73 +43,201 @@ opSYSEXIT(uint32_t fetchdat) return ret; } +static int +sf_fx_save_stor_common(uint32_t fetchdat, int bits) +{ + uint8_t fxinst = 0; + uint32_t tag_byte; + unsigned index; + floatx80 reg; + + if (CPUID < 0x650) + return ILLEGAL(fetchdat); + + FP_ENTER(); + + if (bits == 32) { + fetch_ea_32(fetchdat); + } else { + fetch_ea_16(fetchdat); + } + + if (cpu_state.eaaddr & 0xf) { + x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); + x86gpf(NULL, 0); + return cpu_state.abrt; + } + + fxinst = (rmdat >> 3) & 7; + + if ((fxinst > 1) || (cpu_mod == 3)) { + x86illegal(); + return cpu_state.abrt; + } + + FP_ENTER(); + + if (fxinst == 1) { + /* FXRSTOR */ + fpu_state.cwd = readmemw(easeg, cpu_state.eaaddr); + fpu_state.swd = readmemw(easeg, cpu_state.eaaddr + 2); + fpu_state.tos = (fpu_state.swd >> 11) & 7; + + /* always set bit 6 as '1 */ + fpu_state.cwd = (fpu_state.cwd & ~FPU_CW_Reserved_Bits) | 0x0040; + + /* Restore x87 FPU Opcode */ + /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */ + fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; + + fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8); + fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12); + + tag_byte = readmemb(easeg, cpu_state.eaaddr + 4); + + fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16); + fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20); + + /* load i387 register file */ + for (index = 0; index < 8; index++) { + reg.fraction = readmemq(easeg, cpu_state.eaaddr + (index * 16) + 32); + reg.exp = readmemw(easeg, cpu_state.eaaddr + (index * 16) + 40); + + // update tag only if it is not empty + FPU_save_regi_tag(reg, IS_TAG_EMPTY(index) ? X87_TAG_EMPTY : FPU_tagof(reg), index); + } + + fpu_state.tag = unpack_FPU_TW(tag_byte); + + /* check for unmasked exceptions */ + if (fpu_state.swd & ~fpu_state.cwd & FPU_CW_Exceptions_Mask) { + /* set the B and ES bits in the status-word */ + fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward); + } else { + /* clear the B and ES bits in the status-word */ + fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward); + } + + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + } else { + /* FXSAVE */ + writememw(easeg, cpu_state.eaaddr, i387_get_control_word()); + writememw(easeg, cpu_state.eaaddr + 2, i387_get_status_word()); + writememw(easeg, cpu_state.eaaddr + 4, pack_FPU_TW(fpu_state.tag)); + + /* x87 FPU Opcode (16 bits) */ + /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */ + writememw(easeg, cpu_state.eaaddr + 6, fpu_state.foo); + + /* + * x87 FPU IP Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32/64 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit IP offset + * + 32-bit mode - 32-bit IP offset + * + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved. + * x87 CS FPU IP Selector + * + 16 bit, in 16/32 bit mode only + */ + writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip); + writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs); + + /* + * x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit offset + * + 32-bit mode - 32-bit offset + * + 16-bit mode - low 16 bits are offset; high 16 bits are reserved. + * x87 DS FPU Instruction Operand (Data) Pointer Selector + * + 16 bit, in 16/32 bit mode only + */ + writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp); + writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds); + + /* store i387 register file */ + for (index = 0; index < 8; index++) { + const floatx80 fp = FPU_read_regi(index); + + writememq(easeg, cpu_state.eaaddr + (index * 16) + 32, fp.fraction); + writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.exp); + } + + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + } + + return cpu_state.abrt; +} + static int fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; - int i, mmx_tags = 0; - uint16_t exp = 0x0000; - uint64_t mant = 0x0000000000000000ULL; - uint64_t fraction; - uint8_t jm, valid; - /* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent - ----------------------------------------------+------ */ - uint8_t ftw_table_idx; - uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */ - 0x02, /* 0 0 0 0 0 1 | 0x01 */ - 0x03, /* 0 0 0 0 0 0 | 0x02 */ - 0x02, /* 0 0 0 0 1 1 | 0x03 */ - 0x03, /* 0 0 0 1 0 0 | 0x04 */ - 0x00, /* 0 0 0 1 0 1 | 0x05 */ - 0x03, /* 0 0 0 1 1 0 | 0x06 */ - 0x00, /* 0 0 0 1 1 1 | 0x07 */ - 0x03, /* 0 0 1 0 0 0 | 0x08 */ - 0x02, /* 0 0 1 0 0 1 | 0x09 */ - 0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */ - 0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */ - 0x03, /* 0 0 1 1 0 0 | 0x0c */ - 0x02, /* 0 0 1 1 0 1 | 0x0d */ - 0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */ - 0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */ - 0x03, /* 0 1 0 0 0 0 | 0x10 */ - 0x02, /* 0 1 0 0 0 1 | 0x11 */ - 0x03, /* 0 1 0 0 1 0 | 0x12 */ - 0x02, /* 0 1 0 0 1 1 | 0x13 */ - 0x03, /* 0 1 0 1 0 0 | 0x14 */ - 0x02, /* 0 1 0 1 0 1 | 0x15 */ - 0x03, /* 0 1 0 1 1 0 | 0x16 */ - 0x02, /* 0 1 0 1 1 1 | 0x17 */ - 0x03, /* 0 1 1 0 0 0 | 0x18 */ - 0x01, /* 0 1 1 0 0 1 | 0x19 */ - 0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */ - 0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */ - 0x03, /* 0 1 1 1 0 0 | 0x1c */ - 0x01, /* 0 1 1 1 0 1 | 0x1d */ - 0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */ - 0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */ - 0x03, /* 1 0 0 0 0 0 | 0x20 */ - 0x02, /* 1 0 0 0 0 1 | 0x21 */ - 0x03, /* 1 0 0 0 1 0 | 0x22 */ - 0x02, /* 1 0 0 0 1 1 | 0x23 */ - 0x03, /* 1 0 0 1 0 0 | 0x24 */ - 0x02, /* 1 0 0 1 0 1 | 0x25 */ - 0x03, /* 1 0 0 1 1 0 | 0x26 */ - 0x02, /* 1 0 0 1 1 1 | 0x27 */ - 0x03, /* 1 0 1 0 0 0 | 0x28 */ - 0x02, /* 1 0 1 0 0 1 | 0x29 */ - 0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */ - 0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */ - 0x03, /* 1 0 1 1 0 0 | 0x2c */ - 0x02, /* 1 0 1 1 0 1 | 0x2d */ - 0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */ - 0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */ - /* M is the most significant bit of the franction, so it is impossible - for M to o be 1 when the fraction is all 0's. */ + uint8_t fxinst = 0; + uint16_t twd = x87_gettag(); + uint32_t old_eaaddr = 0; + uint8_t ftwb = 0; + uint16_t rec_ftw = 0; + uint16_t fpus = 0; + int i; + int mmx_tags = 0; + uint16_t exp = 0x0000; + uint64_t mant = 0x0000000000000000ULL; + uint64_t fraction; + uint8_t jm; + uint8_t valid; + /* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent + ----------------------------------------------+------ */ + uint8_t ftw_table_idx; + uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */ + 0x02, /* 0 0 0 0 0 1 | 0x01 */ + 0x03, /* 0 0 0 0 0 0 | 0x02 */ + 0x02, /* 0 0 0 0 1 1 | 0x03 */ + 0x03, /* 0 0 0 1 0 0 | 0x04 */ + 0x00, /* 0 0 0 1 0 1 | 0x05 */ + 0x03, /* 0 0 0 1 1 0 | 0x06 */ + 0x00, /* 0 0 0 1 1 1 | 0x07 */ + 0x03, /* 0 0 1 0 0 0 | 0x08 */ + 0x02, /* 0 0 1 0 0 1 | 0x09 */ + 0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */ + 0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */ + 0x03, /* 0 0 1 1 0 0 | 0x0c */ + 0x02, /* 0 0 1 1 0 1 | 0x0d */ + 0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */ + 0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */ + 0x03, /* 0 1 0 0 0 0 | 0x10 */ + 0x02, /* 0 1 0 0 0 1 | 0x11 */ + 0x03, /* 0 1 0 0 1 0 | 0x12 */ + 0x02, /* 0 1 0 0 1 1 | 0x13 */ + 0x03, /* 0 1 0 1 0 0 | 0x14 */ + 0x02, /* 0 1 0 1 0 1 | 0x15 */ + 0x03, /* 0 1 0 1 1 0 | 0x16 */ + 0x02, /* 0 1 0 1 1 1 | 0x17 */ + 0x03, /* 0 1 1 0 0 0 | 0x18 */ + 0x01, /* 0 1 1 0 0 1 | 0x19 */ + 0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */ + 0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */ + 0x03, /* 0 1 1 1 0 0 | 0x1c */ + 0x01, /* 0 1 1 1 0 1 | 0x1d */ + 0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */ + 0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */ + 0x03, /* 1 0 0 0 0 0 | 0x20 */ + 0x02, /* 1 0 0 0 0 1 | 0x21 */ + 0x03, /* 1 0 0 0 1 0 | 0x22 */ + 0x02, /* 1 0 0 0 1 1 | 0x23 */ + 0x03, /* 1 0 0 1 0 0 | 0x24 */ + 0x02, /* 1 0 0 1 0 1 | 0x25 */ + 0x03, /* 1 0 0 1 1 0 | 0x26 */ + 0x02, /* 1 0 0 1 1 1 | 0x27 */ + 0x03, /* 1 0 1 0 0 0 | 0x28 */ + 0x02, /* 1 0 1 0 0 1 | 0x29 */ + 0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */ + 0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */ + 0x03, /* 1 0 1 1 0 0 | 0x2c */ + 0x02, /* 1 0 1 1 0 1 | 0x2d */ + 0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */ + 0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */ + /* M is the most significant bit of the franction, so it is impossible + for M to o be 1 when the fraction is all 0's. */ if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -159,11 +287,11 @@ fx_save_stor_common(uint32_t fetchdat, int bits) for (i = 0; i <= 7; i++) { cpu_state.eaaddr = old_eaaddr + 32 + (i << 4); - mant = readmemq(easeg, cpu_state.eaaddr); - fraction = mant & 0x7fffffffffffffffULL; - exp = readmemw(easeg, cpu_state.eaaddr + 8); - jm = (mant >> 62) & 0x03; - valid = !(ftwb & (1 << i)); + mant = readmemq(easeg, cpu_state.eaaddr); + fraction = mant & 0x7fffffffffffffffULL; + exp = readmemw(easeg, cpu_state.eaaddr + 8); + jm = (mant >> 62) & 0x03; + valid = !(ftwb & (1 << i)); ftw_table_idx = (!!(exp == 0x1111)) << 5; ftw_table_idx |= (!!(exp == 0x0000)) << 4; @@ -253,12 +381,18 @@ fx_save_stor_common(uint32_t fetchdat, int bits) static int opFXSAVESTOR_a16(uint32_t fetchdat) { + if (fpu_softfloat) + return sf_fx_save_stor_common(fetchdat, 16); + return fx_save_stor_common(fetchdat, 16); } static int opFXSAVESTOR_a32(uint32_t fetchdat) { + if (fpu_softfloat) + return sf_fx_save_stor_common(fetchdat, 32); + return fx_save_stor_common(fetchdat, 32); } diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index a1503a75ed..97ca673d78 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -86,9 +86,10 @@ opJ(L) opJ(NL) opJ(LE) opJ(NLE) -// clang-format on + // clang-format on - static int opLOOPNE_w(uint32_t fetchdat) +static int +opLOOPNE_w(uint32_t fetchdat) { int8_t offset = (int8_t) getbytef(); CX--; @@ -271,15 +272,17 @@ opJMP_r32(uint32_t fetchdat) static int opJMP_far_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; uint32_t old_pc; + addr = getwordf(); seg = getword(); if (cpu_state.abrt) return 1; old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + op_loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); PREFETCH_FLUSH(); @@ -289,14 +292,16 @@ static int opJMP_far_a32(uint32_t fetchdat) { uint16_t seg; - uint32_t addr, old_pc; + uint32_t addr; + uint32_t old_pc; + addr = getlong(); seg = getword(); if (cpu_state.abrt) return 1; old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + op_loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); PREFETCH_FLUSH(); @@ -307,6 +312,7 @@ static int opCALL_r16(uint32_t fetchdat) { int16_t addr = (int16_t) getwordf(); + PUSH_W(cpu_state.pc); cpu_state.pc += addr; cpu_state.pc &= 0xffff; @@ -320,6 +326,7 @@ static int opCALL_r32(uint32_t fetchdat) { int32_t addr = getlong(); + if (cpu_state.abrt) return 1; PUSH_L(cpu_state.pc); diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 940e2ea8ea..519bdbe3ca 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -51,9 +51,12 @@ opSETALC(uint32_t fetchdat) static int opF6_a16(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; + int tempws = 0; + int tempws2 = 0; + uint16_t tempw = 0; + uint16_t src16; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_16(fetchdat); @@ -126,7 +129,7 @@ opF6_a16(uint32_t fetchdat) if (dst && !(tempw & 0xff00)) { AH = src16 % dst; AL = (src16 / dst) & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -146,7 +149,7 @@ opF6_a16(uint32_t fetchdat) if (dst && ((int) temps == tempws2)) { AH = (tempws % (int) ((int8_t) dst)) & 0xff; AL = tempws2 & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -167,9 +170,12 @@ opF6_a16(uint32_t fetchdat) static int opF6_a32(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; + int tempws = 0; + int tempws2 = 0; + uint16_t tempw = 0; + uint16_t src16; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_32(fetchdat); @@ -240,7 +246,7 @@ opF6_a32(uint32_t fetchdat) if (dst && !(tempw & 0xff00)) { AH = src16 % dst; AL = (src16 / dst) & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -260,7 +266,7 @@ opF6_a32(uint32_t fetchdat) if (dst && ((int) temps == tempws2)) { AH = (tempws % (int) ((int8_t) dst)) & 0xff; AL = tempws2 & 0xff; - if (!cpu_iscyrix) { + if (!cpu_iscyrix && !is6117) { flags_rebuild(); cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ cpu_state.flags &= ~1; @@ -282,10 +288,13 @@ opF6_a32(uint32_t fetchdat) static int opF7_w_a16(uint32_t fetchdat) { - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 0; + uint32_t templ; + uint32_t templ2 = 0; + int tempws; + int tempws2 = 0; int16_t temps16; - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -357,7 +366,7 @@ opF7_w_a16(uint32_t fetchdat) if (dst && !(templ2 & 0xffff0000)) { DX = templ % dst; AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -374,7 +383,7 @@ opF7_w_a16(uint32_t fetchdat) if ((dst != 0) && ((int) temps16 == tempws2)) { DX = tempws % (int) ((int16_t) dst); AX = tempws2 & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -392,10 +401,13 @@ opF7_w_a16(uint32_t fetchdat) static int opF7_w_a32(uint32_t fetchdat) { - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 1; + uint32_t templ; + uint32_t templ2 = 0; + int tempws; + int tempws2 = 1; int16_t temps16; - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -467,7 +479,7 @@ opF7_w_a32(uint32_t fetchdat) if (dst && !(templ2 & 0xffff0000)) { DX = templ % dst; AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); @@ -485,7 +497,7 @@ opF7_w_a32(uint32_t fetchdat) if ((dst != 0) && ((int) temps16 == tempws2)) { DX = tempws % (int) ((int16_t) dst); AX = tempws2 & 0xffff; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp16(AX); /*Not a Cyrix*/ } else { x86_int(0); @@ -505,7 +517,8 @@ static int opF7_l_a16(uint32_t fetchdat) { uint64_t temp64; - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -574,7 +587,7 @@ opF7_l_a16(uint32_t fetchdat) case 0x30: /*DIV EAX,l*/ if (divl(dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES((is486) ? 40 : 38); PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); @@ -582,7 +595,7 @@ opF7_l_a16(uint32_t fetchdat) case 0x38: /*IDIV EAX,l*/ if (idivl((int32_t) dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES(43); PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); @@ -597,7 +610,8 @@ static int opF7_l_a32(uint32_t fetchdat) { uint64_t temp64; - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -666,7 +680,7 @@ opF7_l_a32(uint32_t fetchdat) case 0x30: /*DIV EAX,l*/ if (divl(dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES((is486) ? 40 : 38); PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); @@ -674,7 +688,7 @@ opF7_l_a32(uint32_t fetchdat) case 0x38: /*IDIV EAX,l*/ if (idivl((int32_t) dst)) return 1; - if (!cpu_iscyrix) + if (!cpu_iscyrix && !is6117) setznp32(EAX); /*Not a Cyrix*/ CLOCK_CYCLES(43); PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); @@ -712,6 +726,28 @@ opHLT(uint32_t fetchdat) return 0; } +#ifdef OPS_286_386 +static int +opLOCK(uint32_t fetchdat) +{ + int legal; + fetchdat = fastreadl_fetch(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + legal = is_lock_legal(fetchdat); + + if (legal == 4) + pclog("PREFIX: F0 %08X\n", fetchdat); + + ILLEGAL_ON(legal == 0); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +#else static int opLOCK(uint32_t fetchdat) { @@ -726,11 +762,13 @@ opLOCK(uint32_t fetchdat) PREFETCH_PREFIX(); return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } +#endif static int opBOUND_w_a16(uint32_t fetchdat) { - int16_t low, high; + int16_t low; + int16_t high; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -752,7 +790,8 @@ opBOUND_w_a16(uint32_t fetchdat) static int opBOUND_w_a32(uint32_t fetchdat) { - int16_t low, high; + int16_t low; + int16_t high; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -775,7 +814,8 @@ opBOUND_w_a32(uint32_t fetchdat) static int opBOUND_l_a16(uint32_t fetchdat) { - int32_t low, high; + int32_t low; + int32_t high; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -797,7 +837,8 @@ opBOUND_l_a16(uint32_t fetchdat) static int opBOUND_l_a32(uint32_t fetchdat) { - int32_t low, high; + int32_t low; + int32_t high; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c new file mode 100644 index 0000000000..f26c903f94 --- /dev/null +++ b/src/cpu/x86_ops_mmx.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include "x86.h" +#include "x87.h" +#include <86box/nmi.h> +#include <86box/mem.h> +#include <86box/smram.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/timer.h> +#include "x86seg_common.h" +#include "x86seg.h" +#include "386_common.h" +#include "x86_flags.h" + +MMX_REG *MMP[8]; +uint16_t *MMEP[8]; + +static uint16_t MME[8]; + +#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) +void +mmx_init(void) +{ + memset(MME, 0xff, sizeof(MME)); + + for (uint8_t i = 0; i < 8; i++) { + if (fpu_softfloat) { + MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; + MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp; + } else { + MMP[i] = &(cpu_state.MM[i]); + MMEP[i] = &(MME[i]); + } + } +} diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index d270b728f7..ab5e197623 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -1,11 +1,17 @@ -#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) -#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) -#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) -#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) +#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) +#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) +#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) +#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) + +#define MMX_GETREGP(r) MMP[r] +#define MMX_GETREG(r) *(MMP[r]) + +#define MMX_SETEXP(r) \ + *(MMEP[r]) = 0xffff #define MMX_GETSRC() \ if (cpu_mod == 3) { \ - src = cpu_state.MM[cpu_rm]; \ + src = MMX_GETREG(cpu_rm); \ CLOCK_CYCLES(1); \ } else { \ SEG_CHECK_READ(cpu_state.ea_seg); \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index e473f8ec53..099789970d 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,40 +1,52 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; + dst->b[0] += src.b[0]; + dst->b[1] += src.b[1]; + dst->b[2] += src.b[2]; + dst->b[3] += src.b[3]; + dst->b[4] += src.b[4]; + dst->b[5] += src.b[5]; + dst->b[6] += src.b[6]; + dst->b[7] += src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; + dst->b[0] += src.b[0]; + dst->b[1] += src.b[1]; + dst->b[2] += src.b[2]; + dst->b[3] += src.b[3]; + dst->b[4] += src.b[4]; + dst->b[5] += src.b[5]; + dst->b[6] += src.b[6]; + dst->b[7] += src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -42,32 +54,44 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; + dst->w[0] += src.w[0]; + dst->w[1] += src.w[1]; + dst->w[2] += src.w[2]; + dst->w[3] += src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; + dst->w[0] += src.w[0]; + dst->w[1] += src.w[1]; + dst->w[2] += src.w[2]; + dst->w[3] += src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -75,28 +99,40 @@ opPADDW_a32(uint32_t fetchdat) static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + dst->l[0] += src.l[0]; + dst->l[1] += src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + dst->l[0] += src.l[0]; + dst->l[1] += src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -104,40 +140,52 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] + src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] + src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] + src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] + src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] + src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] + src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -145,40 +193,52 @@ opPADDSB_a32(uint32_t fetchdat) static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + dst->b[0] = USATB(dst->b[0] + src.b[0]); + dst->b[1] = USATB(dst->b[1] + src.b[1]); + dst->b[2] = USATB(dst->b[2] + src.b[2]); + dst->b[3] = USATB(dst->b[3] + src.b[3]); + dst->b[4] = USATB(dst->b[4] + src.b[4]); + dst->b[5] = USATB(dst->b[5] + src.b[5]); + dst->b[6] = USATB(dst->b[6] + src.b[6]); + dst->b[7] = USATB(dst->b[7] + src.b[7]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + dst->b[0] = USATB(dst->b[0] + src.b[0]); + dst->b[1] = USATB(dst->b[1] + src.b[1]); + dst->b[2] = USATB(dst->b[2] + src.b[2]); + dst->b[3] = USATB(dst->b[3] + src.b[3]); + dst->b[4] = USATB(dst->b[4] + src.b[4]); + dst->b[5] = USATB(dst->b[5] + src.b[5]); + dst->b[6] = USATB(dst->b[6] + src.b[6]); + dst->b[7] = USATB(dst->b[7] + src.b[7]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -186,32 +246,44 @@ opPADDUSB_a32(uint32_t fetchdat) static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -219,32 +291,44 @@ opPADDSW_a32(uint32_t fetchdat) static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + dst->w[0] = USATW(dst->w[0] + src.w[0]); + dst->w[1] = USATW(dst->w[1] + src.w[1]); + dst->w[2] = USATW(dst->w[2] + src.w[2]); + dst->w[3] = USATW(dst->w[3] + src.w[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + dst->w[0] = USATW(dst->w[0] + src.w[0]); + dst->w[1] = USATW(dst->w[1] + src.w[1]); + dst->w[2] = USATW(dst->w[2] + src.w[2]); + dst->w[3] = USATW(dst->w[3] + src.w[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -252,42 +336,54 @@ opPADDUSW_a32(uint32_t fetchdat) static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; + if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst->l[0] = 0x80000000; else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + dst->sl[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst->sw[1] * (int32_t) src.sw[1]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; + if (dst->l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst->l[1] = 0x80000000; else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; + if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst->l[0] = 0x80000000; else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + dst->sl[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst->sw[1] * (int32_t) src.sw[1]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; + if (dst->l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst->l[1] = 0x80000000; else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -295,154 +391,178 @@ opPMADDWD_a32(uint32_t fetchdat) static int opPMULLW_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + dst = MMX_GETREGP(cpu_reg); + + if (cpu_mod == 3) + src = MMX_GETREG(cpu_rm); + else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); + CLOCK_CYCLES(1); } + dst->w[0] *= src.w[0]; + dst->w[1] *= src.w[1]; + dst->w[2] *= src.w[2]; + dst->w[3] *= src.w[3]; + CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_reg); + return 0; } static int opPMULLW_a32(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + dst = MMX_GETREGP(cpu_reg); + + if (cpu_mod == 3) + src = MMX_GETREG(cpu_rm); + else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); + CLOCK_CYCLES(1); } + dst->w[0] *= src.w[0]; + dst->w[1] *= src.w[1]; + dst->w[2] *= src.w[2]; + dst->w[3] *= src.w[3]; + CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_reg); + return 0; } static int opPMULHW_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + dst = MMX_GETREGP(cpu_reg); + + if (cpu_mod == 3) + src = MMX_GETREG(cpu_rm); + else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); + CLOCK_CYCLES(1); } + dst->w[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) >> 16; + dst->w[1] = ((int32_t) dst->sw[1] * (int32_t) src.sw[1]) >> 16; + dst->w[2] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) >> 16; + dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_reg); + return 0; } static int opPMULHW_a32(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + dst = MMX_GETREGP(cpu_reg); + + if (cpu_mod == 3) + src = MMX_GETREG(cpu_rm); + else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); + CLOCK_CYCLES(1); } + dst->w[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) >> 16; + dst->w[1] = ((int32_t) dst->sw[1] * (int32_t) src.sw[1]) >> 16; + dst->w[2] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) >> 16; + dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_reg); + return 0; } static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + dst->b[0] -= src.b[0]; + dst->b[1] -= src.b[1]; + dst->b[2] -= src.b[2]; + dst->b[3] -= src.b[3]; + dst->b[4] -= src.b[4]; + dst->b[5] -= src.b[5]; + dst->b[6] -= src.b[6]; + dst->b[7] -= src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + dst->b[0] -= src.b[0]; + dst->b[1] -= src.b[1]; + dst->b[2] -= src.b[2]; + dst->b[3] -= src.b[3]; + dst->b[4] -= src.b[4]; + dst->b[5] -= src.b[5]; + dst->b[6] -= src.b[6]; + dst->b[7] -= src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -450,32 +570,44 @@ opPSUBB_a32(uint32_t fetchdat) static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + dst->w[0] -= src.w[0]; + dst->w[1] -= src.w[1]; + dst->w[2] -= src.w[2]; + dst->w[3] -= src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + dst->w[0] -= src.w[0]; + dst->w[1] -= src.w[1]; + dst->w[2] -= src.w[2]; + dst->w[3] -= src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -483,28 +615,40 @@ opPSUBW_a32(uint32_t fetchdat) static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + dst->l[0] -= src.l[0]; + dst->l[1] -= src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + dst->l[0] -= src.l[0]; + dst->l[1] -= src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -512,42 +656,52 @@ opPSUBD_a32(uint32_t fetchdat) static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - pclog("opPSUBSB_a16(%08X)\n", fetchdat); + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] - src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] - src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] - src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - pclog("opPSUBSB_a32(%08X)\n", fetchdat); + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] - src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] - src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] - src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -555,40 +709,52 @@ opPSUBSB_a32(uint32_t fetchdat) static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + dst->b[0] = USATB(dst->b[0] - src.b[0]); + dst->b[1] = USATB(dst->b[1] - src.b[1]); + dst->b[2] = USATB(dst->b[2] - src.b[2]); + dst->b[3] = USATB(dst->b[3] - src.b[3]); + dst->b[4] = USATB(dst->b[4] - src.b[4]); + dst->b[5] = USATB(dst->b[5] - src.b[5]); + dst->b[6] = USATB(dst->b[6] - src.b[6]); + dst->b[7] = USATB(dst->b[7] - src.b[7]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + dst->b[0] = USATB(dst->b[0] - src.b[0]); + dst->b[1] = USATB(dst->b[1] - src.b[1]); + dst->b[2] = USATB(dst->b[2] - src.b[2]); + dst->b[3] = USATB(dst->b[3] - src.b[3]); + dst->b[4] = USATB(dst->b[4] - src.b[4]); + dst->b[5] = USATB(dst->b[5] - src.b[5]); + dst->b[6] = USATB(dst->b[6] - src.b[6]); + dst->b[7] = USATB(dst->b[7] - src.b[7]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -596,32 +762,44 @@ opPSUBUSB_a32(uint32_t fetchdat) static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -629,32 +807,44 @@ opPSUBSW_a32(uint32_t fetchdat) static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + dst->w[0] = USATW(dst->w[0] - src.w[0]); + dst->w[1] = USATW(dst->w[1] - src.w[1]); + dst->w[2] = USATW(dst->w[2] - src.w[2]); + dst->w[3] = USATW(dst->w[3] - src.w[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + dst->w[0] = USATW(dst->w[0] - src.w[0]); + dst->w[1] = USATW(dst->w[1] - src.w[1]); + dst->w[2] = USATW(dst->w[2] - src.w[2]); + dst->w[3] = USATW(dst->w[3] - src.w[3]); + + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index 40ae66a9c2..141dba6bc3 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,42 +1,52 @@ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; + dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; + dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; + dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0; + dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0; + dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0; + dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; + dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; + dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; + dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; + dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0; + dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0; + dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0; + dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; + dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; + + MMX_SETEXP(cpu_reg); return 0; } @@ -44,42 +54,52 @@ opPCMPEQB_a32(uint32_t fetchdat) static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; + dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; + dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; + dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0; + dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0; + dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0; + dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; + dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; + dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; + dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; + dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0; + dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0; + dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0; + dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; + dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; + + MMX_SETEXP(cpu_reg); return 0; } @@ -87,34 +107,44 @@ opPCMPGTB_a32(uint32_t fetchdat) static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; + dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; + dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; + dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; + dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; + dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; + dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } @@ -122,34 +152,44 @@ opPCMPEQW_a32(uint32_t fetchdat) static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; + dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; + dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; + dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; + dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; + dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; + dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } @@ -157,30 +197,40 @@ opPCMPGTW_a32(uint32_t fetchdat) static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } @@ -188,30 +238,40 @@ opPCMPEQD_a32(uint32_t fetchdat) static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; + + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index c22c820c12..6172198459 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,99 +1,155 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; + dst->q &= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; + dst->q &= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + dst->q = ~dst->q & src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + dst->q = ~dst->q & src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; + dst->q |= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; + dst->q |= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; + dst->q ^= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; + dst->q ^= src.q; + + MMX_SETEXP(cpu_reg); + return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index bb51573e62..c72c8143d6 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -1,88 +1,112 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) { + uint32_t dst; + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; + op->l[0] = cpu_state.regs[cpu_rm].l; + op->l[1] = 0; CLOCK_CYCLES(1); } else { - uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + op->l[0] = dst; + op->l[1] = 0; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opMOVD_l_mm_a32(uint32_t fetchdat) { + uint32_t dst; + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; + op->l[0] = cpu_state.regs[cpu_rm].l; + op->l[1] = 0; CLOCK_CYCLES(1); } else { - uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + op->l[0] = dst; + op->l[1] = 0; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opMOVD_mm_l_a16(uint32_t fetchdat) { + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } static int opMOVD_mm_l_a32(uint32_t fetchdat) { + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } @@ -91,45 +115,59 @@ opMOVD_mm_l_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) { + const MMX_REG *op; + if (in_smm) return opSMINT(fetchdat); MMX_ENTER(); fetch_ea_16(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) { + const MMX_REG *op; + if (in_smm) return opSMINT(fetchdat); MMX_ENTER(); fetch_ea_32(fetchdat); + + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } #endif @@ -137,81 +175,121 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat) static int opMOVQ_q_mm_a16(uint32_t fetchdat) { + uint64_t dst; + MMX_REG src; + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); + + src = MMX_GETREG(cpu_rm); + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + op->q = src.q; CLOCK_CYCLES(1); } else { - uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; + + op->q = dst; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opMOVQ_q_mm_a32(uint32_t fetchdat) { + uint64_t dst; + MMX_REG src; + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); + + src = MMX_GETREG(cpu_rm); + op = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + op->q = src.q; CLOCK_CYCLES(1); } else { - uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; + + op->q = dst; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opMOVQ_mm_q_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; + MMX_ENTER(); fetch_ea_16(fetchdat); + + src = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_rm); + if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + dst->q = src.q; CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_rm); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + writememq(easeg, cpu_state.eaaddr, src.q); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } static int opMOVQ_mm_q_a32(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; + MMX_ENTER(); fetch_ea_32(fetchdat); + + src = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_rm); + if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + dst->q = src.q; CLOCK_CYCLES(1); + + MMX_SETEXP(cpu_rm); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + writememq(easeg, cpu_state.eaaddr, src.q); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); } + return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index f0180db91a..90ed1b6d2c 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -1,73 +1,101 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { + uint32_t usrc; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + src = MMX_GETREG(cpu_rm); + dst = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + dst->l[1] = src.l[0]; CLOCK_CYCLES(1); } else { - uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); + usrc = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + dst->l[1] = usrc; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opPUNPCKLDQ_a32(uint32_t fetchdat) { + uint32_t usrc; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + src = MMX_GETREG(cpu_rm); + dst = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + dst->l[1] = src.l[0]; CLOCK_CYCLES(1); } else { - uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); + usrc = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + dst->l[1] = usrc; CLOCK_CYCLES(2); } + + MMX_SETEXP(cpu_reg); + return 0; } static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + dst->l[0] = dst->l[1]; + dst->l[1] = src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + dst->l[0] = dst->l[1]; + dst->l[1] = src.l[1]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -75,40 +103,52 @@ opPUNPCKHDQ_a32(uint32_t fetchdat) static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + dst->b[7] = src.b[3]; + dst->b[6] = dst->b[3]; + dst->b[5] = src.b[2]; + dst->b[4] = dst->b[2]; + dst->b[3] = src.b[1]; + dst->b[2] = dst->b[1]; + dst->b[1] = src.b[0]; + dst->b[0] = dst->b[0]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + dst->b[7] = src.b[3]; + dst->b[6] = dst->b[3]; + dst->b[5] = src.b[2]; + dst->b[4] = dst->b[2]; + dst->b[3] = src.b[1]; + dst->b[2] = dst->b[1]; + dst->b[1] = src.b[0]; + dst->b[0] = dst->b[0]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -116,40 +156,52 @@ opPUNPCKLBW_a32(uint32_t fetchdat) static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + dst->b[0] = dst->b[4]; + dst->b[1] = src.b[4]; + dst->b[2] = dst->b[5]; + dst->b[3] = src.b[5]; + dst->b[4] = dst->b[6]; + dst->b[5] = src.b[6]; + dst->b[6] = dst->b[7]; + dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + dst->b[0] = dst->b[4]; + dst->b[1] = src.b[4]; + dst->b[2] = dst->b[5]; + dst->b[3] = src.b[5]; + dst->b[4] = dst->b[6]; + dst->b[5] = src.b[6]; + dst->b[6] = dst->b[7]; + dst->b[7] = src.b[7]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -157,32 +209,44 @@ opPUNPCKHBW_a32(uint32_t fetchdat) static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + dst->w[3] = src.w[1]; + dst->w[2] = dst->w[1]; + dst->w[1] = src.w[0]; + dst->w[0] = dst->w[0]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + dst->w[3] = src.w[1]; + dst->w[2] = dst->w[1]; + dst->w[1] = src.w[0]; + dst->w[0] = dst->w[0]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -190,32 +254,44 @@ opPUNPCKLWD_a32(uint32_t fetchdat) static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + dst->w[0] = dst->w[2]; + dst->w[1] = src.w[2]; + dst->w[2] = dst->w[3]; + dst->w[3] = src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + dst->w[0] = dst->w[2]; + dst->w[1] = src.w[2]; + dst->w[2] = dst->w[3]; + dst->w[3] = src.w[3]; + + MMX_SETEXP(cpu_reg); return 0; } @@ -223,42 +299,52 @@ opPUNPCKHWD_a32(uint32_t fetchdat) static int opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + dst->sb[0] = SSATB(dst->sw[0]); + dst->sb[1] = SSATB(dst->sw[1]); + dst->sb[2] = SSATB(dst->sw[2]); + dst->sb[3] = SSATB(dst->sw[3]); + dst->sb[4] = SSATB(src.sw[0]); + dst->sb[5] = SSATB(src.sw[1]); + dst->sb[6] = SSATB(src.sw[2]); + dst->sb[7] = SSATB(src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + dst->sb[0] = SSATB(dst->sw[0]); + dst->sb[1] = SSATB(dst->sw[1]); + dst->sb[2] = SSATB(dst->sw[2]); + dst->sb[3] = SSATB(dst->sw[3]); + dst->sb[4] = SSATB(src.sw[0]); + dst->sb[5] = SSATB(src.sw[1]); + dst->sb[6] = SSATB(src.sw[2]); + dst->sb[7] = SSATB(src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -266,42 +352,52 @@ opPACKSSWB_a32(uint32_t fetchdat) static int opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + dst->b[0] = USATB(dst->sw[0]); + dst->b[1] = USATB(dst->sw[1]); + dst->b[2] = USATB(dst->sw[2]); + dst->b[3] = USATB(dst->sw[3]); + dst->b[4] = USATB(src.sw[0]); + dst->b[5] = USATB(src.sw[1]); + dst->b[6] = USATB(src.sw[2]); + dst->b[7] = USATB(src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + dst->b[0] = USATB(dst->sw[0]); + dst->b[1] = USATB(dst->sw[1]); + dst->b[2] = USATB(dst->sw[2]); + dst->b[3] = USATB(dst->sw[3]); + dst->b[4] = USATB(src.sw[0]); + dst->b[5] = USATB(src.sw[1]); + dst->b[6] = USATB(src.sw[2]); + dst->b[7] = USATB(src.sw[3]); + + MMX_SETEXP(cpu_reg); return 0; } @@ -309,34 +405,48 @@ opPACKUSWB_a32(uint32_t fetchdat) static int opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; + MMX_REG dst2; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + dst2 = *dst; + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + dst->sw[0] = SSATW(dst2.sl[0]); + dst->sw[1] = SSATW(dst2.sl[1]); + dst->sw[2] = SSATW(src.sl[0]); + dst->sw[3] = SSATW(src.sl[1]); + + MMX_SETEXP(cpu_reg); return 0; } static int opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; + MMX_REG dst2; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + dst2 = *dst; + MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + dst->sw[0] = SSATW(dst2.sl[0]); + dst->sw[1] = SSATW(dst2.sl[1]); + dst->sw[2] = SSATW(src.sl[0]); + dst->sw[3] = SSATW(src.sl[1]); + + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index c9ddc9b93d..04aeb8a9a1 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,6 +1,6 @@ #define MMX_GETSHIFT() \ if (cpu_mod == 3) { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ + shift = (MMX_GETREG(cpu_rm)).b[0]; \ CLOCK_CYCLES(1); \ } else { \ SEG_CHECK_READ(cpu_state.ea_seg); \ @@ -13,40 +13,42 @@ static int opPSxxW_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + MMX_REG *dst; cpu_state.pc += 2; MMX_ENTER(); + dst = MMX_GETREGP(reg); switch (op) { case 0x10: /*PSRLW*/ if (shift > 15) - cpu_state.MM[reg].q = 0; + dst->q = 0; else { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; } break; case 0x20: /*PSRAW*/ if (shift > 15) shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; break; case 0x30: /*PSLLW*/ if (shift > 15) - cpu_state.MM[reg].q = 0; + dst->q = 0; else { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; } break; default: @@ -55,6 +57,8 @@ opPSxxW_imm(uint32_t fetchdat) return 0; } + MMX_SETEXP(reg); + CLOCK_CYCLES(1); return 0; } @@ -62,126 +66,162 @@ opPSxxW_imm(uint32_t fetchdat) static int opPSLLW_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSLLW_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRLW_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRLW_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRAW_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) shift = 15; - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSRAW_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 15) shift = 15; - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } @@ -189,34 +229,37 @@ opPSRAW_a32(uint32_t fetchdat) static int opPSxxD_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + MMX_REG *dst; cpu_state.pc += 2; MMX_ENTER(); + dst = MMX_GETREGP(reg); + switch (op) { case 0x10: /*PSRLD*/ if (shift > 31) - cpu_state.MM[reg].q = 0; + dst->q = 0; else { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; + dst->l[0] >>= shift; + dst->l[1] >>= shift; } break; case 0x20: /*PSRAD*/ if (shift > 31) shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; break; case 0x30: /*PSLLD*/ if (shift > 31) - cpu_state.MM[reg].q = 0; + dst->q = 0; else { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; + dst->l[0] <<= shift; + dst->l[1] <<= shift; } break; default: @@ -225,6 +268,8 @@ opPSxxD_imm(uint32_t fetchdat) return 0; } + MMX_SETEXP(reg); + CLOCK_CYCLES(1); return 0; } @@ -232,114 +277,150 @@ opPSxxD_imm(uint32_t fetchdat) static int opPSLLD_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; + dst->l[0] <<= shift; + dst->l[1] <<= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSLLD_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; + dst->l[0] <<= shift; + dst->l[1] <<= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRLD_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; + dst->l[0] >>= shift; + dst->l[1] >>= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRLD_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; + dst->l[0] >>= shift; + dst->l[1] >>= shift; } + MMX_SETEXP(cpu_reg); + return 0; } static int opPSRAD_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) shift = 31; - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSRAD_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 31) shift = 31; - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } @@ -347,30 +428,35 @@ opPSRAD_a32(uint32_t fetchdat) static int opPSxxQ_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + MMX_REG *dst; cpu_state.pc += 2; + MMX_ENTER(); + dst = MMX_GETREGP(reg); + switch (op) { case 0x10: /*PSRLW*/ if (shift > 63) - cpu_state.MM[reg].q = 0; + dst->q = 0; else - cpu_state.MM[reg].q >>= shift; + dst->q >>= shift; break; case 0x20: /*PSRAW*/ if (shift > 63) shift = 63; - cpu_state.MM[reg].sq >>= shift; + + dst->sq >>= shift; break; case 0x30: /*PSLLW*/ if (shift > 63) - cpu_state.MM[reg].q = 0; + dst->q = 0; else - cpu_state.MM[reg].q <<= shift; + dst->q <<= shift; break; default: cpu_state.pc = cpu_state.oldpc; @@ -378,6 +464,8 @@ opPSxxQ_imm(uint32_t fetchdat) return 0; } + MMX_SETEXP(reg); + CLOCK_CYCLES(1); return 0; } @@ -385,34 +473,46 @@ opPSxxQ_imm(uint32_t fetchdat) static int opPSLLQ_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else - cpu_state.MM[cpu_reg].q <<= shift; + dst->q <<= shift; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSLLQ_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else - cpu_state.MM[cpu_reg].q <<= shift; + dst->q <<= shift; + + MMX_SETEXP(cpu_reg); return 0; } @@ -420,34 +520,46 @@ opPSLLQ_a32(uint32_t fetchdat) static int opPSRLQ_a16(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else - cpu_state.MM[cpu_reg].q >>= shift; + dst->q >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } static int opPSRLQ_a32(uint32_t fetchdat) { - int shift; + MMX_REG *dst; + int shift; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = MMX_GETREGP(cpu_reg); + MMX_GETSHIFT(); if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; + dst->q = 0; else - cpu_state.MM[cpu_reg].q >>= shift; + dst->q >>= shift; + + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 063a335168..e77876d5c2 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -769,83 +769,84 @@ opMOV_r_l_a32(uint32_t fetchdat) return 0; } -#define opCMOV(condition) \ - static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - temp = geteaw(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - temp = geteaw(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - temp = geteal(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } +#ifndef OPS_286_386 +# define opCMOV(condition) \ + static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } // clang-format off opCMOV(O) @@ -865,3 +866,4 @@ opCMOV(NL) opCMOV(LE) opCMOV(NLE) // clang-format on +#endif diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index d95116c935..b0c841f83f 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -251,12 +251,17 @@ opMOV_DRx_r_a32(uint32_t fetchdat) static void opMOV_r_TRx(void) { - // uint32_t base; +#if 0 + uint32_t base; + + base = _tr[4] & 0xfffff800; +#endif - // base = _tr[4] & 0xfffff800; switch (cpu_reg) { case 3: - // pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#if 0 + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif _tr[3] = *(uint32_t *) &(_cache[cache_index]); cache_index = (cache_index + 4) & 0xf; break; @@ -293,42 +298,57 @@ static void opMOV_TRx_r(void) { uint32_t base; - int i, ctl; + int i; + int ctl; _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; base = _tr[4] & 0xfffff800; ctl = _tr[5] & 3; switch (cpu_reg) { case 3: - // pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#if 0 + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif *(uint32_t *) &(_cache[cache_index]) = _tr[3]; cache_index = (cache_index + 4) & 0xf; break; case 4: - // if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) - // pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#if 0 + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#endif break; case 5: - // pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#if 0 + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#endif if (!(_tr[5] & (1 << 19))) { switch (ctl) { case 0: - // pclog(" Cache fill or read...\n", base); +#if 0 + pclog(" Cache fill or read...\n", base); +#endif break; case 1: base += (_tr[5] & 0x7f0); - // pclog(" Writing 16 bytes to %08X...\n", base); +#if 0 + pclog(" Writing 16 bytes to %08X...\n", base); +#endif for (i = 0; i < 16; i += 4) mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); break; case 2: base += (_tr[5] & 0x7f0); - // pclog(" Reading 16 bytes from %08X...\n", base); +#if 0 + pclog(" Reading 16 bytes from %08X...\n", base); +#endif for (i = 0; i < 16; i += 4) *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); break; case 3: - // pclog(" Cache invalidate/flush...\n", base); +#if 0 + pclog(" Cache invalidate/flush...\n", base); +#endif break; } } diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h new file mode 100644 index 0000000000..cae6c9957b --- /dev/null +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -0,0 +1,500 @@ +static int +opMOV_r_CRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; + break; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_CRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; + break; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_r_DRx_a16(uint32_t fetchdat) +{ + if ((CPL > 0) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_DRx_a32(uint32_t fetchdat) +{ + if ((CPL > 0) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + cpu_state.regs[cpu_rm].l = dr[6]; + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + cpu_state.regs[cpu_rm].l = dr[7]; + break; + default: + x86illegal(); + return 1; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_CRx_r_a16(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + break; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_CRx_r_a32(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + break; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_DRx_r_a16(uint32_t fetchdat) +{ + if ((CPL > 0) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + CPU_BLOCK_END(); + return 0; +} +static int +opMOV_DRx_r_a32(uint32_t fetchdat) +{ + if ((CPL > 0) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) { + trap |= 1; + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0 ... 3: + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + break; + case 4: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 6: + dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f); + break; + case 5: + if (cr4 & 0x8) { + x86illegal(); + return 1; + } + fallthrough; + case 7: + dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400; + break; + default: + x86illegal(); + return 1; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + CPU_BLOCK_END(); + return 0; +} + +static void +opMOV_r_TRx(void) +{ +#if 0 + uint32_t base; + + base = _tr[4] & 0xfffff800; +#endif + + switch (cpu_reg) { + case 3: +#if 0 + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} +static int +opMOV_r_TRx_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_TRx_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_TRx_r(void) +{ + uint32_t base; + int i; + int ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: +#if 0 + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: +#if 0 + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#endif + break; + case 5: +#if 0 + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#endif + if (!(_tr[5] & (1 << 19))) { + switch (ctl) { + case 0: +#if 0 + pclog(" Cache fill or read...\n", base); +#endif + break; + case 1: + base += (_tr[5] & 0x7f0); +#if 0 + pclog(" Writing 16 bytes to %08X...\n", base); +#endif + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); +#if 0 + pclog(" Reading 16 bytes from %08X...\n", base); +#endif + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: +#if 0 + pclog(" Cache invalidate/flush...\n", base); +#endif + break; + } + } + break; + } + CLOCK_CYCLES(6); +} +static int +opMOV_TRx_r_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_TRx_r_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index c6bfd9933c..7fcc923120 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -178,13 +178,13 @@ opMOV_seg_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); + op_loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); + op_loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); + op_loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; @@ -195,13 +195,17 @@ opMOV_seg_w_a16(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); + op_loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); + op_loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -223,13 +227,13 @@ opMOV_seg_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); + op_loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); + op_loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); + op_loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; @@ -240,13 +244,17 @@ opMOV_seg_w_a32(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); + op_loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); + op_loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -258,7 +266,8 @@ opMOV_seg_w_a32(uint32_t fetchdat) static int opLDS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -268,7 +277,7 @@ opLDS_w_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -280,7 +289,8 @@ opLDS_w_a16(uint32_t fetchdat) static int opLDS_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -290,7 +300,7 @@ opLDS_w_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -313,7 +323,7 @@ opLDS_l_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -336,7 +346,7 @@ opLDS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -349,7 +359,8 @@ opLDS_l_a32(uint32_t fetchdat) static int opLSS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -359,7 +370,7 @@ opLSS_w_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -371,7 +382,8 @@ opLSS_w_a16(uint32_t fetchdat) static int opLSS_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -381,7 +393,7 @@ opLSS_w_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -404,7 +416,7 @@ opLSS_l_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -427,7 +439,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -450,7 +462,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].w = addr; \ @@ -472,7 +484,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].w = addr; \ @@ -495,7 +507,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].l = addr; \ @@ -518,7 +530,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].l = addr; \ @@ -532,4 +544,4 @@ opLSS_l_a32(uint32_t fetchdat) opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_mul.h b/src/cpu/x86_ops_mul.h index 552a9973a7..aa7526e758 100644 --- a/src/cpu/x86_ops_mul.h +++ b/src/cpu/x86_ops_mul.h @@ -2,7 +2,8 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -31,7 +32,8 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -61,7 +63,8 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -90,7 +93,8 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -120,7 +124,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -151,7 +156,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -183,7 +189,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -214,7 +221,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index c8e146450b..e84847a7be 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -179,10 +179,16 @@ opLAR(w_a16, fetch_ea_16, 0, 0) static int op0F00_common(uint32_t fetchdat, int ea32) { - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access, ar_high; + int dpl; + int valid; + int granularity; + uint32_t addr; + uint32_t base; + uint32_t limit; + uint16_t desc; + uint16_t sel; + uint8_t access; + uint8_t ar_high; switch (rmdat & 0x38) { case 0x00: /*SLDT*/ @@ -356,9 +362,12 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { uint32_t base; - uint16_t limit, tempw; + uint16_t limit; + uint16_t tempw; + switch (rmdat & 0x38) { case 0x00: /*SGDT*/ + ILLEGAL_ON(cpu_mod == 3); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(gdt.limit); @@ -381,6 +390,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); break; case 0x10: /*LGDT*/ + ILLEGAL_ON(cpu_mod == 3); if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { x86gpf(NULL, 0); break; diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index eba59c17ae..8a73573867 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -88,9 +88,10 @@ op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) -// clang-format on + // clang-format on - static int op_66(uint32_t fetchdat) /*Data size select*/ +static int +op_66(uint32_t fetchdat) /*Data size select*/ { fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) diff --git a/src/cpu/x86_ops_prefix_2386.h b/src/cpu/x86_ops_prefix_2386.h new file mode 100644 index 0000000000..87d1149445 --- /dev/null +++ b/src/cpu/x86_ops_prefix_2386.h @@ -0,0 +1,292 @@ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + int legal; \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + if (in_lock) { \ + legal = is_lock_legal(fetchdat); \ + \ + ILLEGAL_ON(legal == 0); \ + } \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes) +op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes) + // clang-format on + +#define op_srp(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } + +// clang-format off +op_srp(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes) +op_srp(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes) + +op_srp(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes) +op_srp(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes) + // clang-format on + +static int +op_66(uint32_t fetchdat) /*Data size select*/ +{ + int legal; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67(uint32_t fetchdat) /*Address size select*/ +{ + int legal; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + if (in_lock) { + legal = is_lock_legal(fetchdat); + + ILLEGAL_ON(legal == 0); + } + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} diff --git a/src/cpu/x86_ops_rep_2386.h b/src/cpu/x86_ops_rep_2386.h new file mode 100644 index 0000000000..fe5048340b --- /dev/null +++ b/src/cpu/x86_ops_rep_2386.h @@ -0,0 +1,863 @@ +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX, 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX, 2); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX, 4); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX, 1); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX, 2); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX, 4); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } + +#define CHEK_READ(a, b, c) + +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } + +REP_OPS(a16, CX, SI, DI) +REP_OPS(a32, ECX, ESI, EDI) +REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) + +static int +opREPNE(uint32_t fetchdat) +{ + fetchdat = fastreadl_fetch(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int +opREPE(uint32_t fetchdat) +{ + fetchdat = fastreadl_fetch(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; + + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index ec200f2d7a..0d9a6370bf 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -6,16 +6,16 @@ #define RETF_a16(stack_offset) \ if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ - pmoderetf(0, stack_offset); \ + op_pmoderetf(0, stack_offset); \ return 1; \ } \ CPU_SET_OXPC \ if (stack32) { \ cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ + op_loadcs(readmemw(ss, ESP + 2)); \ } else { \ cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ + op_loadcs(readmemw(ss, SP + 2)); \ } \ if (cpu_state.abrt) \ return 1; \ @@ -27,16 +27,16 @@ #define RETF_a32(stack_offset) \ if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ - pmoderetf(1, stack_offset); \ + op_pmoderetf(1, stack_offset); \ return 1; \ } \ CPU_SET_OXPC \ if (stack32) { \ cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \ } else { \ cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ + op_loadcs(readmeml(ss, SP + 4) & 0xffff); \ } \ if (cpu_state.abrt) \ return 1; \ @@ -114,7 +114,7 @@ opIRET_186(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -130,7 +130,7 @@ opIRET_186(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); @@ -154,7 +154,7 @@ opIRET_286(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -170,7 +170,7 @@ opIRET_286(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); @@ -190,7 +190,9 @@ opIRET(uint32_t fetchdat) if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { if (cr4 & CR4_VME) { - uint16_t new_pc, new_cs, new_flags; + uint16_t new_pc; + uint16_t new_cs; + uint16_t new_flags; new_pc = readmemw(ss, SP); new_cs = readmemw(ss, ((SP + 2) & 0xffff)); @@ -208,7 +210,7 @@ opIRET(uint32_t fetchdat) else cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); + op_loadcs(new_cs); cpu_state.pc = new_pc; cycles -= timing_iret_rm; @@ -219,7 +221,7 @@ opIRET(uint32_t fetchdat) } else { if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -235,7 +237,7 @@ opIRET(uint32_t fetchdat) cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } } @@ -260,7 +262,7 @@ opIRETD(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(1); + op_pmodeiret(1); optype = 0; } else { uint16_t new_cs; @@ -278,7 +280,7 @@ opIRETD(uint32_t fetchdat) cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); SP += 12; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); diff --git a/src/cpu/x86_ops_ret_2386.h b/src/cpu/x86_ops_ret_2386.h new file mode 100644 index 0000000000..ca85bf2b06 --- /dev/null +++ b/src/cpu/x86_ops_ret_2386.h @@ -0,0 +1,297 @@ +#ifdef USE_NEW_DYNAREC +# define CPU_SET_OXPC +#else +# define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + +#define RETF_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + op_pmoderetf(0, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmemw(ss, ESP); \ + op_loadcs(readmemw(ss, ESP + 2)); \ + } else { \ + cpu_state.pc = readmemw(ss, SP); \ + op_loadcs(readmemw(ss, SP + 2)); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 4 + stack_offset; \ + else \ + SP += 4 + stack_offset; \ + cycles -= timing_retf_rm; + +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + op_pmoderetf(1, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmeml(ss, ESP); \ + op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + } else { \ + cpu_state.pc = readmeml(ss, SP); \ + op_loadcs(readmeml(ss, SP + 4) & 0xffff); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 8 + stack_offset; \ + else \ + SP += 8 + stack_offset; \ + cycles -= timing_retf_rm; + +static int +opRETF_a16(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a16(0); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRETF_a32(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a32(0); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRETF_a16_imm(uint32_t fetchdat) +{ + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a16(offset); + + PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRETF_a32_imm(uint32_t fetchdat) +{ + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); + + CPU_BLOCK_END(); + RETF_a32(offset); + + PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; +} + +static int +opIRET_186(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET_286(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t new_pc; + uint16_t new_cs; + uint16_t new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) + return 1; + + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); + return 1; + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + op_loadcs(new_cs); + cpu_state.pc = new_pc; + + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + op_pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRETD(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + op_pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); + SP += 12; + } + op_loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + rf_flag_no_clear = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index 30c076a6ed..75caa4491d 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -36,4 +36,4 @@ opSET(L) opSET(NL) opSET(LE) opSET(NLE) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index 9c11a32f01..1394cf4209 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -605,7 +605,8 @@ opC0_a16(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -624,7 +625,8 @@ opC0_a32(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -643,7 +645,8 @@ opC1_w_a16(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -662,7 +665,8 @@ opC1_w_a32(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -681,7 +685,8 @@ opC1_l_a16(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -700,7 +705,8 @@ opC1_l_a32(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -720,7 +726,8 @@ opD0_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -736,7 +743,8 @@ opD0_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -752,7 +760,8 @@ opD1_w_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -768,7 +777,8 @@ opD1_w_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -784,7 +794,8 @@ opD1_l_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -800,7 +811,8 @@ opD1_l_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -817,7 +829,8 @@ opD2_a16(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -834,7 +847,8 @@ opD2_a32(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -851,7 +865,8 @@ opD3_w_a16(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -868,7 +883,8 @@ opD3_w_a32(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -885,7 +901,8 @@ opD3_l_a16(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -902,7 +919,8 @@ opD3_l_a32(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -1053,4 +1071,4 @@ opSHxD(SHLD_w) opSHxD(SHLD_l) opSHxD(SHRD_w) opSHxD(SHRD_l) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 8217a9e5a1..fbf603ddbe 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -189,22 +189,50 @@ static int opPOPA_l(uint32_t fetchdat) { if (stack32) { - EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; + EDI = readmeml(ss, ESP); + if (cpu_state.abrt) + return 1; + ESI = readmeml(ss, ESP + 4); + if (cpu_state.abrt) + return 1; + EBP = readmeml(ss, ESP + 8); + if (cpu_state.abrt) + return 1; + EBX = readmeml(ss, ESP + 16); + if (cpu_state.abrt) + return 1; + EDX = readmeml(ss, ESP + 20); + if (cpu_state.abrt) + return 1; + ECX = readmeml(ss, ESP + 24); + if (cpu_state.abrt) + return 1; + EAX = readmeml(ss, ESP + 28); + if (cpu_state.abrt) + return 1; ESP += 32; } else { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; + EDI = readmeml(ss, ((SP) &0xFFFF)); + if (cpu_state.abrt) + return 1; + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); + if (cpu_state.abrt) + return 1; SP += 32; } CLOCK_CYCLES((is486) ? 9 : 24); @@ -379,9 +407,13 @@ opENTER_w(uint32_t fetchdat) { uint16_t offset; int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint32_t tempEBP; + uint32_t tempESP; + uint32_t frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0; + int writes = 1; + int instr_cycles = 0; #endif uint16_t tempw; @@ -448,9 +480,13 @@ opENTER_l(uint32_t fetchdat) { uint16_t offset; int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint32_t tempEBP; + uint32_t tempESP; + uint32_t frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0; + int writes = 1; + int instr_cycles = 0; #endif uint32_t templ; @@ -574,7 +610,7 @@ opLEAVE_l(uint32_t fetchdat) temp_seg = POP_W(); \ if (cpu_state.abrt) \ return 1; \ - loadseg(temp_seg, realseg); \ + op_loadseg(temp_seg, realseg); \ if (cpu_state.abrt) \ ESP = temp_esp; \ CLOCK_CYCLES(is486 ? 3 : 7); \ @@ -588,7 +624,7 @@ opLEAVE_l(uint32_t fetchdat) temp_seg = POP_L(); \ if (cpu_state.abrt) \ return 1; \ - loadseg(temp_seg & 0xffff, realseg); \ + op_loadseg(temp_seg & 0xffff, realseg); \ if (cpu_state.abrt) \ ESP = temp_esp; \ CLOCK_CYCLES(is486 ? 3 : 7); \ @@ -615,7 +651,7 @@ opPOP_SS_w(uint32_t fetchdat) temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); + op_loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; @@ -631,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } @@ -643,7 +683,7 @@ opPOP_SS_l(uint32_t fetchdat) temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + op_loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; @@ -659,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat) cpu_state.pc++; if (cpu_state.abrt) return 1; +#ifdef OPS_286_386 + x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#else x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +#endif return 1; } diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index c9ba947605..619386fcb1 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -219,7 +219,8 @@ opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; addr64 = addr64_2 = 0x00000000; @@ -259,7 +260,8 @@ opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; addr64 = addr64_2 = 0x00000000; @@ -300,7 +302,8 @@ opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; addr64a[0] = addr64a[1] = 0x00000000; addr64a_2[0] = addr64a_2[1] = 0x00000000; @@ -341,7 +344,8 @@ opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; addr64a[0] = addr64a[1] = 0x00000000; addr64a_2[0] = addr64a_2[1] = 0x00000000; @@ -383,7 +387,8 @@ opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; @@ -424,7 +429,8 @@ opCMPSL_a16(uint32_t fetchdat) static int opCMPSL_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; diff --git a/src/cpu/x86_ops_string_2386.h b/src/cpu/x86_ops_string_2386.h new file mode 100644 index 0000000000..98875e54fb --- /dev/null +++ b/src/cpu/x86_ops_string_2386.h @@ -0,0 +1,1061 @@ +static int +opMOVSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + + do_mmut_wb(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, DI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opMOVSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_wb(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, EDI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opMOVSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_ww(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opMOVSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_ww(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opMOVSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_wl(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opMOVSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_wl(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); + return 0; +} + +static int +opCMPSB_a16(uint32_t fetchdat) +{ + uint8_t src; + uint8_t dst; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI); + CHECK_READ(&cpu_state.seg_es, DI, DI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_rb2(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + dst = readmemb_n(es, DI, addr64_2); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; +} +static int +opCMPSB_a32(uint32_t fetchdat) +{ + uint8_t src; + uint8_t dst; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_rb2(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + dst = readmemb_n(es, EDI, addr64_2); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; +} + +static int +opCMPSW_a16(uint32_t fetchdat) +{ + uint16_t src; + uint16_t dst; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rw2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmemw_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; +} +static int +opCMPSW_a32(uint32_t fetchdat) +{ + uint16_t src; + uint16_t dst; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rw2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmemw_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; +} + +static int +opCMPSL_a16(uint32_t fetchdat) +{ + uint32_t src; + uint32_t dst; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rl2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmeml_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); + return 0; +} +static int +opCMPSL_a32(uint32_t fetchdat) +{ + uint32_t src; + uint32_t dst; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rl2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmeml_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); + return 0; +} + +static int +opSTOSB_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; +} +static int +opSTOSB_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; +} + +static int +opSTOSW_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; +} +static int +opSTOSW_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; +} + +static int +opSTOSL_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; +} +static int +opSTOSL_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); + return 0; +} + +static int +opLODSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opLODSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opLODSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opLODSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opLODSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opLODSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opSCASB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opSCASB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opSCASW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opSCASW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opSCASL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opSCASL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opINSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 1); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_wb(es, DI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, DI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opINSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 1); + high_page = 0; + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, EDI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opINSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 2); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_ww(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opINSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; + check_io_perm(DX, 2); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opINSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 4); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opINSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 4); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); + return 0; +} + +static int +opOUTSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 1); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opOUTSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 1); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opOUTSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 2); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opOUTSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 2); + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opOUTSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 4); + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opOUTSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 4); + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 1); + return 0; +} diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index c5ce08999b..70e7be58c3 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -275,4 +275,4 @@ opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) -// clang-format on + // clang-format on diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 7f630275cd..c50c97a399 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -31,18 +31,30 @@ #include <86box/machine.h> #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_flags.h" +#include "x86seg.h" +#include "x86seg_common.h" #include "386_common.h" -uint8_t opcode2; - -int cgate16, cgate32; -int intgatesize; - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); - -void pmodeint(int num, int soft); +#ifdef OPS_286_386 +#define seg_readmembl readmembl_2386 +#define seg_readmemwl readmemwl_2386 +#define seg_readmemll readmemll_2386 +#define seg_writemembl writemembl_2386 +#define seg_writememwl writememwl_2386 +#define seg_writememll writememll_2386 +#else +#define seg_readmembl readmembl_2386 +#define seg_readmemwl readmemwl_2386 +#define seg_readmemll readmemll_2386 +#define seg_writemembl writemembl_2386 +#define seg_writememwl writememwl_2386 +#define seg_writememll writememll_2386 +#endif #define DPL ((segdat[2] >> 13) & 3) #define DPL2 ((segdat2[2] >> 13) & 3) @@ -66,41 +78,16 @@ x86seg_log(const char *fmt, ...) # define x86seg_log(fmt, ...) #endif -static void -seg_reset(x86seg *s) -{ - s->access = 0x82; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; - s->limit_high = 0xffff; - if (s == &cpu_state.seg_cs) { - if (!cpu_inited) - fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); - if (is6117) - s->base = 0x03ff0000; - else - s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; - s->seg = is286 ? 0xf000 : 0xffff; - } else { - s->base = 0; - s->seg = 0; - } -} - -void -x86seg_reset(void) -{ - seg_reset(&cpu_state.seg_cs); - seg_reset(&cpu_state.seg_ds); - seg_reset(&cpu_state.seg_es); - seg_reset(&cpu_state.seg_fs); - seg_reset(&cpu_state.seg_gs); - seg_reset(&cpu_state.seg_ss); -} +#ifdef USE_DYNAREC +extern int cpu_block_end; +#endif void +#ifdef OPS_286_386 +x86_doabrt_2386(int x86_abrt) +#else x86_doabrt(int x86_abrt) +#endif { #ifndef USE_NEW_DYNAREC CS = oldcs; @@ -110,7 +97,7 @@ x86_doabrt(int x86_abrt) cpu_state.seg_cs.ar_high = 0x10; if (msw & 1) - pmodeint(x86_abrt, 0); + op_pmodeint(x86_abrt, 0); else { uint32_t addr = (x86_abrt << 2) + idt.base; if (stack32) { @@ -130,7 +117,7 @@ x86_doabrt(int x86_abrt) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + op_loadcs(readmemw(0, addr + 2)); return; } @@ -156,52 +143,6 @@ x86_doabrt(int x86_abrt) } } -void -x86de(char *s, uint16_t error) -{ -#ifdef BAD_CODE - cpu_state.abrt = ABRT_DE; - abrt_error = error; -#else - x86_int(0); -#endif -} - -void -x86gpf(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_GPF; - abrt_error = error; -} - -void -x86gpf_expected(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; -} - -void -x86ss(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_SS; - abrt_error = error; -} - -void -x86ts(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_TS; - abrt_error = error; -} - -void -x86np(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_NP; - abrt_error = error; -} - static void set_stack32(int s) { @@ -224,6 +165,7 @@ set_use32(int u) cpu_cur_status &= ~CPU_STATUS_USE32; } +#ifndef OPS_286_386 void do_seg_load(x86seg *s, uint16_t *segdat) { @@ -258,6 +200,7 @@ do_seg_load(x86seg *s, uint16_t *segdat) cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } +#endif static void do_seg_v86_init(x86seg *s) @@ -272,9 +215,9 @@ do_seg_v86_init(x86seg *s) static void check_seg_valid(x86seg *s) { - int dpl = (s->access >> 5) & 3; - int valid = 1; - x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; + int dpl = (s->access >> 5) & 3; + int valid = 1; + const x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) valid = 0; @@ -306,7 +249,7 @@ check_seg_valid(x86seg *s) } if (!valid) - loadseg(0, s); + op_loadseg(0, s); } static void @@ -332,12 +275,17 @@ int #else void #endif +#ifdef OPS_286_386 +loadseg_2386(uint16_t seg, x86seg *s) +#else loadseg(uint16_t seg, x86seg *s) +#endif { - uint16_t segdat[4]; - uint32_t addr, *segdat32 = (uint32_t *) segdat; - int dpl; - x86seg *dt; + uint16_t segdat[4]; + uint32_t addr; + uint32_t *segdat32 = (uint32_t *) segdat; + int dpl; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { if (!(seg & 0xfffc)) { @@ -529,11 +477,16 @@ loadseg(uint16_t seg, x86seg *s) } void +#ifdef OPS_286_386 +loadcs_2386(uint16_t seg) +#else loadcs(uint16_t seg) +#endif { - uint16_t segdat[4]; - uint32_t addr, *segdat32 = (uint32_t *) segdat; - x86seg *dt; + uint16_t segdat[4]; + uint32_t addr; + uint32_t *segdat32 = (uint32_t *) segdat; + const x86seg *dt; x86seg_log("Load CS %04X\n", seg); @@ -617,13 +570,19 @@ loadcs(uint16_t seg) } void +#ifdef OPS_286_386 +loadcsjmp_2386(uint16_t seg, uint32_t old_pc) +#else loadcsjmp(uint16_t seg, uint32_t old_pc) +#endif { - uint16_t type, seg2; - uint16_t segdat[4]; - uint32_t addr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; - x86seg *dt; + uint16_t type; + uint16_t seg2; + uint16_t segdat[4]; + uint32_t addr; + uint32_t newpc; + uint32_t *segdat32 = (uint32_t *) segdat; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { if (!(seg & 0xfffc)) { @@ -743,7 +702,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -775,7 +734,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) cpu_state.pc = old_pc; optype = JMP; cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x800); + op_taskswitch286(seg, segdat, segdat[2] & 0x800); cpu_state.flags &= ~NT_FLAG; cpl_override = 0; return; @@ -802,7 +761,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) } } -void +static void PUSHW(uint16_t v) { if (stack32) { @@ -818,7 +777,7 @@ PUSHW(uint16_t v) } } -void +static void PUSHL(uint32_t v) { if (cpu_16bitbus) { @@ -839,7 +798,7 @@ PUSHL(uint32_t v) } } -uint16_t +static uint16_t POPW(void) { uint16_t tempw; @@ -857,7 +816,7 @@ POPW(void) return tempw; } -uint32_t +static uint32_t POPL(void) { uint32_t templ; @@ -882,6 +841,15 @@ POPL(void) return templ; } +#ifdef OPS_286_386 +#ifdef USE_NEW_DYNAREC +void +loadcscall_2386(uint16_t seg, uint32_t old_pc) +#else +void +loadcscall_2386(uint16_t seg) +#endif +#else #ifdef USE_NEW_DYNAREC void loadcscall(uint16_t seg, uint32_t old_pc) @@ -889,17 +857,26 @@ loadcscall(uint16_t seg, uint32_t old_pc) void loadcscall(uint16_t seg) #endif +#endif { - uint16_t seg2, newss; - uint16_t segdat[4], segdat2[4]; - uint32_t addr, oldssbase = ss; - uint32_t oaddr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - int count, type; - uint32_t oldss, oldsp, newsp, oldsp2; - uint16_t tempw; - x86seg *dt; + uint16_t seg2; + uint16_t newss; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint32_t addr; + uint32_t oldssbase = ss; + uint32_t oaddr; + uint32_t newpc; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + int count; + int type; + uint32_t oldss; + uint32_t oldsp; + uint32_t newsp; + uint32_t oldsp2; + uint16_t tempw; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { x86seg_log("Protected mode CS load! %04X\n", seg); @@ -1174,7 +1151,7 @@ loadcscall(uint16_t seg) x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -1209,7 +1186,7 @@ loadcscall(uint16_t seg) cpu_state.pc = oxpc; #endif cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x0800); + op_taskswitch286(seg, segdat, segdat[2] & 0x0800); cpl_override = 0; break; @@ -1235,14 +1212,24 @@ loadcscall(uint16_t seg) } void +#ifdef OPS_286_386 +pmoderetf_2386(int is32, uint16_t off) +#else pmoderetf(int is32, uint16_t off) +#endif { - uint16_t segdat[4], segdat2[4], seg, newss; - uint32_t newpc, newsp, addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t seg; + uint16_t newss; + uint32_t newpc; + uint32_t newsp; + uint32_t addr; + uint32_t oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); if (is32) { @@ -1465,19 +1452,28 @@ pmoderetf(int is32, uint16_t off) } void +#ifdef OPS_286_386 +pmodeint_2386(int num, int soft) +#else pmodeint(int num, int soft) +#endif { - uint16_t segdat[4], segdat2[4]; - uint16_t segdat3[4]; - uint16_t newss, seg = 0; - int type, new_cpl; - uint32_t addr, oaddr; - uint32_t oldss, oldsp; - uint32_t newsp; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - uint32_t *segdat332 = (uint32_t *) segdat3; - x86seg *dt; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t segdat3[4]; + uint16_t newss; + uint16_t seg = 0; + int type; + int new_cpl; + uint32_t addr; + uint32_t oaddr; + uint32_t oldss; + uint32_t oldsp; + uint32_t newsp; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + uint32_t *segdat332 = (uint32_t *) segdat3; + const x86seg *dt; if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) { x86seg_log("V86 banned int\n"); @@ -1491,7 +1487,7 @@ pmodeint(int num, int soft) softresetx86(); cpu_set_edx(); } else if (num == 0x0d) - pmodeint(8, 0); + op_pmodeint(8, 0); else x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); x86seg_log("addr >= IDT.limit\n"); @@ -1632,10 +1628,10 @@ pmodeint(int num, int soft) PUSHL(ES); if (cpu_state.abrt) return; - loadseg(0, &cpu_state.seg_ds); - loadseg(0, &cpu_state.seg_es); - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); + op_loadseg(0, &cpu_state.seg_ds); + op_loadseg(0, &cpu_state.seg_es); + op_loadseg(0, &cpu_state.seg_fs); + op_loadseg(0, &cpu_state.seg_gs); } PUSHL(oldss); PUSHL(oldsp); @@ -1661,7 +1657,7 @@ pmodeint(int num, int soft) x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -1737,7 +1733,7 @@ pmodeint(int num, int soft) } optype = OPTYPE_INT; cpl_override = 1; - taskswitch286(seg, segdat2, segdat2[2] & 0x0800); + op_taskswitch286(seg, segdat2, segdat2[2] & 0x0800); cpl_override = 0; break; @@ -1748,18 +1744,27 @@ pmodeint(int num, int soft) } void +#ifdef OPS_286_386 +pmodeiret_2386(int is32) +#else pmodeiret(int is32) +#endif { - uint16_t newss, seg = 0; - uint16_t segdat[4], segdat2[4]; - uint16_t segs[4]; - uint32_t tempflags, flagmask; - uint32_t newpc, newsp; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t newss; + uint16_t seg = 0; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t segs[4]; + uint32_t tempflags; + uint32_t flagmask; + uint32_t newpc; + uint32_t newsp; + uint32_t addr; + uint32_t oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; if (is386 && (cpu_state.eflags & VM_FLAG)) { if (IOPL != 3) { @@ -1795,7 +1800,9 @@ pmodeiret(int is32) } if (cpu_state.flags & NT_FLAG) { + cpl_override = 1; seg = readmemw(tr.base, 0); + cpl_override = 0; addr = seg & 0xfff8; if (seg & 0x0004) { x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); @@ -1808,9 +1815,9 @@ pmodeiret(int is32) } addr += gdt.base; } - cpl_override = 1; read_descriptor(addr, segdat, segdat32, 1); - taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 1; + op_taskswitch286(seg, segdat, segdat[2] & 0x0800); cpl_override = 0; return; } @@ -1844,14 +1851,14 @@ pmodeiret(int is32) } cpu_state.eflags = tempflags >> 16; cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); + op_loadseg(segs[0], &cpu_state.seg_es); do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1], &cpu_state.seg_ds); + op_loadseg(segs[1], &cpu_state.seg_ds); do_seg_v86_init(&cpu_state.seg_ds); cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2], &cpu_state.seg_fs); + op_loadseg(segs[2], &cpu_state.seg_fs); do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); + op_loadseg(segs[3], &cpu_state.seg_gs); do_seg_v86_init(&cpu_state.seg_gs); cpu_state.pc = newpc & 0xffff; @@ -1869,7 +1876,7 @@ pmodeiret(int is32) #endif ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); + op_loadseg(newss, &cpu_state.seg_ss); do_seg_v86_init(&cpu_state.seg_ss); cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32 = 0; @@ -2056,17 +2063,39 @@ pmodeiret(int is32) } void +#ifdef OPS_286_386 +taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32) +#else taskswitch286(uint16_t seg, uint16_t *segdat, int is32) +#endif { - uint16_t tempw, new_ldt; - uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; - uint16_t segdat2[4]; - uint32_t base, limit; - uint32_t templ, new_cr3 = 0; - uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; - uint32_t new_esi, new_edi, new_pc, new_flags, addr; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t tempw; + uint16_t new_ldt; + uint16_t new_es; + uint16_t new_cs; + uint16_t new_ss; + uint16_t new_ds; + uint16_t new_fs; + uint16_t new_gs; + uint16_t segdat2[4]; + uint32_t base; + uint32_t limit; + uint32_t templ; + uint32_t new_cr3 = 0; + uint32_t new_eax; + uint32_t new_ebx; + uint32_t new_ecx; + uint32_t new_edx; + uint32_t new_esp; + uint32_t new_ebp; + uint32_t new_esi; + uint32_t new_edi; + uint32_t new_pc; + uint32_t new_flags; + uint32_t t_bit; + uint32_t addr; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; @@ -2165,6 +2194,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_fs = readmemw(base, 0x58); new_gs = readmemw(base, 0x5C); new_ldt = readmemw(base, 0x60); + t_bit = readmemb(base, 0x64) & 1; cr0 |= 8; @@ -2186,7 +2216,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); if (cpu_state.eflags & VM_FLAG) { - loadcs(new_cs); + op_loadcs(new_cs); set_use32(0); cpu_cur_status |= CPU_STATUS_V86; } else { @@ -2250,11 +2280,24 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ESI = new_esi; EDI = new_edi; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - loadseg(new_fs, &cpu_state.seg_fs); - loadseg(new_gs, &cpu_state.seg_gs); + op_loadseg(new_es, &cpu_state.seg_es); + op_loadseg(new_ss, &cpu_state.seg_ss); + op_loadseg(new_ds, &cpu_state.seg_ds); + op_loadseg(new_fs, &cpu_state.seg_fs); + op_loadseg(new_gs, &cpu_state.seg_gs); + + if (!cpu_use_exec) + rf_flag_no_clear = 1; + + if (t_bit) { + if (cpu_use_exec) + trap = 2; + else + trap |= 2; +#ifdef USE_DYNAREC + cpu_block_end = 1; +#endif + } } else { if (limit < 43) { x86ts(NULL, seg); @@ -2416,12 +2459,12 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ESI = new_esi | 0xffff0000; EDI = new_edi | 0xffff0000; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); + op_loadseg(new_es, &cpu_state.seg_es); + op_loadseg(new_ss, &cpu_state.seg_ss); + op_loadseg(new_ds, &cpu_state.seg_ds); if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); + op_loadseg(0, &cpu_state.seg_fs); + op_loadseg(0, &cpu_state.seg_gs); } } @@ -2430,10 +2473,16 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.limit = limit; tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; + if (!cpu_use_exec) + dr[7] &= 0xFFFFFFAA; } void +#ifdef OPS_286_386 +cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg) +#else cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) +#endif { uint32_t limit_raw = seg->limit; @@ -2445,9 +2494,14 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) } void +#ifdef OPS_286_386 +cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg) +#else cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) +#endif { - uint16_t segdat[4], selector; + uint16_t segdat[4]; + uint16_t selector; segdat[0] = readmemw(0, addr); segdat[1] = readmemw(0, addr + 2); diff --git a/src/cpu/x86seg.h b/src/cpu/x86seg.h index 715251f2d5..dcc8c9ef85 100644 --- a/src/cpu/x86seg.h +++ b/src/cpu/x86seg.h @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * x86 CPU segment emulation. + * x86 CPU segment emulation header. * * * @@ -14,8 +14,82 @@ * * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_X86SEG_H +#define EMU_X86SEG_H -extern void do_seg_load(x86seg *s, uint16_t *segdat); +#ifdef OPS_286_386 + +extern void x86_doabrt_2386(int x86_abrt); +#ifdef USE_NEW_DYNAREC +extern int loadseg_2386(uint16_t seg, x86seg *s); +#else +extern void loadseg_2386(uint16_t seg, x86seg *s); +#endif +extern void loadcs_2386(uint16_t seg); +extern void loadcsjmp_2386(uint16_t seg, uint32_t old_pc); +#ifdef USE_NEW_DYNAREC +extern void loadcscall_2386(uint16_t seg, uint32_t old_pc); +#else +extern void loadcscall_2386(uint16_t seg); +#endif +extern void pmoderetf_2386(int is32, uint16_t off); +extern void pmodeint_2386(int num, int soft); +extern void pmodeiret_2386(int is32); +extern void taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32); + +/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */ +#define op_doabrt x86_doabrt_2386 +#define op_loadseg loadseg_2386 +#define op_loadcs loadcs_2386 +#define op_loadcsjmp loadcsjmp_2386 +#define op_loadcscall loadcscall_2386 +#define op_pmoderetf pmoderetf_2386 +#define op_pmodeint pmodeint_2386 +#define op_pmodeiret pmodeiret_2386 +#define op_taskswitch taskswitch_2386 +#define op_taskswitch286 taskswitch286_2386 + +#else + +extern void x86_doabrt(int x86_abrt); +#ifdef USE_NEW_DYNAREC +extern int loadseg(uint16_t seg, x86seg *s); +#else +extern void loadseg(uint16_t seg, x86seg *s); +#endif +/* The prototype of loadcs_2386() is needed here for reset. */ +extern void loadcs_2386(uint16_t seg); +extern void loadcs(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +#else +extern void loadcscall(uint16_t seg); +#endif +extern void pmoderetf(int is32, uint16_t off); +/* The prototype of pmodeint_2386() is needed here for 386_common.c interrupts. */ +extern void pmodeint_2386(int num, int soft); +extern void pmodeint(int num, int soft); +extern void pmodeiret(int is32); +extern void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); + +/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */ +#define op_doabrt x86_doabrt +#define op_loadseg loadseg +#define op_loadcs loadcs +#define op_loadcsjmp loadcsjmp +#define op_loadcscall loadcscall +#define op_pmoderetf pmoderetf +#define op_pmodeint pmodeint +#define op_pmodeiret pmodeiret +#define op_taskswitch286 taskswitch286 + +#endif + +extern void cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg); +extern void cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg); extern void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); extern void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg); + +#endif /*EMU_X86SEG_H*/ diff --git a/src/include/86box/net_plip.h b/src/cpu/x86seg_2386.c similarity index 50% rename from src/include/86box/net_plip.h rename to src/cpu/x86seg_2386.c index 83c33e4c67..335c757e4a 100644 --- a/src/include/86box/net_plip.h +++ b/src/cpu/x86seg_2386.c @@ -6,21 +6,17 @@ * * This file is part of the 86Box distribution. * - * Definitions for the PLIP parallel port network device. + * x86 CPU segment emulation for the 286/386 interpreter. * * * - * Authors: RichardG, + * Authors: Sarah Walker, + * Miran Grca, * - * Copyright 2020 RichardG. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ - -#ifndef NET_PLIP_H -#define NET_PLIP_H -#include <86box/device.h> -#include <86box/lpt.h> - -extern const lpt_device_t lpt_plip_device; -extern const device_t plip_device; - -#endif /*NET_PLIP_H*/ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/cpu/x86seg_common.c b/src/cpu/x86seg_common.c new file mode 100644 index 0000000000..12b698b1ad --- /dev/null +++ b/src/cpu/x86seg_common.c @@ -0,0 +1,129 @@ +/* + * 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. + * + * x86 CPU segment emulation commmon parts. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include "x86seg_common.h" +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + +uint8_t opcode2; + +int cgate16; +int cgate32; + +int intgatesize; + +static void +seg_reset(x86seg *s) +{ + s->access = 0x82; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; + s->limit_high = 0xffff; + if (s == &cpu_state.seg_cs) { + if (!cpu_inited) + fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); + if (is6117) + s->base = 0x03ff0000; + else + s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; + s->seg = is286 ? 0xf000 : 0xffff; + } else { + s->base = 0; + s->seg = 0; + } +} + +void +x86seg_reset(void) +{ + seg_reset(&cpu_state.seg_cs); + seg_reset(&cpu_state.seg_ds); + seg_reset(&cpu_state.seg_es); + seg_reset(&cpu_state.seg_fs); + seg_reset(&cpu_state.seg_gs); + seg_reset(&cpu_state.seg_ss); +} + +void +x86de(UNUSED(char *s), UNUSED(uint16_t error)) +{ +#ifdef BAD_CODE + cpu_state.abrt = ABRT_DE; + abrt_error = error; +#else + x86_int(0); +#endif +} + +void +x86gen(void) +{ + x86_int(1); +} + +void +x86gpf(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_GPF; + abrt_error = error; +} + +void +x86gpf_expected(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; + abrt_error = error; +} + +void +x86ss(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_SS; + abrt_error = error; +} + +void +x86ts(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_TS; + abrt_error = error; +} + +void +x86np(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_NP; + abrt_error = error; +} diff --git a/src/cpu/x86seg_common.h b/src/cpu/x86seg_common.h new file mode 100644 index 0000000000..9f90493225 --- /dev/null +++ b/src/cpu/x86seg_common.h @@ -0,0 +1,53 @@ +/* + * 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. + * + * x86 CPU segment emulation common parts header. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_X86SEG_COMMON_H +#define EMU_X86SEG_COMMON_H + +#define JMP 1 +#define CALL 2 +#define IRET 3 +#define OPTYPE_INT 4 + +enum { + ABRT_NONE = 0, + ABRT_GEN = 1, + ABRT_TS = 0xA, + ABRT_NP = 0xB, + ABRT_SS = 0xC, + ABRT_GPF = 0xD, + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ +}; + +extern uint8_t opcode2; + +extern int cgate16; +extern int cgate32; + +extern int intgatesize; + +extern void x86seg_reset(void); +extern void x86gen(void); +extern void x86de(char *s, uint16_t error); +extern void x86gpf(char *s, uint16_t error); +extern void x86gpf_expected(char *s, uint16_t error); +extern void x86np(char *s, uint16_t error); +extern void x86ss(char *s, uint16_t error); +extern void x86ts(char *s, uint16_t error); +extern void do_seg_load(x86seg *s, uint16_t *segdat); + +#endif /*EMU_X86SEG_COMMON_H*/ diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 98ceb105bc..1f7643453e 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -13,12 +13,15 @@ #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "softfloat/softfloat-specialize.h" -uint32_t x87_pc_off, x87_op_off; -uint16_t x87_pc_seg, x87_op_seg; +uint32_t x87_pc_off; +uint32_t x87_op_off; +uint16_t x87_pc_seg; +uint16_t x87_op_seg; #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; @@ -43,9 +46,8 @@ uint16_t x87_gettag(void) { uint16_t ret = 0; - int c; - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { if (cpu_state.tag[c] == TAG_EMPTY) ret |= X87_TAG_EMPTY << (c * 2); else if (cpu_state.tag[c] & TAG_UINT64) @@ -62,9 +64,7 @@ x87_gettag(void) void x87_settag(uint16_t new_tag) { - int c; - - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { int tag = (new_tag >> (c * 2)) & 3; if (tag == X87_TAG_EMPTY) @@ -106,7 +106,6 @@ x87_settag(uint16_t new_tag) } #endif - static floatx80 FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct float_status_t *status) { @@ -119,24 +118,27 @@ FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct fl // propagate QNaN to SNaN a = propagateFloatx80NaNOne(a, status); - if (aIsNaN & !bIsNaN) return a; + if (aIsNaN & !bIsNaN) + return a; // float32 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags floatx80 b = float32_to_floatx80(b32, status); if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; + if (bIsSignalingNaN) + goto returnLargerSignificand; return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN) return a; - returnLargerSignificand: - if (a.fraction < b.fraction) return b; - if (b.fraction < a.fraction) return a; + } else if (aIsNaN) { + if (bIsSignalingNaN) + return a; +returnLargerSignificand: + if (a.fraction < b.fraction) + return b; + if (b.fraction < a.fraction) + return a; return (a.exp < b.exp) ? a : b; - } - else { + } else { return b; } } @@ -152,7 +154,8 @@ FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *stat return 1; } - int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b); + int aIsNaN = floatx80_is_nan(a); + int bIsNaN = float32_is_nan(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN32_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -172,24 +175,27 @@ FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct fl // propagate QNaN to SNaN a = propagateFloatx80NaNOne(a, status); - if (aIsNaN & !bIsNaN) return a; + if (aIsNaN & !bIsNaN) + return a; // float64 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags floatx80 b = float64_to_floatx80(b64, status); if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; + if (bIsSignalingNaN) + goto returnLargerSignificand; return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN) return a; - returnLargerSignificand: - if (a.fraction < b.fraction) return b; - if (b.fraction < a.fraction) return a; + } else if (aIsNaN) { + if (bIsSignalingNaN) + return a; +returnLargerSignificand: + if (a.fraction < b.fraction) + return b; + if (b.fraction < a.fraction) + return a; return (a.exp < b.exp) ? a : b; - } - else { + } else { return b; } } @@ -205,7 +211,8 @@ FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *stat return 1; } - int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b); + int aIsNaN = floatx80_is_nan(a); + int bIsNaN = float64_is_nan(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN64_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -217,7 +224,7 @@ struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word) { struct float_status_t status; - int precision = control_word & FPU_CW_PC; + int precision = control_word & FPU_CW_PC; switch (precision) { case FPU_PR_32_BITS: @@ -230,24 +237,23 @@ i387cw_to_softfloat_status_word(uint16_t control_word) status.float_rounding_precision = 80; break; default: - /* With the precision control bits set to 01 "(reserved)", a - real CPU behaves as if the precision control bits were - set to 11 "80 bits" */ + /* With the precision control bits set to 01 "(reserved)", a + real CPU behaves as if the precision control bits were + set to 11 "80 bits" */ status.float_rounding_precision = 80; break; } - status.float_exception_flags = 0; // clear exceptions before execution - status.float_nan_handling_mode = float_first_operand_nan; - status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10; - status.flush_underflow_to_zero = 0; + status.float_exception_flags = 0; // clear exceptions before execution + status.float_nan_handling_mode = float_first_operand_nan; + status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10; + status.flush_underflow_to_zero = 0; status.float_suppress_exception = 0; - status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask; - status.denormals_are_zeros = 0; + status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask; + status.denormals_are_zeros = 0; return status; } - int FPU_status_word_flags_fpu_compare(int float_relation) { @@ -256,16 +262,16 @@ FPU_status_word_flags_fpu_compare(int float_relation) return (C0 | C2 | C3); case float_relation_greater: - return (0); + return 0; case float_relation_less: - return (C0); + return C0; case float_relation_equal: - return (C3); + return C3; } - return (-1); // should never get here + return (-1); // should never get here } void @@ -280,11 +286,11 @@ FPU_write_eflags_fpu_compare(int float_relation) break; case float_relation_less: - cpu_state.flags |= (C_FLAG); + cpu_state.flags |= C_FLAG; break; case float_relation_equal: - cpu_state.flags |= (Z_FLAG); + cpu_state.flags |= Z_FLAG; break; default: @@ -319,9 +325,9 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) fpu_state.swd |= exceptions; if (exceptions & FPU_SW_Stack_Fault) { if (!(exceptions & C1)) { - /* This bit distinguishes over- from underflow for a stack fault, - and roundup from round-down for precision loss. */ - fpu_state.swd &= ~C1; + /* This bit distinguishes over- from underflow for a stack fault, + and roundup from round-down for precision loss. */ + fpu_state.swd &= ~C1; } } return unmasked; @@ -354,8 +360,8 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) if (exceptions & FPU_EX_Precision) { if (!(exceptions & C1)) { - /* This bit distinguishes over- from underflow for a stack fault, - and roundup from round-down for precision loss. */ + /* This bit distinguishes over- from underflow for a stack fault, + and roundup from round-down for precision loss. */ fpu_state.swd &= ~C1; } } @@ -439,6 +445,87 @@ FPU_tagof(const floatx80 reg) return X87_TAG_VALID; } +uint8_t +pack_FPU_TW(uint16_t twd) +{ + uint8_t tag_byte = 0; + + if ((twd & 0x0003) != 0x0003) + tag_byte |= 0x01; + if ((twd & 0x000c) != 0x000c) + tag_byte |= 0x02; + if ((twd & 0x0030) != 0x0030) + tag_byte |= 0x04; + if ((twd & 0x00c0) != 0x00c0) + tag_byte |= 0x08; + if ((twd & 0x0300) != 0x0300) + tag_byte |= 0x10; + if ((twd & 0x0c00) != 0x0c00) + tag_byte |= 0x20; + if ((twd & 0x3000) != 0x3000) + tag_byte |= 0x40; + if ((twd & 0xc000) != 0xc000) + tag_byte |= 0x80; + + return tag_byte; +} + +uint16_t +unpack_FPU_TW(uint16_t tag_byte) +{ + uint32_t twd = 0; + + /* FTW + * + * Note that the original format for FTW can be recreated from the stored + * FTW valid bits and the stored 80-bit FP data (assuming the stored data + * was not the contents of MMX registers) using the following table: + + | Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW | + | all 1s | all 0s | all 0s | | | | + ------------------------------------------------------------------- + | 0 | 0 | 0 | 0x | 1 | S 10 | + | 0 | 0 | 0 | 1x | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 0 | 1 | 00 | 1 | S 10 | + | 0 | 0 | 1 | 10 | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 1 | 0 | 0x | 1 | S 10 | + | 0 | 1 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 0 | 1 | 1 | 00 | 1 | Z 01 | + | 0 | 1 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 0 | 1x | 1 | S 10 | + | 1 | 0 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 1 | 00 | 1 | S 10 | + | 1 | 0 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | all combinations above | 0 | E 11 | + + * + * The J-bit is defined to be the 1-bit binary integer to the left of + * the decimal place in the significand. + * + * The M-bit is defined to be the most significant bit of the fractional + * portion of the significand (i.e., the bit immediately to the right of + * the decimal place). When the M-bit is the most significant bit of the + * fractional portion of the significand, it must be 0 if the fraction + * is all 0's. + */ + + for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) { + if (tag_byte & 0x80) { + const floatx80 *fpu_reg = &fpu_state.st_space[index & 7]; + twd |= FPU_tagof(*fpu_reg); + } else { + twd |= X87_TAG_EMPTY; + } + } + + return (twd >> 2); +} #ifdef ENABLE_808X_LOG void diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 5d460bc4b1..f4e24f1ca6 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -3,16 +3,23 @@ #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 -extern uint32_t x87_pc_off, x87_op_off; -extern uint16_t x87_pc_seg, x87_op_seg; +extern uint32_t x87_pc_off; +extern uint32_t x87_op_off; +extern uint16_t x87_pc_seg; +extern uint16_t x87_op_seg; static __inline void x87_set_mmx(void) { uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *) cpu_state.tag; - *p = 0x0101010101010101ull; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } else { + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ULL; + } cpu_state.ismmx = 1; } @@ -20,8 +27,13 @@ static __inline void x87_emms(void) { uint64_t *p; - p = (uint64_t *) cpu_state.tag; - *p = 0; + if (fpu_softfloat) { + fpu_state.tag = 0xffff; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } else { + p = (uint64_t *) cpu_state.tag; + *p = 0; + } cpu_state.ismmx = 0; } @@ -48,99 +60,107 @@ void x87_settag(uint16_t new_tag); void codegen_set_rounding_mode(int mode); /* Status Word */ -#define FPU_SW_Backward (0x8000) /* backward compatibility */ -#define FPU_SW_C3 (0x4000) /* condition bit 3 */ -#define FPU_SW_Top (0x3800) /* top of stack */ -#define FPU_SW_C2 (0x0400) /* condition bit 2 */ -#define FPU_SW_C1 (0x0200) /* condition bit 1 */ -#define FPU_SW_C0 (0x0100) /* condition bit 0 */ -#define FPU_SW_Summary (0x0080) /* exception summary */ -#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ -#define FPU_SW_Precision (0x0020) /* loss of precision */ -#define FPU_SW_Underflow (0x0010) /* underflow */ -#define FPU_SW_Overflow (0x0008) /* overflow */ -#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ -#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ -#define FPU_SW_Invalid (0x0001) /* invalid operation */ - -#define C0 (1 << 8) -#define C1 (1 << 9) -#define C2 (1 << 10) -#define C3 (1 << 14) - -#define FPU_SW_CC (C0 | C1 | C2 | C3) - -#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ +#define FPU_SW_Backward (0x8000) /* backward compatibility */ +#define FPU_SW_C3 (0x4000) /* condition bit 3 */ +#define FPU_SW_Top (0x3800) /* top of stack */ +#define FPU_SW_C2 (0x0400) /* condition bit 2 */ +#define FPU_SW_C1 (0x0200) /* condition bit 1 */ +#define FPU_SW_C0 (0x0100) /* condition bit 0 */ +#define FPU_SW_Summary (0x0080) /* exception summary */ +#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ +#define FPU_SW_Precision (0x0020) /* loss of precision */ +#define FPU_SW_Underflow (0x0010) /* underflow */ +#define FPU_SW_Overflow (0x0008) /* overflow */ +#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ +#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ +#define FPU_SW_Invalid (0x0001) /* invalid operation */ + +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) + +#define FPU_SW_CC (C0 | C1 | C2 | C3) + +#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ /* Exception flags: */ -#define FPU_EX_Precision (0x0020) /* loss of precision */ -#define FPU_EX_Underflow (0x0010) /* underflow */ -#define FPU_EX_Overflow (0x0008) /* overflow */ -#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ -#define FPU_EX_Denormal (0x0002) /* denormalized operand */ -#define FPU_EX_Invalid (0x0001) /* invalid operation */ +#define FPU_EX_Precision (0x0020) /* loss of precision */ +#define FPU_EX_Underflow (0x0010) /* underflow */ +#define FPU_EX_Overflow (0x0008) /* overflow */ +#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ +#define FPU_EX_Denormal (0x0002) /* denormalized operand */ +#define FPU_EX_Invalid (0x0001) /* invalid operation */ /* Special exceptions: */ -#define FPU_EX_Stack_Overflow (0x0041| C1) /* stack overflow */ -#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ +#define FPU_EX_Stack_Overflow (0x0041 | C1) /* stack overflow */ +#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ /* precision control */ -#define FPU_EX_Precision_Lost_Up (EX_Precision | C1) -#define FPU_EX_Precision_Lost_Dn (EX_Precision) +#define FPU_EX_Precision_Lost_Up (EX_Precision | C1) +#define FPU_EX_Precision_Lost_Dn (EX_Precision) -#define setcc(cc) \ - fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) & FPU_SW_CC) +#define setcc(cc) \ + fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) &FPU_SW_CC) -#define clear_C1() { fpu_state.swd &= ~C1; } -#define clear_C2() { fpu_state.swd &= ~C2; } +#define clear_C1() \ + { \ + fpu_state.swd &= ~C1; \ + } +#define clear_C2() \ + { \ + fpu_state.swd &= ~C2; \ + } /* ************ */ /* Control Word */ /* ************ */ -#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ +#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ -#define FPU_CW_RC (0x0C00) /* rounding control */ -#define FPU_CW_PC (0x0300) /* precision control */ +#define FPU_CW_RC (0x0C00) /* rounding control */ +#define FPU_CW_PC (0x0300) /* precision control */ -#define FPU_RC_RND (0x0000) /* rounding control */ -#define FPU_RC_DOWN (0x0400) -#define FPU_RC_UP (0x0800) -#define FPU_RC_CHOP (0x0C00) +#define FPU_RC_RND (0x0000) /* rounding control */ +#define FPU_RC_DOWN (0x0400) +#define FPU_RC_UP (0x0800) +#define FPU_RC_CHOP (0x0C00) -#define FPU_CW_Precision (0x0020) /* loss of precision mask */ -#define FPU_CW_Underflow (0x0010) /* underflow mask */ -#define FPU_CW_Overflow (0x0008) /* overflow mask */ -#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ -#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ -#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ +#define FPU_CW_Precision (0x0020) /* loss of precision mask */ +#define FPU_CW_Underflow (0x0010) /* underflow mask */ +#define FPU_CW_Overflow (0x0008) /* overflow mask */ +#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ +#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ +#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ -#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ +#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ /* Precision control bits affect only the following: ADD, SUB(R), MUL, DIV(R), and SQRT */ -#define FPU_PR_32_BITS (0x000) -#define FPU_PR_RESERVED_BITS (0x100) -#define FPU_PR_64_BITS (0x200) -#define FPU_PR_80_BITS (0x300) +#define FPU_PR_32_BITS (0x000) +#define FPU_PR_RESERVED_BITS (0x100) +#define FPU_PR_64_BITS (0x200) +#define FPU_PR_80_BITS (0x300) #include "softfloat/softfloatx80.h" -static __inline const int +static __inline int is_IA_masked(void) { return (fpu_state.cwd & FPU_CW_Invalid); } struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word); -uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store); -int FPU_status_word_flags_fpu_compare(int float_relation); -void FPU_write_eflags_fpu_compare(int float_relation); -void FPU_stack_overflow(uint32_t fetchdat); -void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); -int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); -int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); -int FPU_tagof(const floatx80 reg); +uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store); +int FPU_status_word_flags_fpu_compare(int float_relation); +void FPU_write_eflags_fpu_compare(int float_relation); +void FPU_stack_overflow(uint32_t fetchdat); +void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); +int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); +int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); +int FPU_tagof(const floatx80 reg); +uint8_t pack_FPU_TW(uint16_t twd); +uint16_t unpack_FPU_TW(uint16_t tag_byte); static __inline uint16_t i387_get_control_word(void) @@ -167,7 +187,7 @@ static __inline void FPU_settagi_valid(int stnr) { int regnr = (stnr + fpu_state.tos) & 7; - fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00 + fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00 } static __inline void @@ -214,16 +234,15 @@ FPU_save_regi_tag(floatx80 reg, int tag, int stnr) FPU_settagi(tag, stnr); } - -#define FPU_check_pending_exceptions() \ -do { \ - if (fpu_state.swd & FPU_SW_Summary) { \ - if (cr0 & 0x20) { \ - x86_int(16); \ - return 1; \ - } else { \ - picint(1 << 13); \ - return 1; \ - } \ - } \ -} while (0) +#define FPU_check_pending_exceptions() \ + do { \ + if (fpu_state.swd & FPU_SW_Summary) { \ + if (cr0 & 0x20) { \ + x86_int(16); \ + return 1; \ + } else { \ + picint(1 << 13); \ + return 1; \ + } \ + } \ + } while (0) diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index e321df959b..1d9220255b 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -45,21 +45,20 @@ static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARD #define C2 (1 << 10) #define C3 (1 << 14) -#define X87_TAG_VALID 0 -#define X87_TAG_ZERO 1 -#define X87_TAG_INVALID 2 -#define X87_TAG_EMPTY 3 +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 +#define X87_TAG_INVALID 2 +#define X87_TAG_EMPTY 3 #define STATUS_ZERODIVIDE 4 -typedef union -{ +typedef union { double d; struct { - uint64_t mantissa:52; - uint64_t exponent:11; - uint64_t negative:1; + uint64_t mantissa : 52; + uint64_t exponent : 11; + uint64_t negative : 1; }; } double_decompose_t; @@ -111,6 +110,7 @@ typedef union static __inline void x87_checkexceptions(void) { + // } static __inline void @@ -169,12 +169,17 @@ x87_pop(void) static __inline int16_t x87_fround16(double b) { - int16_t a, c; + double da; + double dc; + int16_t a; + int16_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ - a = (int16_t) floor(b); - c = (int16_t) floor(b + 1.0); + da = floor(b); + dc = floor(b + 1.0); + a = (int16_t) da; + c = (int16_t) dc; if ((b - a) < (c - b)) return a; else if ((b - a) > (c - b)) @@ -182,9 +187,11 @@ x87_fround16(double b) else return (a & 1) ? c : a; case 1: /*Down*/ - return (int16_t) floor(b); + da = floor(b); + return (int16_t) da; case 2: /*Up*/ - return (int16_t) ceil(b); + da = ceil(b); + return (int16_t) da; case 3: /*Chop*/ return (int16_t) b; } @@ -201,12 +208,17 @@ x87_fround16_64(double b) static __inline int32_t x87_fround32(double b) { - int32_t a, c; + double da; + double dc; + int32_t a; + int32_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ - a = (int32_t) floor(b); - c = (int32_t) floor(b + 1.0); + da = floor(b); + dc = floor(b + 1.0); + a = (int32_t) da; + c = (int32_t) dc; if ((b - a) < (c - b)) return a; else if ((b - a) > (c - b)) @@ -214,9 +226,11 @@ x87_fround32(double b) else return (a & 1) ? c : a; case 1: /*Down*/ - return (int32_t) floor(b); + da = floor(b); + return (int32_t) da; case 2: /*Up*/ - return (int32_t) ceil(b); + da = ceil(b); + return (int32_t) da; case 3: /*Chop*/ return (int32_t) b; } @@ -233,12 +247,17 @@ x87_fround32_64(double b) static __inline int64_t x87_fround(double b) { - int64_t a, c; + double da; + double dc; + int64_t a; + int64_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ - a = (int64_t) floor(b); - c = (int64_t) floor(b + 1.0); + da = floor(b); + dc = floor(b + 1.0); + a = (int64_t) da; + c = (int64_t) dc; if ((b - a) < (c - b)) return a; else if ((b - a) > (c - b)) @@ -246,9 +265,11 @@ x87_fround(double b) else return (a & 1) ? c : a; case 1: /*Down*/ - return (int64_t) floor(b); + da = floor(b); + return (int64_t) da; case 2: /*Up*/ - return (int64_t) ceil(b); + da = ceil(b); + return (int64_t) da; case 3: /*Chop*/ return (int64_t) b; } @@ -338,9 +359,10 @@ x87_compare(double a, double b) { #ifdef X87_INLINE_ASM uint32_t result; - double ea = a, eb = b; - const uint64_t ia = 0x3fec1a6ff866a936ull; - const uint64_t ib = 0x3fec1a6ff866a938ull; + double ea = a; + double eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ULL; + const uint64_t ib = 0x3fec1a6ff866a938ULL; /* Hack to make CHKCOP happy. */ if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) @@ -481,6 +503,8 @@ typedef union { # define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 #endif +#include "softfloat/softfloat-specialize.h" + #include "x87_ops_sf_arith.h" #include "x87_ops_sf_compare.h" #include "x87_ops_sf_const.h" @@ -1067,7 +1091,6 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { #else # define ILLEGAL_a32 FPU_ILLEGAL_a32 - const OpFn OP_TABLE(sf_fpu_d8_a16)[32] = { // clang-format off sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, @@ -1406,6 +1429,7 @@ const OpFn OP_TABLE(sf_fpu_da_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(sf_fpu_686_da_a16)[256] = { // clang-format off sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, @@ -1485,6 +1509,7 @@ const OpFn OP_TABLE(sf_fpu_686_da_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(sf_fpu_287_db_a16)[256] = { // clang-format off @@ -1646,6 +1671,7 @@ const OpFn OP_TABLE(sf_fpu_db_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(sf_fpu_686_db_a16)[256] = { // clang-format off sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, @@ -1724,6 +1750,7 @@ const OpFn OP_TABLE(sf_fpu_686_db_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(sf_fpu_287_dc_a16)[32] = { // clang-format off @@ -2241,6 +2268,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = { // clang-format off sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, @@ -2320,6 +2348,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(fpu_d8_a16)[32] = { // clang-format off @@ -2659,6 +2688,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(fpu_686_da_a16)[256] = { // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -2738,6 +2768,7 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(fpu_287_db_a16)[256] = { // clang-format off @@ -2899,6 +2930,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(fpu_686_db_a16)[256] = { // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, @@ -2977,6 +3009,7 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(fpu_287_dc_a16)[32] = { // clang-format off @@ -3494,6 +3527,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = { // clang-format on }; +# ifndef OPS_286_386 const OpFn OP_TABLE(fpu_686_df_a16)[256] = { // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, @@ -3573,6 +3607,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, // clang-format on }; +# endif const OpFn OP_TABLE(nofpu_a16)[256] = { // clang-format off diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index d38d584a81..808a150517 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -143,9 +143,9 @@ opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif -// clang-format on + // clang-format on -static int opFADD(uint32_t fetchdat) + static int opFADD(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; @@ -242,6 +242,7 @@ opFUCOMPP(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int opFCOMI(uint32_t fetchdat) { @@ -273,6 +274,7 @@ opFCOMIP(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } +# endif #endif static int @@ -476,6 +478,7 @@ opFUCOMP(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int opFUCOMI(uint32_t fetchdat) { @@ -507,4 +510,5 @@ opFUCOMIP(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } +# endif #endif diff --git a/src/cpu/x87_ops_conv.h b/src/cpu/x87_ops_conv.h index bb1e497dac..7a949cfb22 100644 --- a/src/cpu/x87_ops_conv.h +++ b/src/cpu/x87_ops_conv.h @@ -22,7 +22,7 @@ x87_from80(x87_conv_t *test) blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); + mant64 = (test->eind.ll >> 11) & (0xfffffffffffffLL); sign = (test->begin & 0x8000) ? 1 : 0; if ((test->begin & 0x7fff) == 0x7fff) @@ -48,19 +48,19 @@ x87_to80(double d, x87_conv_t *test) test->eind.d = d; - sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0; - exp80 = test->eind.ll & (0x7ff0000000000000ll); + sign80 = (test->eind.ll & (0x8000000000000000LL)) ? 1 : 0; + exp80 = test->eind.ll & (0x7ff0000000000000LL); exp80final = (exp80 >> 52); - mant80 = test->eind.ll & (0x000fffffffffffffll); + mant80 = test->eind.ll & (0x000fffffffffffffLL); mant80final = (mant80 << 11); if (exp80final == 0x7ff) /*Infinity / Nan*/ { exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); + mant80final |= (0x8000000000000000LL); } else if (d != 0) { /* Zero is a special case */ /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); + mant80final |= (0x8000000000000000LL); /* Ca-cyber doesn't like this when result is zero. */ exp80final += (BIAS80 - BIAS64); } diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index 9cec014909..d77c0ca2b7 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -147,6 +147,7 @@ opFILDiq_a32(uint32_t fetchdat) static int FBSTP_a16(uint32_t fetchdat) { + double dt; double tempd; int c; FP_ENTER(); @@ -156,15 +157,18 @@ FBSTP_a16(uint32_t fetchdat) if (tempd < 0.0) tempd = -tempd; for (c = 0; c < 9; c++) { - uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + dt = floor(fmod(tempd, 10.0)); + uint8_t tempc = (uint8_t) dt; tempd -= floor(fmod(tempd, 10.0)); tempd /= 10.0; - tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + dt = floor(fmod(tempd, 10.0)); + tempc |= ((uint8_t) dt) << 4; tempd -= floor(fmod(tempd, 10.0)); tempd /= 10.0; writememb(easeg, cpu_state.eaaddr + c, tempc); } - tempc = (uint8_t) floor(fmod(tempd, 10.0)); + dt = floor(fmod(tempd, 10.0)); + tempc = (uint8_t) dt; if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index bd2b05c52f..d854f83dbd 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -37,16 +37,17 @@ static int opFXTRACT(uint32_t fetchdat) { x87_conv_t test; - int64_t exp80, exp80final; - double mant; + int64_t exp80; + int64_t exp80final; + double mant; FP_ENTER(); cpu_state.pc++; test.eind.d = ST(0); - exp80 = test.eind.ll & (0x7ff0000000000000ll); - exp80final = (exp80 >> 52) - BIAS64; - mant = test.eind.d / (pow(2.0, (double)exp80final)); - ST(0) = (double)exp80final; + exp80 = test.eind.ll & 0x7ff0000000000000LL; + exp80final = (exp80 >> 52) - BIAS64; + mant = test.eind.d / (pow(2.0, (double) exp80final)); + ST(0) = (double) exp80final; FP_TAG_VALID; x87_push(mant); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxtract) : (x87_timings.fxtract * cpu_multi)); @@ -82,7 +83,7 @@ opFINIT(uint32_t fetchdat) #ifdef USE_NEW_DYNAREC *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303LL; #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -192,7 +193,7 @@ FSTOR(void) something like this is needed*/ p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ULL)) #else if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) #endif @@ -410,7 +411,7 @@ FSAVE(void) #ifdef USE_NEW_DYNAREC *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303LL; #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -629,7 +630,7 @@ opFLDLN2(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - x87_push_u64(0x3fe62e42fefa39f0ull); + x87_push_u64(0x3fe62e42fefa39f0ULL); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; @@ -817,9 +818,12 @@ opFSINCOS(uint32_t fetchdat) static int opFRNDINT(uint32_t fetchdat) { + double dst0; + FP_ENTER(); cpu_state.pc++; - ST(0) = (double) x87_fround(ST(0)); + dst0 = x87_fround(ST(0)); + ST(0) = (double) dst0; FP_TAG_VALID; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); @@ -1045,22 +1049,23 @@ opFSTCW_a32(uint32_t fetchdat) #endif #ifndef FPU_8087 -# define opFCMOV(condition) \ - static int opFCMOV##condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (cond_##condition) { \ - cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } +# ifndef OPS_286_386 +# define opFCMOV(condition) \ + static int opFCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_##condition) { \ + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ + } -# define cond_U (PF_SET()) -# define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) // clang-format off opFCMOV(B) @@ -1072,4 +1077,5 @@ opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) // clang-format on +# endif #endif diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index e70556feab..137919fa97 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -1,7 +1,7 @@ static uint32_t fpu_save_environment(void) { - int tag; + int tag; unsigned offset = 0; /* read all registers in stack order and update x87 tag word */ @@ -16,91 +16,98 @@ fpu_save_environment(void) fpu_state.swd = (fpu_state.swd & ~(7 << 11)) | ((fpu_state.tos & 7) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { - case 0x000: { /*16-bit real mode*/ - uint16_t tmp; - uint32_t fp_ip, fp_dp; - - fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip; - fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp; - - tmp = i387_get_control_word(); - writememw(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = i387_get_status_word(); - writememw(easeg, cpu_state.eaaddr + 0x02, tmp); - tmp = fpu_state.tag; - writememw(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = fp_ip & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x06, tmp); - tmp = (uint16_t)((fp_ip & 0xf0000) >> 4) | fpu_state.foo; - writememw(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = fp_dp & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); - tmp = (uint16_t)((fp_dp & 0xf0000) >> 4); - writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); - offset = 0x0e; - } - break; - case 0x001: {/*16-bit protected mode*/ - uint16_t tmp; - tmp = i387_get_control_word(); - writememw(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = i387_get_status_word(); - writememw(easeg, cpu_state.eaaddr + 0x02, tmp); - tmp = fpu_state.tag; - writememw(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = (uint16_t)(fpu_state.fip) & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x06, tmp); - tmp = fpu_state.fcs; - writememw(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = (uint16_t)(fpu_state.fdp) & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); - tmp = fpu_state.fds; - writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); - offset = 0x0e; - } - break; - case 0x100: { /*32-bit real mode*/ - uint32_t tmp, fp_ip, fp_dp; - - fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip; - fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp; - - tmp = 0xffff0000 | i387_get_control_word(); - writememl(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = 0xffff0000 | i387_get_status_word(); - writememl(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = 0xffff0000 | fpu_state.tag; - writememl(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = 0xffff0000 | (fp_ip & 0xffff); - writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); - tmp = ((fp_ip & 0xffff0000) >> 4) | fpu_state.foo; - writememl(easeg, cpu_state.eaaddr + 0x10, tmp); - tmp = 0xffff0000 | (fp_dp & 0xffff); - writememl(easeg, cpu_state.eaaddr + 0x14, tmp); - tmp = (fp_dp & 0xffff0000) >> 4; - writememl(easeg, cpu_state.eaaddr + 0x18, tmp); - offset = 0x1c; - } - break; - case 0x101: { /*32-bit protected mode*/ - uint32_t tmp; - tmp = 0xffff0000 | i387_get_control_word(); - writememl(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = 0xffff0000 | i387_get_status_word(); - writememl(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = 0xffff0000 | fpu_state.tag; - writememl(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = (uint32_t)(fpu_state.fip); - writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); - tmp = fpu_state.fcs | (((uint32_t)(fpu_state.foo)) << 16); - writememl(easeg, cpu_state.eaaddr + 0x10, tmp); - tmp = (uint32_t)(fpu_state.fdp); - writememl(easeg, cpu_state.eaaddr + 0x14, tmp); - tmp = 0xffff0000 | fpu_state.fds; - writememl(easeg, cpu_state.eaaddr + 0x18, tmp); - offset = 0x1c; - } - break; + case 0x000: + { /*16-bit real mode*/ + uint16_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + fp_ip = ((uint32_t) (fpu_state.fcs << 4)) | fpu_state.fip; + fp_dp = ((uint32_t) (fpu_state.fds << 4)) | fpu_state.fdp; + + tmp = i387_get_control_word(); + writememw(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = i387_get_status_word(); + writememw(easeg, cpu_state.eaaddr + 0x02, tmp); + tmp = fpu_state.tag; + writememw(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = fp_ip & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x06, tmp); + tmp = (uint16_t) ((fp_ip & 0xf0000) >> 4) | fpu_state.foo; + writememw(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = fp_dp & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); + tmp = (uint16_t) ((fp_dp & 0xf0000) >> 4); + writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); + offset = 0x0e; + } + break; + case 0x001: + { /*16-bit protected mode*/ + uint16_t tmp; + tmp = i387_get_control_word(); + writememw(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = i387_get_status_word(); + writememw(easeg, cpu_state.eaaddr + 0x02, tmp); + tmp = fpu_state.tag; + writememw(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = (uint16_t) (fpu_state.fip) & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x06, tmp); + tmp = fpu_state.fcs; + writememw(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = (uint16_t) (fpu_state.fdp) & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); + tmp = fpu_state.fds; + writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); + offset = 0x0e; + } + break; + case 0x100: + { /*32-bit real mode*/ + uint32_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + fp_ip = ((uint32_t) (fpu_state.fcs << 4)) | fpu_state.fip; + fp_dp = ((uint32_t) (fpu_state.fds << 4)) | fpu_state.fdp; + + tmp = 0xffff0000 | i387_get_control_word(); + writememl(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = 0xffff0000 | i387_get_status_word(); + writememl(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = 0xffff0000 | fpu_state.tag; + writememl(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = 0xffff0000 | (fp_ip & 0xffff); + writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); + tmp = ((fp_ip & 0xffff0000) >> 4) | fpu_state.foo; + writememl(easeg, cpu_state.eaaddr + 0x10, tmp); + tmp = 0xffff0000 | (fp_dp & 0xffff); + writememl(easeg, cpu_state.eaaddr + 0x14, tmp); + tmp = (fp_dp & 0xffff0000) >> 4; + writememl(easeg, cpu_state.eaaddr + 0x18, tmp); + offset = 0x1c; + } + break; + case 0x101: + { /*32-bit protected mode*/ + uint32_t tmp; + tmp = 0xffff0000 | i387_get_control_word(); + writememl(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = 0xffff0000 | i387_get_status_word(); + writememl(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = 0xffff0000 | fpu_state.tag; + writememl(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = (uint32_t) (fpu_state.fip); + writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); + tmp = fpu_state.fcs | (((uint32_t) (fpu_state.foo)) << 16); + writememl(easeg, cpu_state.eaaddr + 0x10, tmp); + tmp = (uint32_t) (fpu_state.fdp); + writememl(easeg, cpu_state.eaaddr + 0x14, tmp); + tmp = 0xffff0000 | fpu_state.fds; + writememl(easeg, cpu_state.eaaddr + 0x18, tmp); + offset = 0x1c; + } + break; } return (cpu_state.eaaddr + offset); @@ -112,95 +119,104 @@ fpu_load_environment(void) unsigned offset = 0; switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { - case 0x000: { /*16-bit real mode*/ - uint16_t tmp; - uint32_t fp_ip, fp_dp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); - fp_dp = (tmp & 0xf000) << 4; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); - fpu_state.fdp = fp_dp | tmp; - fpu_state.fds = 0; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); - fp_ip = (tmp & 0xf000) << 4; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); - fpu_state.fip = fp_ip | tmp; - fpu_state.fcs = 0; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); - fpu_state.tag = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); - fpu_state.swd = tmp; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp; - offset = 0x0e; - } - break; - case 0x001: {/*16-bit protected mode*/ - uint16_t tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); - fpu_state.fds = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); - fpu_state.fdp = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); - fpu_state.fcs = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); - fpu_state.fip = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); - fpu_state.tag = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); - fpu_state.swd = tmp; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp; - offset = 0x0e; - } - break; - case 0x100: { /*32-bit real mode*/ - uint32_t tmp, fp_ip, fp_dp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); - fp_dp = (tmp & 0x0ffff000) << 4; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); - fp_dp |= (tmp & 0xffff); - fpu_state.fdp = fp_dp; - fpu_state.fds = 0; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); - fpu_state.foo = tmp & 0x07ff; - fp_ip = (tmp & 0x0ffff000) << 4; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); - fp_ip |= (tmp & 0xffff); - fpu_state.fip = fp_ip; - fpu_state.fcs = 0; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); - fpu_state.tag = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); - fpu_state.swd = tmp & 0xffff; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp & 0xffff; - offset = 0x1c; - } - break; - case 0x101: { /*32-bit protected mode*/ - uint32_t tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); - fpu_state.fds = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); - fpu_state.fdp = tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); - fpu_state.fcs = tmp & 0xffff; - fpu_state.foo = (tmp >> 16) & 0x07ff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); - fpu_state.fip = tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); - fpu_state.tag = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); - fpu_state.swd = tmp & 0xffff; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp & 0xffff; - offset = 0x1c; - } - break; + case 0x000: + { /*16-bit real mode*/ + uint16_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); + fp_dp = (tmp & 0xf000) << 4; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); + fpu_state.fdp = fp_dp | tmp; + fpu_state.fds = 0; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); + fp_ip = (tmp & 0xf000) << 4; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); + fpu_state.fip = fp_ip | tmp; + fpu_state.fcs = 0; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); + fpu_state.tag = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); + fpu_state.swd = tmp; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp; + offset = 0x0e; + } + break; + case 0x001: + { /*16-bit protected mode*/ + uint16_t tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); + fpu_state.fds = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); + fpu_state.fdp = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); + fpu_state.fcs = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); + fpu_state.fip = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); + fpu_state.tag = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); + fpu_state.swd = tmp; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp; + offset = 0x0e; + } + break; + case 0x100: + { /*32-bit real mode*/ + uint32_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); + fp_dp = (tmp & 0x0ffff000) << 4; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); + fp_dp |= (tmp & 0xffff); + fpu_state.fdp = fp_dp; + fpu_state.fds = 0; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); + fpu_state.foo = tmp & 0x07ff; + fp_ip = (tmp & 0x0ffff000) << 4; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); + fp_ip |= (tmp & 0xffff); + fpu_state.fip = fp_ip; + fpu_state.fcs = 0; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); + fpu_state.tag = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); + fpu_state.swd = tmp & 0xffff; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp & 0xffff; + offset = 0x1c; + } + break; + case 0x101: + { /*32-bit protected mode*/ + uint32_t tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); + fpu_state.fds = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); + fpu_state.fdp = tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); + fpu_state.fcs = tmp & 0xffff; + fpu_state.foo = (tmp >> 16) & 0x07ff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); + fpu_state.fip = tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); + fpu_state.tag = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); + fpu_state.swd = tmp & 0xffff; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp & 0xffff; + offset = 0x1c; + } + break; } /* always set bit 6 as '1 */ @@ -356,7 +372,7 @@ static int sf_FRSTOR_a16(uint32_t fetchdat) { floatx80 tmp; - int offset; + int offset; FP_ENTER(); fetch_ea_16(fetchdat); @@ -364,7 +380,7 @@ sf_FRSTOR_a16(uint32_t fetchdat) offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.exp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -376,7 +392,7 @@ static int sf_FRSTOR_a32(uint32_t fetchdat) { floatx80 tmp; - int offset; + int offset; FP_ENTER(); fetch_ea_32(fetchdat); @@ -384,7 +400,7 @@ sf_FRSTOR_a32(uint32_t fetchdat) offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.exp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -397,7 +413,7 @@ static int sf_FNSAVE_a16(uint32_t fetchdat) { floatx80 stn; - int offset; + int offset; FP_ENTER(); fetch_ea_16(fetchdat); @@ -415,15 +431,15 @@ sf_FNSAVE_a16(uint32_t fetchdat) #else fpu_state.cwd = 0x37F; #endif - fpu_state.swd = 0; - fpu_state.tos = 0; - fpu_state.tag = 0xffff; + fpu_state.swd = 0; + fpu_state.tos = 0; + fpu_state.tag = 0xffff; cpu_state.ismmx = 0; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); return cpu_state.abrt; @@ -433,7 +449,7 @@ static int sf_FNSAVE_a32(uint32_t fetchdat) { floatx80 stn; - int offset; + int offset; FP_ENTER(); fetch_ea_32(fetchdat); @@ -446,20 +462,20 @@ sf_FNSAVE_a32(uint32_t fetchdat) writememw(easeg, offset + (m * 10) + 8, stn.exp); } -#ifdef FPU_8087 +# ifdef FPU_8087 fpu_state.swd = 0x3FF; -#else +# else fpu_state.cwd = 0x37F; -#endif - fpu_state.swd = 0; - fpu_state.tos = 0; - fpu_state.tag = 0xffff; +# endif + fpu_state.swd = 0; + fpu_state.tos = 0; + fpu_state.tag = 0xffff; cpu_state.ismmx = 0; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); return cpu_state.abrt; @@ -471,9 +487,7 @@ sf_FNCLEX(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary | FPU_SW_Stack_Fault | FPU_SW_Precision | - FPU_SW_Underflow | FPU_SW_Overflow | FPU_SW_Zero_Div | FPU_SW_Denormal_Op | - FPU_SW_Invalid); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary | FPU_SW_Stack_Fault | FPU_SW_Precision | FPU_SW_Underflow | FPU_SW_Overflow | FPU_SW_Zero_Div | FPU_SW_Denormal_Op | FPU_SW_Invalid); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); return 0; @@ -489,14 +503,14 @@ sf_FNINIT(uint32_t fetchdat) #else fpu_state.cwd = 0x37F; #endif - fpu_state.swd = 0; + fpu_state.swd = 0; fpu_state.tos = 0; - fpu_state.tag = 0xffff; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.tag = 0xffff; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; cpu_state.ismmx = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); @@ -559,7 +573,7 @@ sf_FNSTENV_a16(uint32_t fetchdat) /* mask all floating point exceptions */ fpu_state.cwd |= FPU_CW_Exceptions_Mask; /* clear the B and ES bits in the status word */ - fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; @@ -575,7 +589,7 @@ sf_FNSTENV_a32(uint32_t fetchdat) /* mask all floating point exceptions */ fpu_state.cwd |= FPU_CW_Exceptions_Mask; /* clear the B and ES bits in the status word */ - fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; diff --git a/src/cpu/x87_ops_sf_arith.h b/src/cpu/x87_ops_sf_arith.h index 10b100b2a3..5144062bb9 100644 --- a/src/cpu/x87_ops_sf_arith.h +++ b/src/cpu/x87_ops_sf_arith.h @@ -1,180 +1,180 @@ -#define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ - static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ +#define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ + static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_add(a, use_var, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_add(a, use_var, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_div(a, use_var, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_div(a, use_var, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_div(use_var, a, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_div(use_var, a, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_mul(a, use_var, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_mul(a, use_var, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_sub(a, use_var, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_sub(a, use_var, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_sub(use_var, a, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_sub(use_var, a, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ @@ -198,12 +198,13 @@ sf_FPU(il, uint32_t, 16, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i #ifndef FPU_8087 sf_FPU(il, uint32_t, 32, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32) #endif -// clang-format on + // clang-format on -static int -sf_FADD_st0_stj(uint32_t fetchdat) + static int sf_FADD_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -215,8 +216,8 @@ sf_FADD_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -230,7 +231,9 @@ sf_FADD_st0_stj(uint32_t fetchdat) static int sf_FADD_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -242,8 +245,8 @@ sf_FADD_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -258,7 +261,9 @@ sf_FADD_sti_st0(uint32_t fetchdat) static int sf_FADDP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -270,8 +275,8 @@ sf_FADDP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -288,7 +293,9 @@ sf_FADDP_sti_st0(uint32_t fetchdat) static int sf_FDIV_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -299,8 +306,8 @@ sf_FDIV_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -315,7 +322,9 @@ sf_FDIV_st0_stj(uint32_t fetchdat) static int sf_FDIV_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -326,8 +335,8 @@ sf_FDIV_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -341,7 +350,9 @@ sf_FDIV_sti_st0(uint32_t fetchdat) static int sf_FDIVP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -352,8 +363,8 @@ sf_FDIVP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -370,7 +381,9 @@ sf_FDIVP_sti_st0(uint32_t fetchdat) static int sf_FDIVR_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -381,8 +394,8 @@ sf_FDIVR_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -396,7 +409,9 @@ sf_FDIVR_st0_stj(uint32_t fetchdat) static int sf_FDIVR_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -407,8 +422,8 @@ sf_FDIVR_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -422,7 +437,9 @@ sf_FDIVR_sti_st0(uint32_t fetchdat) static int sf_FDIVRP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -433,8 +450,8 @@ sf_FDIVRP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -451,7 +468,9 @@ sf_FDIVRP_sti_st0(uint32_t fetchdat) static int sf_FMUL_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -462,8 +481,8 @@ sf_FMUL_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -478,7 +497,9 @@ sf_FMUL_st0_stj(uint32_t fetchdat) static int sf_FMUL_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -489,8 +510,8 @@ sf_FMUL_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -505,7 +526,9 @@ sf_FMUL_sti_st0(uint32_t fetchdat) static int sf_FMULP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -516,8 +539,8 @@ sf_FMULP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -534,7 +557,9 @@ sf_FMULP_sti_st0(uint32_t fetchdat) static int sf_FSUB_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -545,8 +570,8 @@ sf_FSUB_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -561,7 +586,9 @@ sf_FSUB_st0_stj(uint32_t fetchdat) static int sf_FSUB_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -572,8 +599,8 @@ sf_FSUB_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -588,7 +615,9 @@ sf_FSUB_sti_st0(uint32_t fetchdat) static int sf_FSUBP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -599,8 +628,8 @@ sf_FSUBP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -617,7 +646,9 @@ sf_FSUBP_sti_st0(uint32_t fetchdat) static int sf_FSUBR_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -628,8 +659,8 @@ sf_FSUBR_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -644,7 +675,9 @@ sf_FSUBR_st0_stj(uint32_t fetchdat) static int sf_FSUBR_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -655,8 +688,8 @@ sf_FSUBR_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -671,7 +704,9 @@ sf_FSUBR_sti_st0(uint32_t fetchdat) static int sf_FSUBRP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -682,8 +717,8 @@ sf_FSUBRP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -700,7 +735,7 @@ sf_FSUBRP_sti_st0(uint32_t fetchdat) static int sf_FSQRT(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -726,7 +761,7 @@ sf_FSQRT(uint32_t fetchdat) static int sf_FRNDINT(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); diff --git a/src/cpu/x87_ops_sf_compare.h b/src/cpu/x87_ops_sf_compare.h index 59135c05bf..6b4c1cb62b 100644 --- a/src/cpu/x87_ops_sf_compare.h +++ b/src/cpu/x87_ops_sf_compare.h @@ -1,76 +1,76 @@ -#define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ - static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \ +#define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ + static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ - } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ - } \ - setcc(FPU_status_word_flags_fpu_compare(rc)); \ - FPU_exception(fetchdat, status.float_exception_flags, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ + setcc(C0 | C2 | C3); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (is_nan) { \ + rc = float_relation_unordered; \ + float_raise(&status, float_flag_invalid); \ + } else { \ + rc = floatx80_compare_two(a, use_var, &status); \ + } \ + setcc(FPU_status_word_flags_fpu_compare(rc)); \ + FPU_exception(fetchdat, status.float_exception_flags, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ - if (is_IA_masked()) \ - FPU_pop(); \ - \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ - } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ - } \ - setcc(FPU_status_word_flags_fpu_compare(rc)); \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_pop(); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ + setcc(C0 | C2 | C3); \ + if (is_IA_masked()) \ + FPU_pop(); \ + \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (is_nan) { \ + rc = float_relation_unordered; \ + float_raise(&status, float_flag_invalid); \ + } else { \ + rc = floatx80_compare_two(a, use_var, &status); \ + } \ + setcc(FPU_status_word_flags_fpu_compare(rc)); \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_pop(); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ - } \ + } // clang-format off cmp_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32) @@ -90,14 +90,14 @@ cmp_FPU(il, int32_t, 16, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i #ifndef FPU_8087 cmp_FPU(il, int32_t, 32, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32) #endif -// clang-format on + // clang-format on -static int -sf_FCOM_sti(uint32_t fetchdat) + static int sf_FCOM_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -108,9 +108,9 @@ sf_FCOM_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -123,9 +123,10 @@ sf_FCOM_sti(uint32_t fetchdat) static int sf_FCOMP_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -139,9 +140,9 @@ sf_FCOMP_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -156,9 +157,10 @@ sf_FCOMP_sti(uint32_t fetchdat) static int sf_FCOMPP(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -173,9 +175,9 @@ sf_FCOMPP(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(1); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -192,9 +194,10 @@ sf_FCOMPP(uint32_t fetchdat) static int sf_FUCOMPP(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -209,9 +212,9 @@ sf_FUCOMPP(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(1); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -224,12 +227,14 @@ sf_FUCOMPP(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int sf_FCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -241,9 +246,9 @@ sf_FCOMI_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); FPU_write_eflags_fpu_compare(rc); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -255,9 +260,10 @@ sf_FCOMI_st0_stj(uint32_t fetchdat) static int sf_FCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -272,9 +278,9 @@ sf_FCOMIP_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); FPU_write_eflags_fpu_compare(rc); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -285,13 +291,15 @@ sf_FCOMIP_st0_stj(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } +# endif static int sf_FUCOM_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -302,9 +310,9 @@ sf_FUCOM_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -317,9 +325,10 @@ sf_FUCOM_sti(uint32_t fetchdat) static int sf_FUCOMP_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -333,9 +342,9 @@ sf_FUCOMP_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_pop(); @@ -346,12 +355,14 @@ sf_FUCOMP_sti(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int sf_FUCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -363,9 +374,9 @@ sf_FUCOMI_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -377,9 +388,10 @@ sf_FUCOMI_st0_stj(uint32_t fetchdat) static int sf_FUCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -394,9 +406,9 @@ sf_FUCOMIP_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_pop(); @@ -406,12 +418,13 @@ sf_FUCOMIP_st0_stj(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } +# endif #endif static int sf_FTST(uint32_t fetchdat) { - int rc; + int rc; struct float_status_t status; FP_ENTER(); @@ -422,7 +435,7 @@ sf_FTST(uint32_t fetchdat) setcc(C0 | C2 | C3); } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status); + rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); } @@ -434,19 +447,19 @@ sf_FTST(uint32_t fetchdat) static int sf_FXAM(uint32_t fetchdat) { - floatx80 reg; - int sign; + floatx80 reg; + int sign; float_class_t aClass; FP_ENTER(); cpu_state.pc++; - reg = FPU_read_regi(0); + reg = FPU_read_regi(0); sign = floatx80_sign(reg); - /* - * Examine the contents of the ST(0) register and sets the condition - * code flags C0, C2 and C3 in the FPU status word to indicate the - * class of value or number in the register. - */ + /* + * Examine the contents of the ST(0) register and sets the condition + * code flags C0, C2 and C3 in the FPU status word to indicate the + * class of value or number in the register. + */ if (IS_TAG_EMPTY(0)) { setcc(C3 | C1 | C0); } else { @@ -476,10 +489,10 @@ sf_FXAM(uint32_t fetchdat) break; } } - /* - * The C1 flag is set to the sign of the value in ST(0), regardless - * of whether the register is empty or full. - */ + /* + * The C1 flag is set to the sign of the value in ST(0), regardless + * of whether the register is empty or full. + */ if (!sign) clear_C1(); diff --git a/src/cpu/x87_ops_sf_const.h b/src/cpu/x87_ops_sf_const.h index 708c6ff7a4..0808cbae82 100644 --- a/src/cpu/x87_ops_sf_const.h +++ b/src/cpu/x87_ops_sf_const.h @@ -1,14 +1,14 @@ /* A fast way to find out whether x is one of RC_DOWN or RC_CHOP (and not one of RC_RND or RC_UP). */ -#define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN) +#define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN) static __inline floatx80 FPU_round_const(const floatx80 a, int adj) { - floatx80 result = a; - result.fraction += adj; - return result; + floatx80 result = a; + result.fraction += adj; + return result; } static int diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index 69bc5598c9..383a7ee52f 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -17,13 +17,18 @@ * Copyright 2016-2019 Miran Grca. */ -#define swap_values16u(a, b) { uint16_t tmp = a; a = b; b = tmp; } +#define swap_values16u(a, b) \ + { \ + uint16_t tmp = a; \ + a = b; \ + b = tmp; \ + } static int sf_FILDiw_a16(uint32_t fetchdat) { floatx80 result; - int16_t temp; + int16_t temp; FP_ENTER(); FPU_check_pending_exceptions(); @@ -49,7 +54,7 @@ static int sf_FILDiw_a32(uint32_t fetchdat) { floatx80 result; - int16_t temp; + int16_t temp; FP_ENTER(); FPU_check_pending_exceptions(); @@ -76,7 +81,7 @@ static int sf_FILDil_a16(uint32_t fetchdat) { floatx80 result; - int32_t templ; + int32_t templ; FP_ENTER(); FPU_check_pending_exceptions(); @@ -102,7 +107,7 @@ static int sf_FILDil_a32(uint32_t fetchdat) { floatx80 result; - int32_t templ; + int32_t templ; FP_ENTER(); FPU_check_pending_exceptions(); @@ -129,7 +134,7 @@ static int sf_FILDiq_a16(uint32_t fetchdat) { floatx80 result; - int64_t temp64; + int64_t temp64; FP_ENTER(); FPU_check_pending_exceptions(); @@ -155,7 +160,7 @@ static int sf_FILDiq_a32(uint32_t fetchdat) { floatx80 result; - int64_t temp64; + int64_t temp64; FP_ENTER(); FPU_check_pending_exceptions(); @@ -182,9 +187,9 @@ static int sf_FLDs_a16(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -198,8 +203,8 @@ sf_FLDs_a16(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float32_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -216,9 +221,9 @@ static int sf_FLDs_a32(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -232,8 +237,8 @@ sf_FLDs_a32(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float32_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -251,9 +256,9 @@ static int sf_FLDd_a16(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -267,8 +272,8 @@ sf_FLDd_a16(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float64_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -285,9 +290,9 @@ static int sf_FLDd_a32(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -301,8 +306,8 @@ sf_FLDd_a32(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float64_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -326,7 +331,7 @@ sf_FLDe_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.exp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); @@ -351,7 +356,7 @@ sf_FLDe_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.exp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); @@ -371,7 +376,7 @@ static int sf_FLD_sti(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 sti_reg; + floatx80 sti_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -403,8 +408,8 @@ static int sf_FISTiw_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -417,7 +422,7 @@ sf_FISTiw_a16(uint32_t fetchdat) goto next_ins; } } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -438,8 +443,8 @@ static int sf_FISTiw_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -451,7 +456,7 @@ sf_FISTiw_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -472,8 +477,8 @@ static int sf_FISTPiw_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -485,7 +490,7 @@ sf_FISTPiw_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -509,8 +514,8 @@ static int sf_FISTPiw_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -522,7 +527,7 @@ sf_FISTPiw_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -546,8 +551,8 @@ static int sf_FISTil_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -559,7 +564,7 @@ sf_FISTil_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -580,8 +585,8 @@ static int sf_FISTil_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -593,7 +598,7 @@ sf_FISTil_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -614,8 +619,8 @@ static int sf_FISTPil_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -627,7 +632,7 @@ sf_FISTPil_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -651,8 +656,8 @@ static int sf_FISTPil_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -664,7 +669,7 @@ sf_FISTPil_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -688,8 +693,8 @@ static int sf_FISTPiq_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -701,9 +706,9 @@ sf_FISTPiq_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; } } @@ -725,8 +730,8 @@ static int sf_FISTPiq_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -738,7 +743,7 @@ sf_FISTPiq_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -762,12 +767,12 @@ static int sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -779,10 +784,10 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - reg = FPU_read_regi(0); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + reg = FPU_read_regi(0); save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; @@ -793,12 +798,12 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { - save_reg_lo += ((uint64_t)(save_val % 10)) << (4 * i); + save_reg_lo += ((uint64_t) (save_val % 10)) << (4 * i); save_val /= 10; } - save_reg_hi += (uint16_t)(save_val % 10); + save_reg_hi += (uint16_t) (save_val % 10); save_val /= 10; - save_reg_hi += (uint16_t)(save_val % 10) << 4; + save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { @@ -826,12 +831,12 @@ static int sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -843,10 +848,10 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - reg = FPU_read_regi(0); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + reg = FPU_read_regi(0); save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; @@ -857,12 +862,12 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { - save_reg_lo += ((uint64_t)(save_val % 10)) << (4 * i); + save_reg_lo += ((uint64_t) (save_val % 10)) << (4 * i); save_val /= 10; } - save_reg_hi += (uint16_t)(save_val % 10); + save_reg_hi += (uint16_t) (save_val % 10); save_val /= 10; - save_reg_hi += (uint16_t)(save_val % 10) << 4; + save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { @@ -891,8 +896,8 @@ static int sf_FSTs_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -904,7 +909,7 @@ sf_FSTs_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -925,8 +930,8 @@ static int sf_FSTs_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -938,7 +943,7 @@ sf_FSTs_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -959,8 +964,8 @@ static int sf_FSTPs_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -972,7 +977,7 @@ sf_FSTPs_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -997,8 +1002,8 @@ static int sf_FSTPs_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1010,7 +1015,7 @@ sf_FSTPs_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1034,8 +1039,8 @@ static int sf_FSTd_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1047,7 +1052,7 @@ sf_FSTd_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -1068,8 +1073,8 @@ static int sf_FSTd_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1081,7 +1086,7 @@ sf_FSTd_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1102,8 +1107,8 @@ static int sf_FSTPd_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1116,7 +1121,7 @@ sf_FSTPd_a16(uint32_t fetchdat) goto next_ins; } } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -1140,8 +1145,8 @@ static int sf_FSTPd_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1153,7 +1158,7 @@ sf_FSTPd_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1177,7 +1182,7 @@ static int sf_FSTPe_a16(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 save_reg; + floatx80 save_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1209,7 +1214,7 @@ static int sf_FSTPe_a32(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 save_reg; + floatx80 save_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1279,25 +1284,26 @@ sf_FSTP_sti(uint32_t fetchdat) } #ifndef FPU_8087 -# define sf_FCMOV(condition) \ - static int sf_FCMOV##condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - FPU_check_pending_exceptions(); \ - cpu_state.pc++; \ - if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) \ - FPU_stack_underflow(fetchdat, 0, 0); \ - else { \ - if (cond_##condition) { \ - FPU_save_regi(FPU_read_regi(fetchdat & 7), 0); \ - } \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } +# ifndef OPS_286_386 +# define sf_FCMOV(condition) \ + static int sf_FCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + FPU_check_pending_exceptions(); \ + cpu_state.pc++; \ + if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) \ + FPU_stack_underflow(fetchdat, 0, 0); \ + else { \ + if (cond_##condition) { \ + FPU_save_regi(FPU_read_regi(fetchdat & 7), 0); \ + } \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ + } -# define cond_U (PF_SET()) -# define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) // clang-format off sf_FCMOV(B) @@ -1309,4 +1315,5 @@ sf_FCMOV(NE) sf_FCMOV(NBE) sf_FCMOV(NU) // clang-format on +# endif #endif diff --git a/src/cpu/x87_ops_sf_misc.h b/src/cpu/x87_ops_sf_misc.h index d8a3d7368a..85f42e6d58 100644 --- a/src/cpu/x87_ops_sf_misc.h +++ b/src/cpu/x87_ops_sf_misc.h @@ -2,8 +2,10 @@ static int sf_FXCH_sti(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 st0_reg, sti_reg; - int st0_tag, sti_tag; + floatx80 st0_reg; + floatx80 sti_reg; + int st0_tag; + int sti_tag; FP_ENTER(); FPU_check_pending_exceptions(); @@ -48,7 +50,7 @@ sf_FCHS(uint32_t fetchdat) else { clear_C1(); st0_reg = FPU_read_regi(0); - result = floatx80_chs(st0_reg); + result = floatx80_chs(st0_reg); FPU_save_regi(result, 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); @@ -70,7 +72,7 @@ sf_FABS(uint32_t fetchdat) else { clear_C1(); st0_reg = FPU_read_regi(0); - result = floatx80_abs(st0_reg); + result = floatx80_abs(st0_reg); FPU_save_regi(result, 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); diff --git a/src/cpu/x87_ops_sf_trans.h b/src/cpu/x87_ops_sf_trans.h index 5289b2bbf5..5a99abb4c0 100644 --- a/src/cpu/x87_ops_sf_trans.h +++ b/src/cpu/x87_ops_sf_trans.h @@ -1,7 +1,7 @@ static int sf_F2XM1(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -13,7 +13,7 @@ sf_F2XM1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = f2xm1(FPU_read_regi(0), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(result, 0); next_ins: @@ -25,7 +25,7 @@ sf_F2XM1(uint32_t fetchdat) static int sf_FYL2X(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -37,7 +37,7 @@ sf_FYL2X(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2x(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -51,8 +51,8 @@ sf_FYL2X(uint32_t fetchdat) static int sf_FPTAN(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 y; + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -74,14 +74,14 @@ sf_FPTAN(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (ftan(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } if (floatx80_is_nan(y)) { - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(y, 0); @@ -89,7 +89,7 @@ sf_FPTAN(uint32_t fetchdat) goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(Const_1, 0); @@ -104,7 +104,9 @@ sf_FPTAN(uint32_t fetchdat) static int sf_FPATAN(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -113,11 +115,11 @@ sf_FPATAN(uint32_t fetchdat) FPU_stack_underflow(fetchdat, 1, 1); goto next_ins; } - a = FPU_read_regi(0); - b = FPU_read_regi(1); + a = FPU_read_regi(0); + b = FPU_read_regi(1); status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fpatan(a, b, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -132,13 +134,14 @@ static int sf_FXTRACT(uint32_t fetchdat) { struct float_status_t status; - floatx80 a, b; + floatx80 a; + floatx80 b; FP_ENTER(); cpu_state.pc++; clear_C1(); -#if 0 //TODO +#if 0 // TODO if ((IS_TAG_EMPTY(0) || IS_TAG_EMPTY(-1))) { if (IS_TAG_EMPTY(0)) FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); @@ -156,15 +159,15 @@ sf_FXTRACT(uint32_t fetchdat) #endif status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = floatx80_extract(&a, &status); + a = FPU_read_regi(0); + b = floatx80_extract(&a, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(b, 0); // exponent FPU_push(); FPU_save_regi(a, 0); // fraction } -#if 0 //TODO. +#if 0 // TODO. next_ins: #endif CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxtract) : (x87_timings.fxtract * cpu_multi)); @@ -175,10 +178,13 @@ sf_FXTRACT(uint32_t fetchdat) static int sf_FPREM1(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; - uint64_t quotient = 0; - int flags, cc; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); cpu_state.pc++; @@ -189,10 +195,10 @@ sf_FPREM1(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - flags = floatx80_ieee754_remainder(a, b, &result, "ient, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + a = FPU_read_regi(0); + b = FPU_read_regi(1); + flags = floatx80_ieee754_remainder(a, b, &result, "ient, &status); + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { if (flags >= 0) { cc = 0; if (flags) @@ -219,10 +225,13 @@ sf_FPREM1(uint32_t fetchdat) static int sf_FPREM(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; - uint64_t quotient = 0; - int flags, cc; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); cpu_state.pc++; @@ -233,11 +242,11 @@ sf_FPREM(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); + a = FPU_read_regi(0); + b = FPU_read_regi(1); // handle unsupported extended double-precision floating encodings flags = floatx80_remainder(a, b, &result, "ient, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { if (flags >= 0) { cc = 0; if (flags) @@ -264,7 +273,7 @@ sf_FPREM(uint32_t fetchdat) static int sf_FYL2XP1(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -276,7 +285,7 @@ sf_FYL2XP1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2xp1(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(result, 1); FPU_pop(); } @@ -291,9 +300,11 @@ sf_FYL2XP1(uint32_t fetchdat) static int sf_FSINCOS(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); struct float_status_t status; - floatx80 y, sin_y, cos_y; + floatx80 y; + floatx80 sin_y; + floatx80 cos_y; FP_ENTER(); cpu_state.pc++; @@ -314,12 +325,12 @@ sf_FSINCOS(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fsincos(y, &sin_y, &cos_y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(sin_y, 0); FPU_push(); FPU_save_regi(cos_y, 0); @@ -335,7 +346,7 @@ sf_FSINCOS(uint32_t fetchdat) static int sf_FSCALE(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -347,7 +358,7 @@ sf_FSCALE(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word()); result = floatx80_scale(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(result, 0); next_ins: @@ -360,7 +371,7 @@ sf_FSCALE(uint32_t fetchdat) static int sf_FSIN(uint32_t fetchdat) { - floatx80 y; + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -372,12 +383,12 @@ sf_FSIN(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fsin(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(y, 0); next_ins: @@ -389,7 +400,7 @@ sf_FSIN(uint32_t fetchdat) static int sf_FCOS(uint32_t fetchdat) { - floatx80 y; + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -401,12 +412,12 @@ sf_FCOS(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fcos(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(y, 0); next_ins: diff --git a/src/ddma.c b/src/ddma.c index 7623dc0df2..7cbe2831ed 100644 --- a/src/ddma.c +++ b/src/ddma.c @@ -34,6 +34,7 @@ #include <86box/pit.h> #include <86box/dma.h> #include <86box/ddma.h> +#include <86box/plat_unused.h> #ifdef ENABLE_DDMA_LOG int ddma_do_log = ENABLE_DDMA_LOG; @@ -54,12 +55,12 @@ ddma_log(const char *fmt, ...) #endif static uint8_t -ddma_reg_read(uint16_t addr, void *p) +ddma_reg_read(uint16_t addr, void *priv) { - ddma_channel_t *dev = (ddma_channel_t *) p; - uint8_t ret = 0xff; - int ch = dev->channel; - int dmab = (ch >= 4) ? 0xc0 : 0x00; + const ddma_channel_t *dev = (ddma_channel_t *) priv; + uint8_t ret = 0xff; + int ch = dev->channel; + uint8_t dmab = (ch >= 4) ? 0xc0 : 0x00; switch (addr & 0x0f) { case 0x00: @@ -80,18 +81,21 @@ ddma_reg_read(uint16_t addr, void *p) case 0x09: ret = inb(dmab + 0x08); break; + + default: + break; } return ret; } static void -ddma_reg_write(uint16_t addr, uint8_t val, void *p) +ddma_reg_write(uint16_t addr, uint8_t val, void *priv) { - ddma_channel_t *dev = (ddma_channel_t *) p; - int ch = dev->channel; - int page_regs[4] = { 7, 3, 1, 2 }; - int dmab = (ch >= 4) ? 0xc0 : 0x00; + const ddma_channel_t *dev = (ddma_channel_t *) priv; + int ch = dev->channel; + uint8_t page_regs[4] = { 7, 3, 1, 2 }; + uint8_t dmab = (ch >= 4) ? 0xc0 : 0x00; switch (addr & 0x0f) { case 0x00: @@ -138,6 +142,9 @@ ddma_reg_write(uint16_t addr, uint8_t val, void *p) case 0x0f: outb(dmab + 0x0a, (val << 2) | (ch & 3)); break; + + default: + break; } } @@ -163,7 +170,7 @@ ddma_close(void *priv) } static void * -ddma_init(const device_t *info) +ddma_init(UNUSED(const device_t *info)) { ddma_t *dev; diff --git a/src/device.c b/src/device.c index 7d8f5e88e4..b934e7246f 100644 --- a/src/device.c +++ b/src/device.c @@ -39,6 +39,7 @@ * Boston, MA 02111-1307 * USA. */ +#include #include #include #include @@ -61,6 +62,7 @@ static device_t *devices[DEVICE_MAX]; static void *device_priv[DEVICE_MAX]; static device_context_t device_current; static device_context_t device_prev; +static void *device_common_priv; #ifdef ENABLE_DEVICE_LOG int device_do_log = ENABLE_DEVICE_LOG; @@ -88,46 +90,46 @@ device_init(void) } void -device_set_context(device_context_t *c, const device_t *d, int inst) +device_set_context(device_context_t *c, const device_t *dev, int inst) { - void *sec; - void *single_sec; + const void *sec; + void *single_sec; memset(c, 0, sizeof(device_context_t)); - c->dev = d; + c->dev = dev; c->instance = inst; if (inst) { - sprintf(c->name, "%s #%i", d->name, inst); + sprintf(c->name, "%s #%i", dev->name, inst); /* If this is the first instance and a numbered section is not present, but a non-numbered section of the same name is, rename the non-numbered section to numbered. */ if (inst == 1) { sec = config_find_section(c->name); - single_sec = config_find_section((char *) d->name); + single_sec = config_find_section((char *) dev->name); if ((sec == NULL) && (single_sec != NULL)) config_rename_section(single_sec, c->name); } } else - sprintf(c->name, "%s", d->name); + sprintf(c->name, "%s", dev->name); } static void -device_context_common(const device_t *d, int inst) +device_context_common(const device_t *dev, int inst) { memcpy(&device_prev, &device_current, sizeof(device_context_t)); - device_set_context(&device_current, d, inst); + device_set_context(&device_current, dev, inst); } void -device_context(const device_t *d) +device_context(const device_t *dev) { - device_context_common(d, 0); + device_context_common(dev, 0); } void -device_context_inst(const device_t *d, int inst) +device_context_inst(const device_t *dev, int inst) { - device_context_common(d, inst); + device_context_common(dev, inst); } void @@ -137,13 +139,13 @@ device_context_restore(void) } static void * -device_add_common(const device_t *d, const device_t *cd, void *p, void *params, int inst) +device_add_common(const device_t *dev, const device_t *cd, void *p, void *params, int inst) { void *priv = NULL; int c; for (c = 0; c < 256; c++) { - if (!inst && (devices[c] == (device_t *) d)) { + if (!inst && (devices[c] == dev)) { device_log("DEVICE: device already exists!\n"); return (NULL); } @@ -157,17 +159,19 @@ device_add_common(const device_t *d, const device_t *cd, void *p, void *params, /* Do this so that a chained device_add will not identify the same ID its master device is already trying to assign. */ - devices[c] = (device_t *) d; + devices[c] = (device_t *) dev; + if (!strcmp(dev->name, "None") || !strcmp(dev->name, "Internal")) + fatal("Attempting to add dummy device of type: %s\n", dev->name); if (p == NULL) { memcpy(&device_prev, &device_current, sizeof(device_context_t)); device_set_context(&device_current, cd, inst); - if (d->init != NULL) { - priv = (d->flags & DEVICE_EXTPARAMS) ? d->init_ext(d, params) : d->init(d); + if (dev->init != NULL) { + priv = (dev->flags & DEVICE_EXTPARAMS) ? dev->init_ext(dev, params) : dev->init(dev); if (priv == NULL) { - if (d->name) - device_log("DEVICE: device '%s' init failed\n", d->name); + if (dev->name) + device_log("DEVICE: device '%s' init failed\n", dev->name); else device_log("DEVICE: device init failed\n"); @@ -178,8 +182,8 @@ device_add_common(const device_t *d, const device_t *cd, void *p, void *params, } } - if (d->name) - device_log("DEVICE: device '%s' init successful\n", d->name); + if (dev->name) + device_log("DEVICE: device '%s' init successful\n", dev->name); else device_log("DEVICE: device init successful\n"); @@ -191,115 +195,131 @@ device_add_common(const device_t *d, const device_t *cd, void *p, void *params, return priv; } -char * -device_get_internal_name(const device_t *d) +const char * +device_get_internal_name(const device_t *dev) { - if (d == NULL) + if (dev == NULL) return ""; - return (char *) d->internal_name; + return dev->internal_name; +} + +void * +device_add(const device_t *dev) +{ + return device_add_common(dev, dev, NULL, NULL, 0); } void * -device_add(const device_t *d) +device_add_linked(const device_t *dev, void *priv) { - return device_add_common(d, d, NULL, NULL, 0); + void *ret; + device_common_priv = priv; + ret = device_add_common(dev, dev, NULL, NULL, 0); + device_common_priv = NULL; + return ret; } void * -device_add_parameters(const device_t *d, void *params) +device_add_parameters(const device_t *dev, void *params) { - return device_add_common(d, d, NULL, params, 0); + return device_add_common(dev, dev, NULL, params, 0); } /* For devices that do not have an init function (internal video etc.) */ void -device_add_ex(const device_t *d, void *priv) +device_add_ex(const device_t *dev, void *priv) { - device_add_common(d, d, priv, NULL, 0); + device_add_common(dev, dev, priv, NULL, 0); } void -device_add_ex_parameters(const device_t *d, void *priv, void *params) +device_add_ex_parameters(const device_t *dev, void *priv, void *params) { - device_add_common(d, d, priv, params, 0); + device_add_common(dev, dev, priv, params, 0); } void * -device_add_inst(const device_t *d, int inst) +device_add_inst(const device_t *dev, int inst) { - return device_add_common(d, d, NULL, NULL, inst); + return device_add_common(dev, dev, NULL, NULL, inst); } void * -device_add_inst_parameters(const device_t *d, int inst, void *params) +device_add_inst_parameters(const device_t *dev, int inst, void *params) { - return device_add_common(d, d, NULL, params, inst); + return device_add_common(dev, dev, NULL, params, inst); } /* For devices that do not have an init function (internal video etc.) */ void -device_add_inst_ex(const device_t *d, void *priv, int inst) +device_add_inst_ex(const device_t *dev, void *priv, int inst) { - device_add_common(d, d, priv, NULL, inst); + device_add_common(dev, dev, priv, NULL, inst); } void -device_add_inst_ex_parameters(const device_t *d, void *priv, int inst, void *params) +device_add_inst_ex_parameters(const device_t *dev, void *priv, int inst, void *params) { - device_add_common(d, d, priv, params, inst); + device_add_common(dev, dev, priv, params, inst); } /* These eight are to add a device with another device's context - will be used to add machines' internal devices. */ void * -device_cadd(const device_t *d, const device_t *cd) +device_cadd(const device_t *dev, const device_t *cd) { - return device_add_common(d, cd, NULL, NULL, 0); + return device_add_common(dev, cd, NULL, NULL, 0); } void * -device_cadd_parameters(const device_t *d, const device_t *cd, void *params) +device_cadd_parameters(const device_t *dev, const device_t *cd, void *params) { - return device_add_common(d, cd, NULL, params, 0); + return device_add_common(dev, cd, NULL, params, 0); } /* For devices that do not have an init function (internal video etc.) */ void -device_cadd_ex(const device_t *d, const device_t *cd, void *priv) +device_cadd_ex(const device_t *dev, const device_t *cd, void *priv) { - device_add_common(d, cd, priv, NULL, 0); + device_add_common(dev, cd, priv, NULL, 0); } void -device_cadd_ex_parameters(const device_t *d, const device_t *cd, void *priv, void *params) +device_cadd_ex_parameters(const device_t *dev, const device_t *cd, void *priv, void *params) { - device_add_common(d, cd, priv, params, 0); + device_add_common(dev, cd, priv, params, 0); } void * -device_cadd_inst(const device_t *d, const device_t *cd, int inst) +device_cadd_inst(const device_t *dev, const device_t *cd, int inst) { - return device_add_common(d, cd, NULL, NULL, inst); + return device_add_common(dev, cd, NULL, NULL, inst); } void * -device_cadd_inst_parameters(const device_t *d, const device_t *cd, int inst, void *params) +device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params) { - return device_add_common(d, cd, NULL, params, inst); + return device_add_common(dev, cd, NULL, params, inst); } /* For devices that do not have an init function (internal video etc.) */ void -device_cadd_inst_ex(const device_t *d, const device_t *cd, void *priv, int inst) +device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst) { - device_add_common(d, cd, priv, NULL, inst); + device_add_common(dev, cd, priv, NULL, inst); } void -device_cadd_inst_ex_parameters(const device_t *d, const device_t *cd, void *priv, int inst, void *params) +device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params) { - device_add_common(d, cd, priv, params, inst); + device_add_common(dev, cd, priv, params, inst); +} + +void * +device_get_common_priv(void) +{ + return device_common_priv; } void @@ -328,11 +348,28 @@ device_reset_all(uint32_t match_flags) } void * -device_get_priv(const device_t *d) +device_find_first_priv(uint32_t match_flags) { + void *ret = NULL; + for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { - if (devices[c] == d) + if ((device_priv[c] != NULL) && (devices[c]->flags & match_flags)) { + ret = device_priv[c]; + break; + } + } + } + + return ret; +} + +void * +device_get_priv(const device_t *dev) +{ + for (uint16_t c = 0; c < DEVICE_MAX; c++) { + if (devices[c] != NULL) { + if (devices[c] == dev) return (device_priv[c]); } } @@ -341,25 +378,25 @@ device_get_priv(const device_t *d) } int -device_available(const device_t *d) +device_available(const device_t *dev) { - device_config_t *config = NULL; - device_config_bios_t *bios = NULL; - int roms_present = 0; - int i = 0; + const device_config_t *config = NULL; + const device_config_bios_t *bios = NULL; + int roms_present = 0; + int i = 0; - if (d != NULL) { - config = (device_config_t *) d->config; + if (dev != NULL) { + config = dev->config; if (config != NULL) { while (config->type != -1) { if (config->type == CONFIG_BIOS) { - bios = (device_config_bios_t *) config->bios; + bios = (const device_config_bios_t *) config->bios; /* Go through the ROM's in the device configuration. */ while (bios->files_no != 0) { i = 0; for (int bf = 0; bf < bios->files_no; bf++) - i += !!rom_present((char *) bios->files[bf]); + i += !!rom_present(bios->files[bf]); if (i == bios->files_no) roms_present++; bios++; @@ -372,8 +409,8 @@ device_available(const device_t *d) } /* No CONFIG_BIOS field present, use the classic available(). */ - if (d->available != NULL) - return (d->available()); + if (dev->available != NULL) + return (dev->available()); else return 1; } @@ -383,17 +420,17 @@ device_available(const device_t *d) } const char * -device_get_bios_file(const device_t *d, const char *internal_name, int file_no) +device_get_bios_file(const device_t *dev, const char *internal_name, int file_no) { - device_config_t *config = NULL; - device_config_bios_t *bios = NULL; + const device_config_t *config = NULL; + const device_config_bios_t *bios = NULL; - if (d != NULL) { - config = (device_config_t *) d->config; + if (dev != NULL) { + config = dev->config; if (config != NULL) { while (config->type != -1) { if (config->type == CONFIG_BIOS) { - bios = (device_config_bios_t *) config->bios; + bios = config->bios; /* Go through the ROM's in the device configuration. */ while (bios->files_no != 0) { @@ -416,18 +453,18 @@ device_get_bios_file(const device_t *d, const char *internal_name, int file_no) } int -device_has_config(const device_t *d) +device_has_config(const device_t *dev) { - int c = 0; - device_config_t *config; + int c = 0; + const device_config_t *config; - if (d == NULL) + if (dev == NULL) return 0; - if (d->config == NULL) + if (dev->config == NULL) return 0; - config = (device_config_t *) d->config; + config = dev->config; while (config->type != -1) { if (config->type != CONFIG_MAC) @@ -439,13 +476,13 @@ device_has_config(const device_t *d) } int -device_poll(const device_t *d, int x, int y, int z, int b) +device_poll(const device_t *dev) { for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { - if (devices[c] == d) { + if (devices[c] == dev) { if (devices[c]->poll) - return (devices[c]->poll(x, y, z, b, 0, 0, device_priv[c])); + return (devices[c]->poll(device_priv[c])); } } } @@ -454,54 +491,38 @@ device_poll(const device_t *d, int x, int y, int z, int b) } void -device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd) +device_get_name(const device_t *dev, int bus, char *name) { - for (uint16_t c = 0; c < DEVICE_MAX; c++) { - if (devices[c] != NULL) { - if (devices[c] == d) { - if (devices[c]->register_pci_slot) - devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]); - return; - } - } - } + const char *sbus = NULL; + const char *fbus; + char *tname; + char pbus[8] = { 0 }; - return; -} - -void -device_get_name(const device_t *d, int bus, char *name) -{ - char *sbus = NULL; - char *fbus; - char *tname; - char pbus[8] = { 0 }; - - if (d == NULL) + if (dev == NULL) return; name[0] = 0x00; if (bus) { - if (d->flags & DEVICE_ISA) - sbus = (d->flags & DEVICE_AT) ? "ISA16" : "ISA"; - else if (d->flags & DEVICE_CBUS) + if (dev->flags & DEVICE_ISA) + sbus = (dev->flags & DEVICE_AT) ? "ISA16" : "ISA"; + else if (dev->flags & DEVICE_CBUS) sbus = "C-BUS"; - else if (d->flags & DEVICE_MCA) + else if (dev->flags & DEVICE_MCA) sbus = "MCA"; - else if (d->flags & DEVICE_EISA) + else if (dev->flags & DEVICE_EISA) sbus = "EISA"; - else if (d->flags & DEVICE_VLB) + else if (dev->flags & DEVICE_VLB) sbus = "VLB"; - else if (d->flags & DEVICE_PCI) + else if (dev->flags & DEVICE_PCI) sbus = "PCI"; - else if (d->flags & DEVICE_AGP) + else if (dev->flags & DEVICE_AGP) sbus = "AGP"; - else if (d->flags & DEVICE_AC97) + else if (dev->flags & DEVICE_AC97) sbus = "AMR"; - else if (d->flags & DEVICE_COM) + else if (dev->flags & DEVICE_COM) sbus = "COM"; - else if (d->flags & DEVICE_LPT) + else if (dev->flags & DEVICE_LPT) sbus = "LPT"; if (sbus != NULL) { @@ -515,7 +536,7 @@ device_get_name(const device_t *d, int bus, char *name) sbus = "ISA"; else if (!strcmp(sbus, "COM") || !strcmp(sbus, "LPT")) { sbus = NULL; - strcat(name, d->name); + strcat(name, dev->name); return; } @@ -525,17 +546,17 @@ device_get_name(const device_t *d, int bus, char *name) strcat(pbus, ")"); /* Allocate the temporary device name string and set it to all zeroes. */ - tname = (char *) malloc(strlen(d->name) + 1); - memset(tname, 0x00, strlen(d->name) + 1); + tname = (char *) malloc(strlen(dev->name) + 1); + memset(tname, 0x00, strlen(dev->name) + 1); /* First strip the bus string with parentheses. */ - fbus = strstr(d->name, pbus); - if (fbus == d->name) - strcat(tname, d->name + strlen(pbus) + 1); + fbus = strstr(dev->name, pbus); + if (fbus == dev->name) + strcat(tname, dev->name + strlen(pbus) + 1); else if (fbus == NULL) - strcat(tname, d->name); + strcat(tname, dev->name); else { - strncat(tname, d->name, fbus - d->name - 1); + strncat(tname, dev->name, fbus - dev->name - 1); strcat(tname, fbus + strlen(pbus)); } @@ -556,9 +577,9 @@ device_get_name(const device_t *d, int bus, char *name) free(tname); tname = NULL; } else - strcat(name, d->name); + strcat(name, dev->name); } else - strcat(name, d->name); + strcat(name, dev->name); } void @@ -566,6 +587,8 @@ device_speed_changed(void) { for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { + device_log("DEVICE: device '%s' speed changed\n", devices[c]->name); + if (devices[c]->speed_changed != NULL) devices[c]->speed_changed(device_priv[c]); } @@ -747,31 +770,55 @@ device_is_valid(const device_t *device, int m) if (device == NULL) return 1; + if ((device->flags & DEVICE_PCJR) && !machine_has_bus(m, MACHINE_BUS_PCJR)) + return 0; + + if ((device->flags & DEVICE_XTKBC) && machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) + return 0; + if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16)) return 0; - if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) + if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) return 0; if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA)) return 0; + if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) + return 0; + + if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA)) + return 0; + if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA)) return 0; + if ((device->flags & DEVICE_HIL) && !machine_has_bus(m, MACHINE_BUS_HIL)) + return 0; + if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA)) return 0; + if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB)) + return 0; + if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB)) return 0; if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI)) return 0; + if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS)) + return 0; + + if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB)) + return 0; + if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP)) return 0; - if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2)) + if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS)) return 0; if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97)) @@ -819,3 +866,9 @@ machine_get_config_string(char *s) return NULL; } + +const device_t* +device_context_get_device(void) +{ + return device_current.dev; +} diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index ef3a392ee2..9c5705325d 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -17,12 +17,16 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c + postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c + smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c - mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c - mouse_wacom_tablet.c serial_passthrough.c) + mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c + serial_passthrough.c) + +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_link_libraries(86Box atomic) +endif() if(ISAMEM_RAMPAGE) target_compile_definitions(dev PRIVATE USE_ISAMEM_RAMPAGE) diff --git a/src/device/bugger.c b/src/device/bugger.c index 05df6530e9..c2678d66a4 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -266,7 +266,7 @@ bug_reset(void) /* Handle a WRITE operation to one of our registers. */ static void -bug_write(uint16_t port, uint8_t val, void *priv) +bug_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { switch (port - BUGGER_ADDR) { case BUG_CTRL: /* control register */ @@ -284,12 +284,14 @@ bug_write(uint16_t port, uint8_t val, void *priv) bug_wdata(val); } break; + default: + break; } } /* Handle a READ operation from one of our registers. */ static uint8_t -bug_read(uint16_t port, void *priv) +bug_read(uint16_t port, UNUSED(void *priv)) { uint8_t ret = 0xff; @@ -319,7 +321,7 @@ bug_read(uint16_t port, void *priv) /* Initialize the ISA BusBugger emulator. */ static void * -bug_init(const device_t *info) +bug_init(UNUSED(const device_t *info)) { bugger_log("%s, I/O=%04x\n", info->name, BUGGER_ADDR); diff --git a/src/device/cartridge.c b/src/device/cartridge.c index 6f8424f70c..edabd3ed0e 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -29,8 +29,7 @@ #include <86box/machine.h> #include <86box/cartridge.h> -typedef struct -{ +typedef struct cart_t { uint8_t *buf; uint32_t base; } cart_t; @@ -62,13 +61,13 @@ cartridge_log(const char *fmt, ...) static uint8_t cart_read(uint32_t addr, void *priv) { - cart_t *dev = (cart_t *) priv; + const cart_t *dev = (cart_t *) priv; return dev->buf[addr - dev->base]; } static void -cart_load_error(int drive, char *fn) +cart_load_error(int drive, UNUSED(char *fn)) { cartridge_log("Cartridge: could not load '%s'\n", fn); memset(cart_fns[drive], 0, sizeof(cart_fns[drive])); @@ -91,16 +90,16 @@ cart_image_close(int drive) static void cart_image_load(int drive, char *fn) { - FILE *f; + FILE *fp; uint32_t size; uint32_t base = 0x00000000; cart_image_close(drive); - f = fopen(fn, "rb"); - if (fseek(f, 0, SEEK_END) == -1) + fp = fopen(fn, "rb"); + if (fseek(fp, 0, SEEK_END) == -1) fatal("cart_image_load(): Error seeking to the end of the file\n"); - size = ftell(f); + size = ftell(fp); if (size < 0x1200) { cartridge_log("cart_image_load(): File size %i is too small\n", size); cart_load_error(drive, fn); @@ -108,23 +107,23 @@ cart_image_load(int drive, char *fn) } if (size & 0x00000fff) { size -= 0x00000200; - fseek(f, 0x000001ce, SEEK_SET); - (void) !fread(&base, 1, 2, f); + fseek(fp, 0x000001ce, SEEK_SET); + (void) !fread(&base, 1, 2, fp); base <<= 4; - fseek(f, 0x00000200, SEEK_SET); + fseek(fp, 0x00000200, SEEK_SET); carts[drive].buf = (uint8_t *) malloc(size); memset(carts[drive].buf, 0x00, size); - (void) !fread(carts[drive].buf, 1, size, f); - fclose(f); + (void) !fread(carts[drive].buf, 1, size, fp); + fclose(fp); } else { base = drive ? 0xe0000 : 0xd0000; if (size == 32768) base += 0x8000; - fseek(f, 0x00000000, SEEK_SET); + fseek(fp, 0x00000000, SEEK_SET); carts[drive].buf = (uint8_t *) malloc(size); memset(carts[drive].buf, 0x00, size); - (void) !fread(carts[drive].buf, 1, size, f); - fclose(f); + (void) !fread(carts[drive].buf, 1, size, fp); + fclose(fp); } cartridge_log("cart_image_load(): %s at %08X-%08X\n", fn, base, base + size - 1); @@ -137,15 +136,15 @@ cart_image_load(int drive, char *fn) static void cart_load_common(int drive, char *fn, uint8_t hard_reset) { - FILE *f; + FILE *fp; cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn); if (!fn) return; - f = plat_fopen(fn, "rb"); - if (f) { - fclose(f); + fp = plat_fopen(fn, "rb"); + if (fp) { + fclose(fp); strcpy(cart_fns[drive], fn); cart_image_load(drive, cart_fns[drive]); /* On the real PCjr, inserting a cartridge causes a reset diff --git a/src/device/cassette.c b/src/device/cassette.c index 4582e0751b..1d0b885314 100644 --- a/src/device/cassette.c +++ b/src/device/cassette.c @@ -544,7 +544,7 @@ pc_cas_set_out(pc_cassette_t *cas, unsigned char val) } void -pc_cas_print_state(const pc_cassette_t *cas) +pc_cas_print_state(UNUSED(const pc_cassette_t *cas)) { cassette_log("%s %s %lu %s %lu\n", (cas->fname != NULL) ? cas->fname : "", cas->pcm ? "pcm" : "cas", cas->srate, cas->save ? "save" : "load", cas->position); } @@ -552,9 +552,8 @@ pc_cas_print_state(const pc_cassette_t *cas) static void pc_cas_clock_pcm(pc_cassette_t *cas, unsigned long cnt) { - unsigned long i; - unsigned long n; - int v = 0; + uint64_t n; + int v = 0; n = cas->srate * cnt + cas->clk_pcm; @@ -567,11 +566,11 @@ pc_cas_clock_pcm(pc_cassette_t *cas, unsigned long cnt) } if (cas->save) { - for (i = 0; i < n; i++) { + for (uint64_t i = 0; i < n; i++) { pc_cas_write_smp(cas, cas->pcm_out_val); } } else { - for (i = 0; i < n; i++) { + for (uint64_t i = 0; i < n; i++) { v = pc_cas_read_smp(cas); } @@ -642,7 +641,7 @@ pc_cas_advance(pc_cassette_t *cas) } static void -cassette_close(void *p) +cassette_close(UNUSED(void *priv)) { if (cassette != NULL) { free(cassette); @@ -651,9 +650,9 @@ cassette_close(void *p) } static void -cassette_callback(void *p) +cassette_callback(void *priv) { - pc_cassette_t *cas = (pc_cassette_t *) p; + pc_cassette_t *cas = (pc_cassette_t *) priv; pc_cas_clock(cas, 8); @@ -664,7 +663,7 @@ cassette_callback(void *p) } static void * -cassette_init(const device_t *info) +cassette_init(UNUSED(const device_t *info)) { cassette = NULL; diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index 0fedfaef76..2631707416 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -26,6 +26,7 @@ #include <86box/i2c.h> #include "cpu.h" #include <86box/clock.h> +#include <86box/plat_unused.h> #ifdef ENABLE_ICS9xxx_LOG int ics9xxx_do_log = ENABLE_ICS9xxx_LOG; @@ -51,26 +52,26 @@ ics9xxx_log(const char *fmt, ...) , #define agp_div ram_mult /* temporarily saves space while neither field matters */ -typedef struct { +typedef struct ics9xxx_frequency_t { uint16_t bus : 15; uint8_t ram_mult : 2; /* change to full float when this becomes useful */ uint8_t pci_div : 3; } ics9xxx_frequency_t; -typedef struct { +typedef struct ics9xxx_model_t { #if defined(ENABLE_ICS9xxx_LOG) || defined(ENABLE_ICS9xxx_DETECT) const char *name; /* populated by macro */ #endif uint8_t max_reg : 3; /* largest register index */ uint8_t regs[7]; /* default registers */ - struct { /* for each hardware frequency select bit [FS0:FS4]: */ + struct fs_regs { /* for each hardware frequency select bit [FS0:FS4]: */ uint8_t normal_reg : 3; /* which register (or -1) for non-inverted input (FSn) */ uint8_t normal_bit : 3; /* which bit (0-7) for non-inverted input (FSn) */ uint8_t inv_reg : 3; /* which register (or -1) for inverted input (FSn#) */ uint8_t inv_bit : 3; /* which bit (0-7) for inverted input (FSn#) */ } fs_regs[5]; uint8_t normal_bits_fixed : 1; /* set to 1 if the non-inverted bits are straps (hardware select only) */ - struct { /* hardware select bit, which should be cleared for hardware select (latched inputs), or set for programming */ + struct hw_select { /* hardware select bit, which should be cleared for hardware select (latched inputs), or set for programming */ uint8_t normal_reg : 3; /* which register (or -1) */ uint8_t normal_bit : 3; /* which bit (0-7) */ } hw_select; @@ -79,7 +80,7 @@ typedef struct { const ics9xxx_frequency_t *frequencies; /* frequency table, if not using another model's table */ } ics9xxx_model_t; -typedef struct { +typedef struct ics9xxx_t { uint8_t model_idx; ics9xxx_model_t *model; device_t *dyn_device; @@ -98,811 +99,811 @@ static const ics9xxx_model_t ics9xxx_models[] = { = 6 ICS9xxx_MODEL_END() #endif ICS9xxx_MODEL(ICS9150_08) - .max_reg = 5, - .regs = {0x00, 0xff, 0xff, 0xff, 0x6f, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 5000, .pci_div = 2}, - {.bus = 7500, .pci_div = 2}, - {.bus = 8333, .pci_div = 2}, - {.bus = 6680, .pci_div = 2}, - {.bus = 10300, .pci_div = 3}, - {.bus = 11200, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 10020, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x00, 0xff, 0xff, 0xff, 0x6f, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 5000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8333, .pci_div = 2}, + {.bus = 6680, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11200, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 10020, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_39) - .max_reg = 5, - .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff}, - .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies_ref = ICS9250_08 + .max_reg = 5, + .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff}, + .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies_ref = ICS9250_08 ICS9xxx_MODEL_END() #ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9248_81) - .max_reg = 5, - .regs = {0x82, 0xfe, 0x7f, 0xff, 0xff, 0xb7}, - .fs_regs = {{0, 4, 1, 0}, {0, 5, 2, 7}, {0, 6, 5, 6}, {0, 2, 5, 3}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 9000, .ram_mult = 1, .pci_div = 3}, - {.bus = 6670, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 9500, .ram_mult = 2.0/3.0, .pci_div = 3}, - {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, - {.bus = 10000, .ram_mult = 0.75, .pci_div = 3}, - {.bus = 11200, .ram_mult = 2.0/3.0, .pci_div = 3}, - {.bus = 12400, .ram_mult = 2.0/3.0, .pci_div = 4}, - {.bus = 13330, .ram_mult = 2.0/3.0, .pci_div = 4}, - {.bus = 6670, .ram_mult = 1, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1, .pci_div = 3}, - {.bus = 8330, .ram_mult = 1, .pci_div = 3}, - {.bus = 9500, .ram_mult = 1, .pci_div = 3}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 11200, .ram_mult = 1, .pci_div = 3}, - {.bus = 12400, .ram_mult = 1, .pci_div = 4}, - {.bus = 13330, .ram_mult = 1, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x82, 0xfe, 0x7f, 0xff, 0xff, 0xb7}, + .fs_regs = {{0, 4, 1, 0}, {0, 5, 2, 7}, {0, 6, 5, 6}, {0, 2, 5, 3}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 9000, .ram_mult = 1, .pci_div = 3}, + {.bus = 6670, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 9500, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 10000, .ram_mult = 0.75, .pci_div = 3}, + {.bus = 11200, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 12400, .ram_mult = 2.0/3.0, .pci_div = 4}, + {.bus = 13330, .ram_mult = 2.0/3.0, .pci_div = 4}, + {.bus = 6670, .ram_mult = 1, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1, .pci_div = 3}, + {.bus = 8330, .ram_mult = 1, .pci_div = 3}, + {.bus = 9500, .ram_mult = 1, .pci_div = 3}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 11200, .ram_mult = 1, .pci_div = 3}, + {.bus = 12400, .ram_mult = 1, .pci_div = 4}, + {.bus = 13330, .ram_mult = 1, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_95) - .max_reg = 5, - .regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .pci_div = 2}, - {.bus = 10000, .pci_div = 3}, - {.bus = 10030, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 10500, .pci_div = 3}, - {.bus = 13337, .pci_div = 4}, - {.bus = 13700, .pci_div = 4}, - {.bus = 7500, .pci_div = 2}, - {.bus = 10000, .pci_div = 3}, - {.bus = 9500, .pci_div = 2}, - {.bus = 9700, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 9000, .pci_div = 3}, - {.bus = 9622, .pci_div = 3}, - {.bus = 6681, .pci_div = 2}, - {.bus = 9150, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .pci_div = 2}, + {.bus = 10000, .pci_div = 3}, + {.bus = 10030, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 10500, .pci_div = 3}, + {.bus = 13337, .pci_div = 4}, + {.bus = 13700, .pci_div = 4}, + {.bus = 7500, .pci_div = 2}, + {.bus = 10000, .pci_div = 3}, + {.bus = 9500, .pci_div = 2}, + {.bus = 9700, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 9000, .pci_div = 3}, + {.bus = 9622, .pci_div = 3}, + {.bus = 6681, .pci_div = 2}, + {.bus = 9150, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_98) - .max_reg = 6, - .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff, 0x06}, - .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {0, 2, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 8000, .pci_div = 2}, - {.bus = 7500, .pci_div = 2}, - {.bus = 8331, .pci_div = 2}, - {.bus = 6682, .pci_div = 2}, - {.bus = 10300, .pci_div = 3}, - {.bus = 11201, .pci_div = 3}, - {.bus = 6801, .pci_div = 2}, - {.bus = 10023, .pci_div = 3}, - {.bus = 12000, .pci_div = 3}, - {.bus = 11499, .pci_div = 3}, - {.bus = 10999, .pci_div = 3}, - {.bus = 10500, .pci_div = 3}, - {.bus = 14000, .pci_div = 4}, - {.bus = 15000, .pci_div = 4}, - {.bus = 12400, .pci_div = 4}, - {.bus = 13299, .pci_div = 4}, - {.bus = 13500, .pci_div = 4}, - {.bus = 12999, .pci_div = 4}, - {.bus = 12600, .pci_div = 4}, - {.bus = 11800, .pci_div = 3}, - {.bus = 11598, .pci_div = 3}, - {.bus = 9500, .pci_div = 3}, - {.bus = 9000, .pci_div = 3}, - {.bus = 8501, .pci_div = 3}, - {.bus = 16600, .pci_div = 4}, - {.bus = 16001, .pci_div = 4}, - {.bus = 15499, .pci_div = 4}, - {.bus = 14795, .pci_div = 4}, - {.bus = 14598, .pci_div = 4}, - {.bus = 14398, .pci_div = 4}, - {.bus = 14199, .pci_div = 4}, - {.bus = 13801, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff, 0x06}, + .fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {0, 2, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 8000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8331, .pci_div = 2}, + {.bus = 6682, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11201, .pci_div = 3}, + {.bus = 6801, .pci_div = 2}, + {.bus = 10023, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11499, .pci_div = 3}, + {.bus = 10999, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13299, .pci_div = 4}, + {.bus = 13500, .pci_div = 4}, + {.bus = 12999, .pci_div = 4}, + {.bus = 12600, .pci_div = 4}, + {.bus = 11800, .pci_div = 3}, + {.bus = 11598, .pci_div = 3}, + {.bus = 9500, .pci_div = 3}, + {.bus = 9000, .pci_div = 3}, + {.bus = 8501, .pci_div = 3}, + {.bus = 16600, .pci_div = 4}, + {.bus = 16001, .pci_div = 4}, + {.bus = 15499, .pci_div = 4}, + {.bus = 14795, .pci_div = 4}, + {.bus = 14598, .pci_div = 4}, + {.bus = 14398, .pci_div = 4}, + {.bus = 14199, .pci_div = 4}, + {.bus = 13801, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_101) - .max_reg = 5, - .regs = {0x82, 0xff, 0xff, 0xff, 0xf5, 0xff}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 12400, .pci_div = 3}, - {.bus = 12000, .pci_div = 3}, - {.bus = 11499, .pci_div = 3}, - {.bus = 10999, .pci_div = 3}, - {.bus = 10500, .pci_div = 3}, - {.bus = 8331, .pci_div = 2}, - {.bus = 13700, .pci_div = 4}, - {.bus = 7500, .pci_div = 2}, - {.bus = 10000, .pci_div = 3}, - {.bus = 9500, .pci_div = 3}, - {.bus = 8331, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 9000, .pci_div = 3}, - {.bus = 9622, .pci_div = 3}, - {.bus = 6682, .pci_div = 2}, - {.bus = 9150, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x82, 0xff, 0xff, 0xff, 0xf5, 0xff}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 12400, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11499, .pci_div = 3}, + {.bus = 10999, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 8331, .pci_div = 2}, + {.bus = 13700, .pci_div = 4}, + {.bus = 7500, .pci_div = 2}, + {.bus = 10000, .pci_div = 3}, + {.bus = 9500, .pci_div = 3}, + {.bus = 8331, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 9000, .pci_div = 3}, + {.bus = 9622, .pci_div = 3}, + {.bus = 6682, .pci_div = 2}, + {.bus = 9150, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_103) - .max_reg = 5, - .regs = {0x82, 0xff, 0xff, 0xff, 0xf5, 0xff}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies_ref = ICS9248_101 + .max_reg = 5, + .regs = {0x82, 0xff, 0xff, 0xff, 0xf5, 0xff}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies_ref = ICS9248_101 ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_107) - .max_reg = 6, - .regs = {0x02, 0xff, 0xff, 0xec, 0xde, 0xff, 0x06}, - .fs_regs = {{0, 4, 4, 5}, {0, 5, 3, 4}, {0, 6, 3, 0}, {0, 7, 3, 1}, {0, 2, 4, 0}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 10300, .pci_div = 3}, - {.bus = 10000, .pci_div = 3}, - {.bus = 10045, .pci_div = 3}, - {.bus = 10090, .pci_div = 3}, - {.bus = 10710, .pci_div = 2}, - {.bus = 10900, .pci_div = 3}, - {.bus = 11200, .pci_div = 3}, - {.bus = 11400, .pci_div = 4}, - {.bus = 11600, .pci_div = 4}, - {.bus = 11800, .pci_div = 4}, - {.bus = 13330, .pci_div = 3}, - {.bus = 12000, .pci_div = 4}, - {.bus = 12200, .pci_div = 4}, - {.bus = 12500, .pci_div = 4}, - {.bus = 5000, .pci_div = 2}, - {.bus = 6670, .pci_div = 4}, - {.bus = 13330, .pci_div = 3}, - {.bus = 13390, .pci_div = 3}, - {.bus = 13800, .pci_div = 4}, - {.bus = 14200, .pci_div = 4}, - {.bus = 14600, .pci_div = 4}, - {.bus = 15000, .pci_div = 4}, - {.bus = 15300, .pci_div = 4}, - {.bus = 15600, .pci_div = 4}, - {.bus = 15910, .pci_div = 3}, - {.bus = 16200, .pci_div = 4}, - {.bus = 16670, .pci_div = 4}, - {.bus = 16800, .pci_div = 4}, - {.bus = 17100, .pci_div = 4}, - {.bus = 17400, .pci_div = 4}, - {.bus = 17700, .pci_div = 4}, - {.bus = 18000, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0xff, 0xff, 0xec, 0xde, 0xff, 0x06}, + .fs_regs = {{0, 4, 4, 5}, {0, 5, 3, 4}, {0, 6, 3, 0}, {0, 7, 3, 1}, {0, 2, 4, 0}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 10300, .pci_div = 3}, + {.bus = 10000, .pci_div = 3}, + {.bus = 10045, .pci_div = 3}, + {.bus = 10090, .pci_div = 3}, + {.bus = 10710, .pci_div = 2}, + {.bus = 10900, .pci_div = 3}, + {.bus = 11200, .pci_div = 3}, + {.bus = 11400, .pci_div = 4}, + {.bus = 11600, .pci_div = 4}, + {.bus = 11800, .pci_div = 4}, + {.bus = 13330, .pci_div = 3}, + {.bus = 12000, .pci_div = 4}, + {.bus = 12200, .pci_div = 4}, + {.bus = 12500, .pci_div = 4}, + {.bus = 5000, .pci_div = 2}, + {.bus = 6670, .pci_div = 4}, + {.bus = 13330, .pci_div = 3}, + {.bus = 13390, .pci_div = 3}, + {.bus = 13800, .pci_div = 4}, + {.bus = 14200, .pci_div = 4}, + {.bus = 14600, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 15300, .pci_div = 4}, + {.bus = 15600, .pci_div = 4}, + {.bus = 15910, .pci_div = 3}, + {.bus = 16200, .pci_div = 4}, + {.bus = 16670, .pci_div = 4}, + {.bus = 16800, .pci_div = 4}, + {.bus = 17100, .pci_div = 4}, + {.bus = 17400, .pci_div = 4}, + {.bus = 17700, .pci_div = 4}, + {.bus = 18000, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_112) - .max_reg = 6, - .regs = {0x02, 0x1f, 0xff, 0xff, 0xfb, 0xff, 0x06}, - .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6800, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10030, .ram_mult = 1, .pci_div = 3}, - {.bus = 10300, .ram_mult = 1, .pci_div = 3}, - {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13733, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 1, .pci_div = 2}, - {.bus = 11800, .ram_mult = 1, .pci_div = 3}, - {.bus = 12400, .ram_mult = 1, .pci_div = 3}, - {.bus = 13369, .ram_mult = 1, .pci_div = 2}, - {.bus = 13700, .ram_mult = 1, .pci_div = 2}, - {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 7250, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8300, .ram_mult = 1, .pci_div = 6}, - {.bus = 11000, .ram_mult = 1, .pci_div = 2}, - {.bus = 12000, .ram_mult = 1, .pci_div = 3}, - {.bus = 12500, .ram_mult = 1, .pci_div = 2}, - {.bus = 6925, .ram_mult = 1.5, .pci_div = 1}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 14500, .ram_mult = 1, .pci_div = 3}, - {.bus = 6650, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 15000, .ram_mult = 1, .pci_div = 3}, - {.bus = 9975, .ram_mult = 1, .pci_div = 3}, - {.bus = 15500, .ram_mult = 1, .pci_div = 2}, - {.bus = 16650, .ram_mult = 1, .pci_div = 3}, - {.bus = 15333, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13300, .ram_mult = 0.75, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xfb, 0xff, 0x06}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6800, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13733, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 2}, + {.bus = 11800, .ram_mult = 1, .pci_div = 3}, + {.bus = 12400, .ram_mult = 1, .pci_div = 3}, + {.bus = 13369, .ram_mult = 1, .pci_div = 2}, + {.bus = 13700, .ram_mult = 1, .pci_div = 2}, + {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 7250, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8300, .ram_mult = 1, .pci_div = 6}, + {.bus = 11000, .ram_mult = 1, .pci_div = 2}, + {.bus = 12000, .ram_mult = 1, .pci_div = 3}, + {.bus = 12500, .ram_mult = 1, .pci_div = 2}, + {.bus = 6925, .ram_mult = 1.5, .pci_div = 1}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 14500, .ram_mult = 1, .pci_div = 3}, + {.bus = 6650, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 15000, .ram_mult = 1, .pci_div = 3}, + {.bus = 9975, .ram_mult = 1, .pci_div = 3}, + {.bus = 15500, .ram_mult = 1, .pci_div = 2}, + {.bus = 16650, .ram_mult = 1, .pci_div = 3}, + {.bus = 15333, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13300, .ram_mult = 0.75, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_138) - .max_reg = 6, - .regs = {0x02, 0x3f, 0x7f, 0x6f, 0xff, 0xff, 0x06}, - .fs_regs = {{0, 4, 2, 7}, {0, 5, 1, 6}, {0, 6, 1, 7}, {0, 7, 3, 4}, {0, 2, 3, 7}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6687, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6867, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7134, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 10030, .ram_mult = 1, .pci_div = 3}, - {.bus = 10300, .ram_mult = 1, .pci_div = 3}, - {.bus = 10700, .ram_mult = 1, .pci_div = 2}, - {.bus = 13333, .ram_mult = 1, .pci_div = 4}, - {.bus = 13372, .ram_mult = 1, .pci_div = 4}, - {.bus = 13733, .ram_mult = 1, .pci_div = 4}, - {.bus = 12000, .ram_mult = 1, .pci_div = 4}, - {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13733, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 12000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13600, .ram_mult = 1, .pci_div = 4}, - {.bus = 14000, .ram_mult = 1, .pci_div = 4}, - {.bus = 14266, .ram_mult = 1, .pci_div = 3}, - {.bus = 14533, .ram_mult = 1, .pci_div = 4}, - {.bus = 13600, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14266, .ram_mult = 0.75, .pci_div = 3}, - {.bus = 14533, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14666, .ram_mult = 1, .pci_div = 3}, - {.bus = 15333, .ram_mult = 1, .pci_div = 4}, - {.bus = 16000, .ram_mult = 1, .pci_div = 4}, - {.bus = 16667, .ram_mult = 1, .pci_div = 3}, - {.bus = 14666, .ram_mult = 0.75, .pci_div = 3}, - {.bus = 16000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 16667, .ram_mult = 0.75, .pci_div = 3}, - {.bus = 20000, .ram_mult = 1, .pci_div = 6}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x3f, 0x7f, 0x6f, 0xff, 0xff, 0x06}, + .fs_regs = {{0, 4, 2, 7}, {0, 5, 1, 6}, {0, 6, 1, 7}, {0, 7, 3, 4}, {0, 2, 3, 7}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6687, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6867, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7134, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 10700, .ram_mult = 1, .pci_div = 2}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 13372, .ram_mult = 1, .pci_div = 4}, + {.bus = 13733, .ram_mult = 1, .pci_div = 4}, + {.bus = 12000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13372, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13733, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 12000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13600, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14266, .ram_mult = 1, .pci_div = 3}, + {.bus = 14533, .ram_mult = 1, .pci_div = 4}, + {.bus = 13600, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14266, .ram_mult = 0.75, .pci_div = 3}, + {.bus = 14533, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14666, .ram_mult = 1, .pci_div = 3}, + {.bus = 15333, .ram_mult = 1, .pci_div = 4}, + {.bus = 16000, .ram_mult = 1, .pci_div = 4}, + {.bus = 16667, .ram_mult = 1, .pci_div = 3}, + {.bus = 14666, .ram_mult = 0.75, .pci_div = 3}, + {.bus = 16000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16667, .ram_mult = 0.75, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1, .pci_div = 6}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_141) - .max_reg = 6, - .regs = {0x02, 0x6b, 0x7f, 0xff, 0xff, 0xe7, 0x06}, - .fs_regs = {{0, 4, 2, 7}, {0, 5, 5, 3}, {0, 6, 1, 7}, {0, 7, 1, 4}, {0, 2, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 9000, .pci_div = 3}, - {.bus = 9500, .pci_div = 2}, - {.bus = 10100, .pci_div = 2}, - {.bus = 10200, .pci_div = 3}, - {.bus = 10090, .pci_div = 3}, - {.bus = 10300, .pci_div = 3}, - {.bus = 10500, .pci_div = 3}, - {.bus = 10000, .pci_div = 3}, - {.bus = 10700, .pci_div = 2}, - {.bus = 10900, .pci_div = 3}, - {.bus = 11000, .pci_div = 2}, - {.bus = 11100, .pci_div = 3}, - {.bus = 11300, .pci_div = 2}, - {.bus = 11500, .pci_div = 3}, - {.bus = 11700, .pci_div = 3}, - {.bus = 13330, .pci_div = 3}, - {.bus = 12000, .pci_div = 3}, - {.bus = 12500, .pci_div = 4}, - {.bus = 13000, .pci_div = 4}, - {.bus = 13372, .pci_div = 4}, - {.bus = 13500, .pci_div = 4}, - {.bus = 13700, .pci_div = 4}, - {.bus = 13900, .pci_div = 4}, - {.bus = 10000, .pci_div = 3}, - {.bus = 14000, .pci_div = 4}, - {.bus = 14300, .pci_div = 4}, - {.bus = 14500, .pci_div = 4}, - {.bus = 14800, .pci_div = 4}, - {.bus = 15000, .pci_div = 4}, - {.bus = 15500, .pci_div = 4}, - {.bus = 16666, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x6b, 0x7f, 0xff, 0xff, 0xe7, 0x06}, + .fs_regs = {{0, 4, 2, 7}, {0, 5, 5, 3}, {0, 6, 1, 7}, {0, 7, 1, 4}, {0, 2, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 9000, .pci_div = 3}, + {.bus = 9500, .pci_div = 2}, + {.bus = 10100, .pci_div = 2}, + {.bus = 10200, .pci_div = 3}, + {.bus = 10090, .pci_div = 3}, + {.bus = 10300, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 10000, .pci_div = 3}, + {.bus = 10700, .pci_div = 2}, + {.bus = 10900, .pci_div = 3}, + {.bus = 11000, .pci_div = 2}, + {.bus = 11100, .pci_div = 3}, + {.bus = 11300, .pci_div = 2}, + {.bus = 11500, .pci_div = 3}, + {.bus = 11700, .pci_div = 3}, + {.bus = 13330, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 12500, .pci_div = 4}, + {.bus = 13000, .pci_div = 4}, + {.bus = 13372, .pci_div = 4}, + {.bus = 13500, .pci_div = 4}, + {.bus = 13700, .pci_div = 4}, + {.bus = 13900, .pci_div = 4}, + {.bus = 10000, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 14300, .pci_div = 4}, + {.bus = 14500, .pci_div = 4}, + {.bus = 14800, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 15500, .pci_div = 4}, + {.bus = 16666, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_143) - .max_reg = 5, - .regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .pci_div = 2}, - {.bus = 10000, .pci_div = 3}, - {.bus = 10030, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 10500, .pci_div = 3}, - {.bus = 13337, .pci_div = 4}, - {.bus = 13700, .pci_div = 4}, - {.bus = 7500, .pci_div = 2}, - {.bus = 10000, .pci_div = 3}, - {.bus = 9500, .pci_div = 2}, - {.bus = 9700, .pci_div = 3}, - {.bus = 13333, .pci_div = 4}, - {.bus = 9000, .pci_div = 3}, - {.bus = 9622, .pci_div = 3}, - {.bus = 6681, .pci_div = 2}, - {.bus = 9150, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .pci_div = 2}, + {.bus = 10000, .pci_div = 3}, + {.bus = 10030, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 10500, .pci_div = 3}, + {.bus = 13337, .pci_div = 4}, + {.bus = 13700, .pci_div = 4}, + {.bus = 7500, .pci_div = 2}, + {.bus = 10000, .pci_div = 3}, + {.bus = 9500, .pci_div = 2}, + {.bus = 9700, .pci_div = 3}, + {.bus = 13333, .pci_div = 4}, + {.bus = 9000, .pci_div = 3}, + {.bus = 9622, .pci_div = 3}, + {.bus = 6681, .pci_div = 2}, + {.bus = 9150, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_151) - .max_reg = 6, - .regs = {0x80, 0x4f, 0xff, 0x3f, 0xff, 0xff, 0x06}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, -1, -1}, {0, 6, 3, 7}, {0, 1, 1, 4}, {0, 2, 1, 5}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 20000, .pci_div = 5, .agp_div = 2.5}, - {.bus = 19000, .pci_div = 5, .agp_div = 2.5}, - {.bus = 18000, .pci_div = 5, .agp_div = 2.5}, - {.bus = 17000, .pci_div = 5, .agp_div = 2.5}, - {.bus = 16600, .pci_div = 5, .agp_div = 2.5}, - {.bus = 16000, .pci_div = 5, .agp_div = 2.5}, - {.bus = 15000, .pci_div = 4, .agp_div = 2}, - {.bus = 14500, .pci_div = 4, .agp_div = 2}, - {.bus = 14000, .pci_div = 4, .agp_div = 2}, - {.bus = 13600, .pci_div = 4, .agp_div = 2}, - {.bus = 13000, .pci_div = 4, .agp_div = 2}, - {.bus = 12400, .pci_div = 4, .agp_div = 2}, - {.bus = 6667, .pci_div = 1, .agp_div = 1}, - {.bus = 10000, .pci_div = 3, .agp_div = 1.5}, - {.bus = 11800, .pci_div = 3, .agp_div = 1.5}, - {.bus = 13333, .pci_div = 3, .agp_div = 2}, - {.bus = 6680, .pci_div = 2, .agp_div = 1}, - {.bus = 10020, .pci_div = 3, .agp_div = 1.5}, - {.bus = 11500, .pci_div = 3, .agp_div = 1.5}, - {.bus = 13340, .pci_div = 4, .agp_div = 2}, - {.bus = 6680, .pci_div = 2, .agp_div = 1}, - {.bus = 10020, .pci_div = 3, .agp_div = 1.5}, - {.bus = 11000, .pci_div = 2, .agp_div = 1.5}, - {.bus = 13340, .pci_div = 4, .agp_div = 2}, - {.bus = 10500, .pci_div = 3, .agp_div = 1.5}, - {.bus = 9000, .pci_div = 3, .agp_div = 1.5}, - {.bus = 8500, .pci_div = 3, .agp_div = 1.5}, - {.bus = 7800, .pci_div = 2, .agp_div = 1}, - {.bus = 6667, .pci_div = 1, .agp_div = 1}, - {.bus = 10000, .pci_div = 3, .agp_div = 1.5}, - {.bus = 7500, .pci_div = 2, .agp_div = 1}, - {.bus = 13333, .pci_div = 3, .agp_div = 2}, - {0} - } + .max_reg = 6, + .regs = {0x80, 0x4f, 0xff, 0x3f, 0xff, 0xff, 0x06}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, -1, -1}, {0, 6, 3, 7}, {0, 1, 1, 4}, {0, 2, 1, 5}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 20000, .pci_div = 5, .agp_div = 2.5}, + {.bus = 19000, .pci_div = 5, .agp_div = 2.5}, + {.bus = 18000, .pci_div = 5, .agp_div = 2.5}, + {.bus = 17000, .pci_div = 5, .agp_div = 2.5}, + {.bus = 16600, .pci_div = 5, .agp_div = 2.5}, + {.bus = 16000, .pci_div = 5, .agp_div = 2.5}, + {.bus = 15000, .pci_div = 4, .agp_div = 2}, + {.bus = 14500, .pci_div = 4, .agp_div = 2}, + {.bus = 14000, .pci_div = 4, .agp_div = 2}, + {.bus = 13600, .pci_div = 4, .agp_div = 2}, + {.bus = 13000, .pci_div = 4, .agp_div = 2}, + {.bus = 12400, .pci_div = 4, .agp_div = 2}, + {.bus = 6667, .pci_div = 1, .agp_div = 1}, + {.bus = 10000, .pci_div = 3, .agp_div = 1.5}, + {.bus = 11800, .pci_div = 3, .agp_div = 1.5}, + {.bus = 13333, .pci_div = 3, .agp_div = 2}, + {.bus = 6680, .pci_div = 2, .agp_div = 1}, + {.bus = 10020, .pci_div = 3, .agp_div = 1.5}, + {.bus = 11500, .pci_div = 3, .agp_div = 1.5}, + {.bus = 13340, .pci_div = 4, .agp_div = 2}, + {.bus = 6680, .pci_div = 2, .agp_div = 1}, + {.bus = 10020, .pci_div = 3, .agp_div = 1.5}, + {.bus = 11000, .pci_div = 2, .agp_div = 1.5}, + {.bus = 13340, .pci_div = 4, .agp_div = 2}, + {.bus = 10500, .pci_div = 3, .agp_div = 1.5}, + {.bus = 9000, .pci_div = 3, .agp_div = 1.5}, + {.bus = 8500, .pci_div = 3, .agp_div = 1.5}, + {.bus = 7800, .pci_div = 2, .agp_div = 1}, + {.bus = 6667, .pci_div = 1, .agp_div = 1}, + {.bus = 10000, .pci_div = 3, .agp_div = 1.5}, + {.bus = 7500, .pci_div = 2, .agp_div = 1}, + {.bus = 13333, .pci_div = 3, .agp_div = 2}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9248_192) - .max_reg = 6, - .regs = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 7, -1, -1}, {0, 2, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6731, .pci_div = 2}, - {.bus = 6864, .pci_div = 2}, - {.bus = 6995, .pci_div = 2}, - {.bus = 7259, .pci_div = 2}, - {.bus = 6150, .pci_div = 2}, - {.bus = 6300, .pci_div = 2}, - {.bus = 6400, .pci_div = 2}, - {.bus = 6500, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 5000, .pci_div = 2}, - {.bus = 4800, .pci_div = 2}, - {.bus = 5880, .pci_div = 2}, - {.bus = 5760, .pci_div = 2}, - {.bus = 5640, .pci_div = 2}, - {.bus = 5400, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6000, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {.bus = 6659, .pci_div = 2}, - {0} - } + .max_reg = 6, + .regs = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 7, -1, -1}, {0, 2, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6731, .pci_div = 2}, + {.bus = 6864, .pci_div = 2}, + {.bus = 6995, .pci_div = 2}, + {.bus = 7259, .pci_div = 2}, + {.bus = 6150, .pci_div = 2}, + {.bus = 6300, .pci_div = 2}, + {.bus = 6400, .pci_div = 2}, + {.bus = 6500, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 5000, .pci_div = 2}, + {.bus = 4800, .pci_div = 2}, + {.bus = 5880, .pci_div = 2}, + {.bus = 5760, .pci_div = 2}, + {.bus = 5640, .pci_div = 2}, + {.bus = 5400, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6000, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {.bus = 6659, .pci_div = 2}, + {0} + } ICS9xxx_MODEL_END() #endif ICS9xxx_MODEL(ICS9250_08) - .max_reg = 5, - .regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 12400, .pci_div = 3}, - {.bus = 7500, .pci_div = 2}, - {.bus = 8333, .pci_div = 2}, - {.bus = 6680, .pci_div = 2}, - {.bus = 10300, .pci_div = 3}, - {.bus = 11200, .pci_div = 3}, - {.bus = 13300, .pci_div = 3}, - {.bus = 10030, .pci_div = 3}, - {.bus = 12000, .pci_div = 3}, - {.bus = 11500, .pci_div = 3}, - {.bus = 11000, .pci_div = 3}, - {.bus = 10500, .pci_div = 3}, - {.bus = 14000, .pci_div = 4}, - {.bus = 15000, .pci_div = 4}, - {.bus = 12400, .pci_div = 4}, - {.bus = 13300, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 12400, .pci_div = 3}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8333, .pci_div = 2}, + {.bus = 6680, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11200, .pci_div = 3}, + {.bus = 13300, .pci_div = 3}, + {.bus = 10030, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11500, .pci_div = 3}, + {.bus = 11000, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13300, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() #ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_10) - .max_reg = 5, - .regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06}, - .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {5, 4, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7067, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7466, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8266, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6350, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6867, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8866, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 10600, .ram_mult = 1, .pci_div = 3}, - {.bus = 11200, .ram_mult = 1, .pci_div = 3}, - {.bus = 12400, .ram_mult = 1, .pci_div = 3}, - {.bus = 9525, .ram_mult = 1, .pci_div = 3}, - {.bus = 10300, .ram_mult = 1, .pci_div = 3}, - {.bus = 10900, .ram_mult = 1, .pci_div = 3}, - {.bus = 13300, .ram_mult = 1, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06}, + .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {5, 4, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7067, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7466, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8266, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6350, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6867, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8866, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10600, .ram_mult = 1, .pci_div = 3}, + {.bus = 11200, .ram_mult = 1, .pci_div = 3}, + {.bus = 12400, .ram_mult = 1, .pci_div = 3}, + {.bus = 9525, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 10900, .ram_mult = 1, .pci_div = 3}, + {.bus = 13300, .ram_mult = 1, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_13) - .max_reg = 5, - .regs = {0x82, 0xcf, 0x7f, 0xff, 0xff, 0xf7}, - .fs_regs = {{0, 4, 1, 4}, {0, 5, 5, 7}, {0, 6, 1, 5}, {0, 2, 2, 7}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 9000, .ram_mult = 1, .pci_div = 2}, - {.bus = 8901, .ram_mult = 1, .pci_div = 2}, - {.bus = 8800, .ram_mult = 1, .pci_div = 2}, - {.bus = 8699, .ram_mult = 1, .pci_div = 2}, - {.bus = 8591, .ram_mult = 1, .pci_div = 2}, - {.bus = 8501, .ram_mult = 1, .pci_div = 2}, - {.bus = 8400, .ram_mult = 1, .pci_div = 2}, - {.bus = 8200, .ram_mult = 1, .pci_div = 2}, - {.bus = 8101, .ram_mult = 1, .pci_div = 2}, - {.bus = 8000, .ram_mult = 1, .pci_div = 2}, - {.bus = 8331, .ram_mult = 1, .pci_div = 2}, - {.bus = 6849, .ram_mult = 1, .pci_div = 2}, - {.bus = 7800, .ram_mult = 1, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1, .pci_div = 2}, - {.bus = 7199, .ram_mult = 1, .pci_div = 2}, - {.bus = 6682, .ram_mult = 1, .pci_div = 2}, - {0} - } + .max_reg = 5, + .regs = {0x82, 0xcf, 0x7f, 0xff, 0xff, 0xf7}, + .fs_regs = {{0, 4, 1, 4}, {0, 5, 5, 7}, {0, 6, 1, 5}, {0, 2, 2, 7}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 9000, .ram_mult = 1, .pci_div = 2}, + {.bus = 8901, .ram_mult = 1, .pci_div = 2}, + {.bus = 8800, .ram_mult = 1, .pci_div = 2}, + {.bus = 8699, .ram_mult = 1, .pci_div = 2}, + {.bus = 8591, .ram_mult = 1, .pci_div = 2}, + {.bus = 8501, .ram_mult = 1, .pci_div = 2}, + {.bus = 8400, .ram_mult = 1, .pci_div = 2}, + {.bus = 8200, .ram_mult = 1, .pci_div = 2}, + {.bus = 8101, .ram_mult = 1, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1, .pci_div = 2}, + {.bus = 8331, .ram_mult = 1, .pci_div = 2}, + {.bus = 6849, .ram_mult = 1, .pci_div = 2}, + {.bus = 7800, .ram_mult = 1, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1, .pci_div = 2}, + {.bus = 7199, .ram_mult = 1, .pci_div = 2}, + {.bus = 6682, .ram_mult = 1, .pci_div = 2}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_14) - .max_reg = 5, - .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, - .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6781, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7201, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7301, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7801, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8449, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8608, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8800, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 9000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 9500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 4990, .ram_mult = 1, .pci_div = 3}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 7485, .ram_mult = 1, .pci_div = 3}, - {.bus = 6658, .ram_mult = 1, .pci_div = 3}, - {.bus = 8284, .ram_mult = 1, .pci_div = 3}, - {.bus = 8981, .ram_mult = 1, .pci_div = 3}, - {.bus = 9480, .ram_mult = 1, .pci_div = 3}, - {.bus = 10050, .ram_mult = 1, .pci_div = 3}, - {.bus = 10478, .ram_mult = 1, .pci_div = 3}, - {.bus = 11177, .ram_mult = 1, .pci_div = 3}, - {.bus = 11477, .ram_mult = 1, .pci_div = 3}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 12375, .ram_mult = 1, .pci_div = 3}, - {.bus = 13274, .ram_mult = 1, .pci_div = 3}, - {.bus = 13975, .ram_mult = 1, .pci_div = 3}, - {.bus = 14969, .ram_mult = 1, .pci_div = 3}, - {0} - } + .max_reg = 5, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6781, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7201, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7301, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7801, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8449, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8608, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8800, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 9000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 9500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 4990, .ram_mult = 1, .pci_div = 3}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 7485, .ram_mult = 1, .pci_div = 3}, + {.bus = 6658, .ram_mult = 1, .pci_div = 3}, + {.bus = 8284, .ram_mult = 1, .pci_div = 3}, + {.bus = 8981, .ram_mult = 1, .pci_div = 3}, + {.bus = 9480, .ram_mult = 1, .pci_div = 3}, + {.bus = 10050, .ram_mult = 1, .pci_div = 3}, + {.bus = 10478, .ram_mult = 1, .pci_div = 3}, + {.bus = 11177, .ram_mult = 1, .pci_div = 3}, + {.bus = 11477, .ram_mult = 1, .pci_div = 3}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 12375, .ram_mult = 1, .pci_div = 3}, + {.bus = 13274, .ram_mult = 1, .pci_div = 3}, + {.bus = 13975, .ram_mult = 1, .pci_div = 3}, + {.bus = 14969, .ram_mult = 1, .pci_div = 3}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_16) - .max_reg = 5, - .regs = {0x1f, 0xff, 0xff, 0x00, 0x00, 0x06}, - .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7467, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 10500, .ram_mult = 1, .pci_div = 3}, - {.bus = 10900, .ram_mult = 1, .pci_div = 3}, - {.bus = 11201, .ram_mult = 1, .pci_div = 3}, - {.bus = 13334, .ram_mult = 1, .pci_div = 3}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 12000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 12400, .ram_mult = 1, .pci_div = 3}, - {.bus = 13334, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 15000, .ram_mult = 1, .pci_div = 4}, - {.bus = 14000, .ram_mult = 1, .pci_div = 4}, - {.bus = 13299, .ram_mult = 1, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x1f, 0xff, 0xff, 0x00, 0x00, 0x06}, + .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7267, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7467, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10500, .ram_mult = 1, .pci_div = 3}, + {.bus = 10900, .ram_mult = 1, .pci_div = 3}, + {.bus = 11201, .ram_mult = 1, .pci_div = 3}, + {.bus = 13334, .ram_mult = 1, .pci_div = 3}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 12000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 12400, .ram_mult = 1, .pci_div = 3}, + {.bus = 13334, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13299, .ram_mult = 1, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() #endif ICS9xxx_MODEL(ICS9250_18) - .max_reg = 5, - .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 8000, .pci_div = 2}, - {.bus = 7500, .pci_div = 2}, - {.bus = 8331, .pci_div = 2}, - {.bus = 6690, .pci_div = 2}, - {.bus = 10300, .pci_div = 3}, - {.bus = 11201, .pci_div = 3}, - {.bus = 6801, .pci_div = 2}, - {.bus = 10070, .pci_div = 3}, - {.bus = 12000, .pci_div = 3}, - {.bus = 11499, .pci_div = 3}, - {.bus = 10999, .pci_div = 3}, - {.bus = 10500, .pci_div = 3}, - {.bus = 14000, .pci_div = 4}, - {.bus = 15000, .pci_div = 4}, - {.bus = 12400, .pci_div = 4}, - {.bus = 13390, .pci_div = 4}, - {.bus = 13500, .pci_div = 4}, - {.bus = 12999, .pci_div = 4}, - {.bus = 12600, .pci_div = 4}, - {.bus = 11800, .pci_div = 4}, - {.bus = 11598, .pci_div = 4}, - {.bus = 9500, .pci_div = 3}, - {.bus = 9000, .pci_div = 3}, - {.bus = 8501, .pci_div = 3}, - {.bus = 16600, .pci_div = 4}, - {.bus = 16001, .pci_div = 4}, - {.bus = 15499, .pci_div = 4}, - {.bus = 14795, .pci_div = 4}, - {.bus = 14598, .pci_div = 4}, - {.bus = 14398, .pci_div = 4}, - {.bus = 14199, .pci_div = 4}, - {.bus = 13801, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 8000, .pci_div = 2}, + {.bus = 7500, .pci_div = 2}, + {.bus = 8331, .pci_div = 2}, + {.bus = 6690, .pci_div = 2}, + {.bus = 10300, .pci_div = 3}, + {.bus = 11201, .pci_div = 3}, + {.bus = 6801, .pci_div = 2}, + {.bus = 10070, .pci_div = 3}, + {.bus = 12000, .pci_div = 3}, + {.bus = 11499, .pci_div = 3}, + {.bus = 10999, .pci_div = 3}, + {.bus = 10500, .pci_div = 3}, + {.bus = 14000, .pci_div = 4}, + {.bus = 15000, .pci_div = 4}, + {.bus = 12400, .pci_div = 4}, + {.bus = 13390, .pci_div = 4}, + {.bus = 13500, .pci_div = 4}, + {.bus = 12999, .pci_div = 4}, + {.bus = 12600, .pci_div = 4}, + {.bus = 11800, .pci_div = 4}, + {.bus = 11598, .pci_div = 4}, + {.bus = 9500, .pci_div = 3}, + {.bus = 9000, .pci_div = 3}, + {.bus = 8501, .pci_div = 3}, + {.bus = 16600, .pci_div = 4}, + {.bus = 16001, .pci_div = 4}, + {.bus = 15499, .pci_div = 4}, + {.bus = 14795, .pci_div = 4}, + {.bus = 14598, .pci_div = 4}, + {.bus = 14398, .pci_div = 4}, + {.bus = 14199, .pci_div = 4}, + {.bus = 13801, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() #ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_19) - .max_reg = 5, - .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, - .hw_select = {0, 3}, - .frequencies_ref = ICS9250_08 + .max_reg = 5, + .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .hw_select = {0, 3}, + .frequencies_ref = ICS9250_08 ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_23) - .max_reg = 5, - .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, - .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6900, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7100, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6690, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7660, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6800, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7400, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 14000, .ram_mult = 1, .pci_div = 4}, - {.bus = 13333, .ram_mult = 1, .pci_div = 4}, - {.bus = 15000, .ram_mult = 1, .pci_div = 4}, - {.bus = 15500, .ram_mult = 1, .pci_div = 4}, - {.bus = 16600, .ram_mult = 1, .pci_div = 4}, - {.bus = 16600, .ram_mult = 1, .pci_div = 3}, - {.bus = 11177, .ram_mult = 1, .pci_div = 3}, - {.bus = 10478, .ram_mult = 1, .pci_div = 3}, - {.bus = 10951, .ram_mult = 1, .pci_div = 3}, - {.bus = 10090, .ram_mult = 1, .pci_div = 3}, - {.bus = 11700, .ram_mult = 1, .pci_div = 3}, - {.bus = 12375, .ram_mult = 1, .pci_div = 3}, - {.bus = 13333, .ram_mult = 1, .pci_div = 3}, - {.bus = 14250, .ram_mult = 1, .pci_div = 3}, - {.bus = 13600, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14300, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13390, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14667, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14933, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 15330, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 16667, .ram_mult = 0.75, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6900, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7100, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6690, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7660, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6800, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7400, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 15500, .ram_mult = 1, .pci_div = 4}, + {.bus = 16600, .ram_mult = 1, .pci_div = 4}, + {.bus = 16600, .ram_mult = 1, .pci_div = 3}, + {.bus = 11177, .ram_mult = 1, .pci_div = 3}, + {.bus = 10478, .ram_mult = 1, .pci_div = 3}, + {.bus = 10951, .ram_mult = 1, .pci_div = 3}, + {.bus = 10090, .ram_mult = 1, .pci_div = 3}, + {.bus = 11700, .ram_mult = 1, .pci_div = 3}, + {.bus = 12375, .ram_mult = 1, .pci_div = 3}, + {.bus = 13333, .ram_mult = 1, .pci_div = 3}, + {.bus = 14250, .ram_mult = 1, .pci_div = 3}, + {.bus = 13600, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14300, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13390, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14667, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14933, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15330, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16667, .ram_mult = 0.75, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_25) - .max_reg = 6, - .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff, 0x06}, - .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 5500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8330, .ram_mult = 1, .pci_div = 3}, - {.bus = 9000, .ram_mult = 1, .pci_div = 3}, - {.bus = 10030, .ram_mult = 1, .pci_div = 3}, - {.bus = 10300, .ram_mult = 1, .pci_div = 3}, - {.bus = 11250, .ram_mult = 1, .pci_div = 3}, - {.bus = 11500, .ram_mult = 1, .pci_div = 3}, - {.bus = 12000, .ram_mult = 1, .pci_div = 3}, - {.bus = 12500, .ram_mult = 1, .pci_div = 3}, - {.bus = 12800, .ram_mult = 1, .pci_div = 4}, - {.bus = 13000, .ram_mult = 1, .pci_div = 4}, - {.bus = 13370, .ram_mult = 1, .pci_div = 4}, - {.bus = 13700, .ram_mult = 1, .pci_div = 4}, - {.bus = 14000, .ram_mult = 1, .pci_div = 4}, - {.bus = 14500, .ram_mult = 1, .pci_div = 4}, - {.bus = 15000, .ram_mult = 1, .pci_div = 4}, - {.bus = 15333, .ram_mult = 1, .pci_div = 4}, - {.bus = 12500, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 15333, .ram_mult = 0.75, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff, 0x06}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 5500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7200, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7700, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8330, .ram_mult = 1, .pci_div = 3}, + {.bus = 9000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 11250, .ram_mult = 1, .pci_div = 3}, + {.bus = 11500, .ram_mult = 1, .pci_div = 3}, + {.bus = 12000, .ram_mult = 1, .pci_div = 3}, + {.bus = 12500, .ram_mult = 1, .pci_div = 3}, + {.bus = 12800, .ram_mult = 1, .pci_div = 4}, + {.bus = 13000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13370, .ram_mult = 1, .pci_div = 4}, + {.bus = 13700, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14500, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 15333, .ram_mult = 1, .pci_div = 4}, + {.bus = 12500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15333, .ram_mult = 0.75, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_26) - .max_reg = 5, - .regs = {0x1e, 0xff, 0xff, 0x00, 0x00, 0x06}, - .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies_ref = ICS9250_16 + .max_reg = 5, + .regs = {0x1e, 0xff, 0xff, 0x00, 0x00, 0x06}, + .fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies_ref = ICS9250_16 ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_27) - .max_reg = 5, - .regs = {0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00}, - .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 13332, .ram_mult = 1, .pci_div = 4}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 13332, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 13332, .ram_mult = 1, .pci_div = 4}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 13332, .ram_mult = 1, .pci_div = 4}, - {0} - } + .max_reg = 5, + .regs = {0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 13332, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 6666, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 13332, .ram_mult = 1, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_28) - .max_reg = 4, - .regs = {0x1e, 0xff, 0xfe, 0x00, 0x00}, - .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies_ref = ICS9250_27 + .max_reg = 4, + .regs = {0x1e, 0xff, 0xfe, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies_ref = ICS9250_27 ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_29) - .max_reg = 5, - .regs = {0x16, 0xff, 0xfe, 0x00, 0x00, 0x00}, - .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .hw_select = {-1, -1}, - .frequencies_ref = ICS9250_27 + .max_reg = 5, + .regs = {0x16, 0xff, 0xfe, 0x00, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .hw_select = {-1, -1}, + .frequencies_ref = ICS9250_27 ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_30) - .max_reg = 6, - .regs = {0x02, 0x0f, 0xff, 0xff, 0xeb, 0xff, 0x06}, - .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, - {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - {.bus = 9000, .ram_mult = 1, .pci_div = 3}, - {.bus = 10030, .ram_mult = 1, .pci_div = 3}, - {.bus = 10300, .ram_mult = 1, .pci_div = 3}, - {.bus = 10500, .ram_mult = 1, .pci_div = 3}, - {.bus = 11000, .ram_mult = 1, .pci_div = 3}, - {.bus = 11500, .ram_mult = 1, .pci_div = 3}, - {.bus = 20000, .ram_mult = 1, .pci_div = 6}, - {.bus = 13333, .ram_mult = 1, .pci_div = 4}, - {.bus = 16667, .ram_mult = 1, .pci_div = 4}, - {.bus = 13370, .ram_mult = 1, .pci_div = 4}, - {.bus = 13700, .ram_mult = 1, .pci_div = 4}, - {.bus = 14000, .ram_mult = 1, .pci_div = 4}, - {.bus = 14500, .ram_mult = 1, .pci_div = 4}, - {.bus = 15000, .ram_mult = 1, .pci_div = 4}, - {.bus = 16000, .ram_mult = 1, .pci_div = 4}, - {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 16667, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, - {.bus = 16000, .ram_mult = 0.75, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x0f, 0xff, 0xff, 0xeb, 0xff, 0x06}, + .fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6680, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 6833, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 7500, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8000, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 8300, .ram_mult = 1.5, .pci_div = 2}, + {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + {.bus = 9000, .ram_mult = 1, .pci_div = 3}, + {.bus = 10030, .ram_mult = 1, .pci_div = 3}, + {.bus = 10300, .ram_mult = 1, .pci_div = 3}, + {.bus = 10500, .ram_mult = 1, .pci_div = 3}, + {.bus = 11000, .ram_mult = 1, .pci_div = 3}, + {.bus = 11500, .ram_mult = 1, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1, .pci_div = 6}, + {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + {.bus = 16667, .ram_mult = 1, .pci_div = 4}, + {.bus = 13370, .ram_mult = 1, .pci_div = 4}, + {.bus = 13700, .ram_mult = 1, .pci_div = 4}, + {.bus = 14000, .ram_mult = 1, .pci_div = 4}, + {.bus = 14500, .ram_mult = 1, .pci_div = 4}, + {.bus = 15000, .ram_mult = 1, .pci_div = 4}, + {.bus = 16000, .ram_mult = 1, .pci_div = 4}, + {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16667, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13370, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 13700, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 14500, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 15000, .ram_mult = 0.75, .pci_div = 4}, + {.bus = 16000, .ram_mult = 0.75, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_32) - .max_reg = 4, - .regs = {0x07, 0xff, 0xff, 0x00, 0x00}, - .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}} + .max_reg = 4, + .regs = {0x07, 0xff, 0xff, 0x00, 0x00}, + .fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}} ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_38) - .max_reg = 6, - .regs = {0x18, 0x07, 0xfe, 0xc7, 0xfc, 0x00, 0x80}, - .fs_regs = {{0, 0, -1, -1}, {0, 1, -1, -1}, {0, 2, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, - .normal_bits_fixed = 1, - .frequencies = (const ics9xxx_frequency_t[]) { - {.bus = 6666, .ram_mult = 1, .pci_div = 1}, - {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, - {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, - {.bus = 13333, .ram_mult = 0.5, .pci_div = 2}, - {.bus = 6666, .ram_mult = 1, .pci_div = 1}, - {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, - {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, - {.bus = 13333, .ram_mult = 0.5, .pci_div = 2}, - {0} - } + .max_reg = 6, + .regs = {0x18, 0x07, 0xfe, 0xc7, 0xfc, 0x00, 0x80}, + .fs_regs = {{0, 0, -1, -1}, {0, 1, -1, -1}, {0, 2, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}, + .normal_bits_fixed = 1, + .frequencies = (const ics9xxx_frequency_t[]) { + {.bus = 6666, .ram_mult = 1, .pci_div = 1}, + {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, + {.bus = 13333, .ram_mult = 0.5, .pci_div = 2}, + {.bus = 6666, .ram_mult = 1, .pci_div = 1}, + {.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3}, + {.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6}, + {.bus = 13333, .ram_mult = 0.5, .pci_div = 2}, + {0} + } ICS9xxx_MODEL_END() ICS9xxx_MODEL(ICS9250_50) - .max_reg = 6, - .regs = {0x02, 0x6f, 0xff, 0xff, 0xef, 0xff, 0x06}, - .fs_regs = {{-1, -1, 1, 6}, {-1, -1, 4, 2}, {-1, -1, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, - .hw_select = {0, 3}, - .frequencies = (const ics9xxx_frequency_t[]) { - [0 ... 7] = {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, - [8 ... 15] = {.bus = 10000, .ram_mult = 1, .pci_div = 3}, - [16 ... 23] = {.bus = 13333, .ram_mult = 1, .pci_div = 4}, - [24 ... 31] = {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, - {0} - } + .max_reg = 6, + .regs = {0x02, 0x6f, 0xff, 0xff, 0xef, 0xff, 0x06}, + .fs_regs = {{-1, -1, 1, 6}, {-1, -1, 4, 2}, {-1, -1, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}}, + .hw_select = {0, 3}, + .frequencies = (const ics9xxx_frequency_t[]) { + [0 ... 7] = {.bus = 6667, .ram_mult = 1.5, .pci_div = 2}, + [8 ... 15] = {.bus = 10000, .ram_mult = 1, .pci_div = 3}, + [16 ... 23] = {.bus = 13333, .ram_mult = 1, .pci_div = 4}, + [24 ... 31] = {.bus = 13333, .ram_mult = 0.75, .pci_div = 4}, + {0} + } ICS9xxx_MODEL_END() #endif }; @@ -941,7 +942,10 @@ ics9xxx_detect(ics9xxx_t *dev) if (!(dev->regs[detect_reg] & 0x40)) pclog("Bit 3 of register %d is clear, probably in hardware select mode!\n", detect_reg); - uint8_t i = 0, matches = 0, val, bitmask; + uint8_t i = 0; + uint8_t matches = 0; + uint8_t val; + uint8_t bitmask; ics9xxx_frequency_t *frequencies_ptr; uint32_t delta; for (uint8_t j = 0; j < ICS9xxx_MAX; j++) { @@ -983,7 +987,7 @@ ics9xxx_detect(ics9xxx_t *dev) #endif static uint8_t -ics9xxx_start(void *bus, uint8_t addr, uint8_t read, void *priv) +ics9xxx_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { ics9xxx_t *dev = (ics9xxx_t *) priv; @@ -995,7 +999,7 @@ ics9xxx_start(void *bus, uint8_t addr, uint8_t read, void *priv) } static uint8_t -ics9xxx_read(void *bus, uint8_t addr, void *priv) +ics9xxx_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { ics9xxx_t *dev = (ics9xxx_t *) priv; uint8_t ret = 0xff; @@ -1006,7 +1010,7 @@ ics9xxx_read(void *bus, uint8_t addr, void *priv) } #if 0 else if ((dev->model_idx == ICS9250_50) && (dev->addr_register == 0)) - ret = dev->regs[dev->addr_register] & 0x0b; /* -50 reads back revision ID instead */ + ret = dev->regs[dev->addr_register] & 0x0b; /* -50 reads back revision ID instead */ #endif else ret = dev->regs[dev->addr_register]; @@ -1049,7 +1053,7 @@ ics9xxx_set(ics9xxx_t *dev, uint8_t val) } static uint8_t -ics9xxx_write(void *bus, uint8_t addr, uint8_t data, void *priv) +ics9xxx_write(UNUSED(void *bus), UNUSED(uint8_t addr), uint8_t data, void *priv) { ics9xxx_t *dev = (ics9xxx_t *) priv; @@ -1075,32 +1079,32 @@ ics9xxx_write(void *bus, uint8_t addr, uint8_t data, void *priv) } #if 0 - switch (dev->addr_register) { - case 0: - if (dev->model_idx == ICS9250_38) - data = (dev->regs[dev->addr_register] & ~0xe8) | (data & 0xe8); - break; - - case 1: - if (dev->model_idx == ICS9250_38) - data = (dev->regs[dev->addr_register] & ~0xfe) | (data & 0xfe); - break; - - case 3: - if (dev->model_idx == ICS9250_32) - data ^= 0x70; - break; - - case 4: - if (dev->model_idx == ICS9250_38) - data = (dev->regs[dev->addr_register] & ~0xfc) | (data & 0xfc); - break; - - case 6: - if (dev->model_idx == ICS9250_38) /* read-only */ - data = dev->regs[dev->addr_register]; - break; - } + switch (dev->addr_register) { + case 0: + if (dev->model_idx == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xe8) | (data & 0xe8); + break; + + case 1: + if (dev->model_idx == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xfe) | (data & 0xfe); + break; + + case 3: + if (dev->model_idx == ICS9250_32) + data ^= 0x70; + break; + + case 4: + if (dev->model_idx == ICS9250_38) + data = (dev->regs[dev->addr_register] & ~0xfc) | (data & 0xfc); + break; + + case 6: + if (dev->model_idx == ICS9250_38) /* read-only */ + data = dev->regs[dev->addr_register]; + break; + } #endif dev->regs[dev->addr_register] = data; @@ -1113,20 +1117,20 @@ ics9xxx_write(void *bus, uint8_t addr, uint8_t data, void *priv) break; #endif #if 0 - case ICS9250_10: - ics9xxx_set(dev, (cpu_busspeed >= 100000000) * 0x08); - break; - - case ICS9250_16: - case ICS9250_26: - ics9xxx_set(dev, ((cpu_busspeed >= 120000000) * 0x08) | ((((cpu_busspeed >= 100000000) && (cpu_busspeed < 120000000)) || (cpu_busspeed == 150000000) || (cpu_busspeed == 132999999)) * 0x04)); - break; - - case ICS9250_27: - case ICS9250_28: - case ICS9250_29: - ics9xxx_set(dev, ((cpu_busspeed == 100000000) * 0x02) | ((cpu_busspeed > 100000000) * 0x01)); - break; + case ICS9250_10: + ics9xxx_set(dev, (cpu_busspeed >= 100000000) * 0x08); + break; + + case ICS9250_16: + case ICS9250_26: + ics9xxx_set(dev, ((cpu_busspeed >= 120000000) * 0x08) | ((((cpu_busspeed >= 100000000) && (cpu_busspeed < 120000000)) || (cpu_busspeed == 150000000) || (cpu_busspeed == 132999999)) * 0x04)); + break; + + case ICS9250_27: + case ICS9250_28: + case ICS9250_29: + ics9xxx_set(dev, ((cpu_busspeed == 100000000) * 0x02) | ((cpu_busspeed > 100000000) * 0x01)); + break; #endif default: ics9xxx_set(dev, 0x00); diff --git a/src/device/hasp.c b/src/device/hasp.c index 8c71e1f3f2..9873c3460d 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -52,9 +52,11 @@ enum { HASP_TYPE_SAVQUEST = 0 }; -typedef struct { - const uint8_t *password, *prodinfo; - const uint8_t password_size, prodinfo_size; +typedef struct hasp_type_t { + const uint8_t *password; + const uint8_t *prodinfo; + const uint8_t password_size; + const uint8_t prodinfo_size; } hasp_type_t; typedef struct @@ -62,8 +64,13 @@ typedef struct void *lpt; const hasp_type_t *type; - int index, state, passindex, passmode, prodindex; - uint8_t tmppass[0x29], status; + int index; + int state; + int passindex; + int passmode; + int prodindex; + uint8_t tmppass[0x29]; + uint8_t status; } hasp_t; static const hasp_type_t hasp_types[] = { @@ -131,6 +138,8 @@ hasp_write_data(uint8_t val, void *priv) return; } break; + default: + break; } dev->status = 0; @@ -163,6 +172,8 @@ hasp_write_data(uint8_t val, void *priv) I guessed the implicit ones with a bit of trial and error */ dev->status = 0x20; return; + default: + break; } } @@ -199,6 +210,8 @@ hasp_write_data(uint8_t val, void *priv) /* again, just the relevant bits instead of the true values */ dev->status = 0x20; break; + default: + break; } } else if (dev->state == HASP_STATE_PASSWORD_END) { if (val & 1) { diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 730e2f2ce0..6ba1083d97 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -27,21 +27,27 @@ #include <86box/io.h> #include <86box/i2c.h> #include <86box/hwm.h> +#include <86box/plat_unused.h> + #define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) -/* Formulas and factors derived from Linux's gl518sm.c driver. */ -#define GL518SM_RPM_TO_REG(r, d) ((r) ? CLAMP((480000 + (r) * (d) / 2) / (r) * (d), 1, 255) : 0) +/* Formulas and factors derived from Linux's gl518sm.c and gl520sm.c drivers. */ +#define GL518SM_RPM_TO_REG(r, d) ((r) ? (480000 / (CLAMP((r), (480000 >> (d)) / 255, (480000 >> (d))) << (d))) : 0) #define GL518SM_VOLTAGE_TO_REG(v) ((uint8_t) round((v) / 19.0)) #define GL518SM_VDD_TO_REG(v) ((uint8_t) (((v) *4) / 95.0)) -typedef struct { +#define GL520SM 0x100 + +typedef struct gl518sm_t { uint32_t local; hwm_values_t *values; uint16_t regs[32]; uint8_t addr_register : 5; - uint8_t i2c_addr : 7, i2c_state : 2, i2c_enabled : 1; + uint8_t i2c_addr : 7; + uint8_t i2c_state : 2; + uint8_t i2c_enabled : 1; } gl518sm_t; static uint8_t gl518sm_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv); @@ -85,7 +91,7 @@ gl518sm_remap(gl518sm_t *dev, uint8_t addr) } static uint8_t -gl518sm_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv) +gl518sm_i2c_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { gl518sm_t *dev = (gl518sm_t *) priv; @@ -95,7 +101,7 @@ gl518sm_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv) } static uint8_t -gl518sm_i2c_read(void *bus, uint8_t addr, void *priv) +gl518sm_i2c_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { gl518sm_t *dev = (gl518sm_t *) priv; uint16_t read = gl518sm_read(dev, dev->addr_register); @@ -124,18 +130,22 @@ gl518sm_read(gl518sm_t *dev, uint8_t reg) switch (reg) { case 0x04: /* temperature */ - ret = (dev->values->temperatures[0] + 119) & 0xff; + ret = (dev->values->temperatures[0] + ((dev->local & GL520SM) ? 130 : 119)) & 0xff; break; case 0x07: /* fan speeds */ - ret = GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8; - ret |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3)); + ret = GL518SM_RPM_TO_REG(dev->values->fans[0], (dev->regs[0x0f] >> 6) & 0x3) << 8; + ret |= GL518SM_RPM_TO_REG(dev->values->fans[1], (dev->regs[0x0f] >> 4) & 0x3); break; case 0x0d: /* VIN3 */ ret = GL518SM_VOLTAGE_TO_REG(dev->values->voltages[2]); break; + case 0x0e: /* temperature 2 */ + ret = (dev->local & GL520SM) ? ((dev->values->temperatures[1] + 130) & 0xff) : dev->regs[reg]; + break; + case 0x13: /* VIN2 */ ret = GL518SM_VOLTAGE_TO_REG(dev->values->voltages[1]); break; @@ -159,7 +169,7 @@ gl518sm_read(gl518sm_t *dev, uint8_t reg) } static uint8_t -gl518sm_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv) +gl518sm_i2c_write(UNUSED(void *bus), UNUSED(uint8_t addr), uint8_t data, void *priv) { gl518sm_t *dev = (gl518sm_t *) priv; @@ -213,6 +223,11 @@ gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val) gl518sm_reset(dev); break; + case 0x0e: + if (dev->local & GL520SM) + return 0; + break; + case 0x0f: dev->regs[reg] = val & 0xf8; break; @@ -234,10 +249,16 @@ gl518sm_reset(gl518sm_t *dev) { memset(dev->regs, 0, sizeof(dev->regs)); - dev->regs[0x00] = 0x80; - dev->regs[0x01] = 0x80; /* revision 0x80 can read all voltages */ - dev->regs[0x05] = 0xc7; - dev->regs[0x06] = 0xc2; + if (dev->local & GL520SM) { + dev->regs[0x00] = 0x20; + dev->regs[0x01] = 0x00; + dev->regs[0x03] = 0x04; + } else { + dev->regs[0x00] = 0x80; + dev->regs[0x01] = 0x80; /* revision 0x80 can read all voltages */ + dev->regs[0x05] = 0xc7; + dev->regs[0x06] = 0xc2; + } dev->regs[0x08] = 0x6464; dev->regs[0x09] = 0xdac5; dev->regs[0x0a] = 0xdac5; @@ -275,7 +296,8 @@ gl518sm_init(const device_t *info) }, { /* temperatures */ - 30 /* usually CPU */ + 30, /* usually CPU */ + 30 /* GL520SM only: usually System */ }, { /* voltages */ @@ -323,3 +345,34 @@ const device_t gl518sm_2d_device = { .force_redraw = NULL, .config = NULL }; + +/* GL520SM on SMBus address 2Ch */ +const device_t gl520sm_2c_device = { + .name = "Genesys Logic GL520SM Hardware Monitor", + .internal_name = "gl520sm_2c", + .flags = DEVICE_ISA, + .local = GL520SM | 0x2c, + .init = gl518sm_init, + .close = gl518sm_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + + +/* GL520SM on SMBus address 2Dh */ +const device_t gl520sm_2d_device = { + .name = "Genesys Logic GL520SM Hardware Monitor", + .internal_name = "gl520sm_2d", + .flags = DEVICE_ISA, + .local = GL520SM | 0x2d, + .init = gl518sm_init, + .close = gl518sm_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index fdfff0e445..14b6383658 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -25,6 +25,7 @@ #include <86box/device.h> #include <86box/i2c.h> #include <86box/hwm.h> +#include <86box/plat_unused.h> #define LM75_TEMP_TO_REG(t) ((t) << 8) @@ -47,7 +48,7 @@ lm75_log(const char *fmt, ...) #endif static uint8_t -lm75_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv) +lm75_i2c_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { lm75_t *dev = (lm75_t *) priv; @@ -74,7 +75,7 @@ lm75_read(lm75_t *dev, uint8_t reg) } static uint8_t -lm75_i2c_read(void *bus, uint8_t addr, void *priv) +lm75_i2c_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { lm75_t *dev = (lm75_t *) priv; uint8_t ret = 0; @@ -103,6 +104,8 @@ lm75_i2c_read(void *bus, uint8_t addr, void *priv) case 0x3: /* Tos */ ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x5 : 0x6); break; + default: + break; } } @@ -128,7 +131,7 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) } static uint8_t -lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv) +lm75_i2c_write(UNUSED(void *bus), UNUSED(uint8_t addr), uint8_t data, void *priv) { lm75_t *dev = (lm75_t *) priv; @@ -164,6 +167,9 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv) case 0x3: /* Tos */ lm75_write(dev, (dev->i2c_state == 1) ? 0x5 : 0x6, data); break; + + default: + break; } } diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index 9455a2ebd7..f3003db267 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -27,6 +27,8 @@ #include <86box/timer.h> #include <86box/machine.h> #include <86box/nvr.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include "cpu.h" #include <86box/i2c.h> #include <86box/hwm.h> @@ -48,7 +50,7 @@ #define LM78_NEG_VOLTAGE(v, r) (v * (604.0 / ((double) r))) /* negative voltage formula from the W83781D datasheet */ #define LM78_NEG_VOLTAGE2(v, r) (((3600 + v) * (((double) r) / (((double) r) + 56.0))) - v) /* negative voltage formula from the W83782D datasheet */ -typedef struct { +typedef struct lm78_t { uint32_t local; hwm_values_t *values; device_t *lm75[2]; @@ -56,10 +58,10 @@ typedef struct { uint8_t regs[256]; union { - struct { + struct w83782d { uint8_t regs[2][16]; } w83782d; - struct { + struct as99127f { uint8_t regs[3][128]; uint8_t nvram[1024], nvram_i2c_state : 2, nvram_updated : 1; @@ -69,9 +71,12 @@ typedef struct { uint8_t security_i2c_state : 1, security_addr_register : 7; } as99127f; }; - uint8_t addr_register, data_register; + uint8_t addr_register; + uint8_t data_register; - uint8_t i2c_addr : 7, i2c_state : 1, i2c_enabled : 1; + uint8_t i2c_addr : 7; + uint8_t i2c_state : 1; + uint8_t i2c_enabled : 1; } lm78_t; static void lm78_remap(lm78_t *dev, uint8_t addr); @@ -101,20 +106,20 @@ lm78_nvram(lm78_t *dev, uint8_t save) char *nvr_path = (char *) malloc(l); sprintf(nvr_path, "%s_as99127f.nvr", machine_get_internal_name_ex(machine)); - FILE *f = nvr_fopen(nvr_path, save ? "wb" : "rb"); - if (f) { + FILE *fp = nvr_fopen(nvr_path, save ? "wb" : "rb"); + if (fp) { if (save) - fwrite(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f); + fwrite(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, fp); else - (void) !fread(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f); - fclose(f); + (void) !fread(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, fp); + fclose(fp); } free(nvr_path); } static uint8_t -lm78_nvram_start(void *bus, uint8_t addr, uint8_t read, void *priv) +lm78_nvram_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -124,7 +129,7 @@ lm78_nvram_start(void *bus, uint8_t addr, uint8_t read, void *priv) } static uint8_t -lm78_nvram_read(void *bus, uint8_t addr, void *priv) +lm78_nvram_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { lm78_t *dev = (lm78_t *) priv; uint8_t ret = 0xff; @@ -132,7 +137,7 @@ lm78_nvram_read(void *bus, uint8_t addr, void *priv) switch (dev->as99127f.nvram_i2c_state) { case 0: dev->as99127f.nvram_i2c_state = 1; - /* fall-through */ + fallthrough; case 1: ret = dev->as99127f.regs[0][0x0b] & 0x3f; @@ -158,7 +163,7 @@ lm78_nvram_read(void *bus, uint8_t addr, void *priv) } static uint8_t -lm78_nvram_write(void *bus, uint8_t addr, uint8_t val, void *priv) +lm78_nvram_write(UNUSED(void *bus), uint8_t addr, uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -195,7 +200,7 @@ lm78_nvram_write(void *bus, uint8_t addr, uint8_t val, void *priv) } static uint8_t -lm78_security_start(void *bus, uint8_t addr, uint8_t read, void *priv) +lm78_security_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -205,7 +210,7 @@ lm78_security_start(void *bus, uint8_t addr, uint8_t read, void *priv) } static uint8_t -lm78_security_read(void *bus, uint8_t addr, void *priv) +lm78_security_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -213,7 +218,7 @@ lm78_security_read(void *bus, uint8_t addr, void *priv) } static uint8_t -lm78_security_write(void *bus, uint8_t addr, uint8_t val, void *priv) +lm78_security_write(UNUSED(void *bus), UNUSED(uint8_t addr), uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -229,6 +234,8 @@ lm78_security_write(void *bus, uint8_t addr, uint8_t val, void *priv) case 0xe7: /* read-only registers */ return 1; + default: + break; } dev->as99127f.regs[2][dev->as99127f.security_addr_register++] = val; @@ -316,7 +323,7 @@ lm78_reset(void *priv) } static uint8_t -lm78_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv) +lm78_i2c_start(UNUSED(void *bus), UNUSED(uint8_t addr), UNUSED(uint8_t read), void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -405,7 +412,7 @@ lm78_isa_read(uint16_t port, void *priv) } static uint8_t -lm78_i2c_read(void *bus, uint8_t addr, void *priv) +lm78_i2c_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -415,8 +422,8 @@ lm78_i2c_read(void *bus, uint8_t addr, void *priv) uint8_t lm78_as99127f_read(void *priv, uint8_t reg) { - lm78_t *dev = (lm78_t *) priv; - uint8_t ret = dev->as99127f.regs[1][reg & 0x7f]; + const lm78_t *dev = (lm78_t *) priv; + uint8_t ret = dev->as99127f.regs[1][reg & 0x7f]; lm78_log("LM78: read(%02X, AS99127F) = %02X\n", reg, ret); @@ -446,6 +453,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) case 0x20: val &= 0x7f; break; + default: + break; } dev->as99127f.regs[0][reg] = val; @@ -477,6 +486,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) case 0x5f: /* read-only registers */ return 0; + default: + break; } dev->w83782d.regs[0][reg & 0x0f] = val; @@ -497,6 +508,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) case 0x5f: /* read-only registers */ return 0; + default: + break; } dev->w83782d.regs[1][reg & 0x0f] = val; @@ -559,6 +572,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) if (!(dev->local & LM78_WINBOND)) return 0; break; + default: + break; } if ((reg >= 0x60) && (reg <= 0x94)) /* write auto-increment value RAM registers to their non-auto-increment locations */ @@ -613,6 +628,9 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) i2c_sethandler(i2c_smbus, (val & 0xf8) >> 1, 4, lm78_nvram_start, lm78_nvram_read, lm78_nvram_write, NULL, dev); } break; + + default: + break; } return 1; @@ -644,7 +662,7 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -lm78_i2c_write(void *bus, uint8_t addr, uint8_t val, void *priv) +lm78_i2c_write(UNUSED(void *bus), UNUSED(uint8_t addr), uint8_t val, void *priv) { lm78_t *dev = (lm78_t *) priv; @@ -694,13 +712,16 @@ lm78_as99127f_write(void *priv, uint8_t reg, uint8_t val) resetx86(); } break; + + default: + break; } return 1; } static void -lm78_reset_timer(void *priv) +lm78_reset_timer(UNUSED(void *priv)) { pc_reset_hard(); } diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c index 877138a4a1..b6a0dddda8 100644 --- a/src/device/hwm_vt82c686.c +++ b/src/device/hwm_vt82c686.c @@ -25,6 +25,7 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/hwm.h> +#include <86box/plat_unused.h> #define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) /* Formulas and factors derived from Linux's via686a.c driver. */ @@ -32,7 +33,7 @@ #define VT82C686_TEMP_TO_REG(t) (-1.160370e-10 * (t * t * t * t * t * t) + 3.193693e-08 * (t * t * t * t * t) - 1.464447e-06 * (t * t * t * t) - 2.525453e-04 * (t * t * t) + 1.424593e-02 * (t * t) + 2.148941e+00 * t + 7.275808e+01) #define VT82C686_VOLTAGE_TO_REG(v, f) CLAMP((((v) * (2.628 / (f))) - 120.5) / 25, 0, 255) -typedef struct { +typedef struct vt82c686_t { hwm_values_t *values; uint8_t enable; @@ -47,8 +48,8 @@ static void vt82c686_reset(vt82c686_t *dev, uint8_t initialization); static uint8_t vt82c686_read(uint16_t addr, void *priv) { - vt82c686_t *dev = (vt82c686_t *) priv; - uint8_t ret; + const vt82c686_t *dev = (vt82c686_t *) priv; + uint8_t ret; addr -= dev->io_base; @@ -113,6 +114,9 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv) case 0x48: val &= 0x7f; break; + + default: + break; } dev->regs[reg] = val; @@ -143,6 +147,9 @@ vt82c686_hwm_write(uint8_t addr, uint8_t val, void *priv) case 0x74: dev->enable = val & 0x01; break; + + default: + break; } if (dev->enable && dev->io_base) @@ -174,7 +181,7 @@ vt82c686_close(void *priv) } static void * -vt82c686_init(const device_t *info) +vt82c686_init(UNUSED(const device_t *info)) { vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); memset(dev, 0, sizeof(vt82c686_t)); diff --git a/src/device/i2c.c b/src/device/i2c.c index 7937aa10d4..56e6f8f4c6 100644 --- a/src/device/i2c.c +++ b/src/device/i2c.c @@ -38,9 +38,10 @@ typedef struct _i2c_ { struct _i2c_ *prev, *next; } i2c_t; -typedef struct { +typedef struct i2c_bus_t { char *name; - i2c_t *devices[NADDRS], *last[NADDRS]; + i2c_t *devices[NADDRS]; + i2c_t *last[NADDRS]; } i2c_bus_t; void *i2c_smbus; @@ -204,9 +205,9 @@ i2c_handler(int set, void *bus_handle, uint8_t base, int size, uint8_t i2c_start(void *bus_handle, uint8_t addr, uint8_t read) { - uint8_t ret = 0; - i2c_bus_t *bus = (i2c_bus_t *) bus_handle; - i2c_t *p; + uint8_t ret = 0; + const i2c_bus_t *bus = (i2c_bus_t *) bus_handle; + i2c_t *p; if (!bus) return ret; @@ -229,9 +230,9 @@ i2c_start(void *bus_handle, uint8_t addr, uint8_t read) uint8_t i2c_read(void *bus_handle, uint8_t addr) { - uint8_t ret = 0; - i2c_bus_t *bus = (i2c_bus_t *) bus_handle; - i2c_t *p; + uint8_t ret = 0; + const i2c_bus_t *bus = (i2c_bus_t *) bus_handle; + i2c_t *p; if (!bus) return ret; @@ -255,9 +256,9 @@ i2c_read(void *bus_handle, uint8_t addr) uint8_t i2c_write(void *bus_handle, uint8_t addr, uint8_t data) { - uint8_t ret = 0; - i2c_t *p; - i2c_bus_t *bus = (i2c_bus_t *) bus_handle; + uint8_t ret = 0; + i2c_t *p; + const i2c_bus_t *bus = (i2c_bus_t *) bus_handle; if (!bus) return ret; @@ -280,8 +281,8 @@ i2c_write(void *bus_handle, uint8_t addr, uint8_t data) void i2c_stop(void *bus_handle, uint8_t addr) { - i2c_bus_t *bus = (i2c_bus_t *) bus_handle; - i2c_t *p; + const i2c_bus_t *bus = (i2c_bus_t *) bus_handle; + i2c_t *p; if (!bus) return; diff --git a/src/device/i2c_gpio.c b/src/device/i2c_gpio.c index cb7cf6147b..22bdaffd3f 100644 --- a/src/device/i2c_gpio.c +++ b/src/device/i2c_gpio.c @@ -24,11 +24,18 @@ #include <86box/86box.h> #include <86box/i2c.h> -typedef struct { +typedef struct i2c_gpio_t { char *bus_name; void *i2c; - uint8_t prev_scl, prev_sda, slave_sda, started, - slave_addr_received, slave_addr, slave_read, pos, byte; + uint8_t prev_scl; + uint8_t prev_sda; + uint8_t slave_sda; + uint8_t started; + uint8_t slave_addr_received; + uint8_t slave_addr; + uint8_t slave_read; + uint8_t pos; + uint8_t byte; } i2c_gpio_t; #ifdef ENABLE_I2C_GPIO_LOG @@ -136,6 +143,9 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda) dev->slave_sda = !i2c_write(dev->i2c, dev->slave_addr, dev->byte); i2c_gpio_log(2, "I2C GPIO %s: Write %02X %sACK\n", dev->bus_name, dev->byte, dev->slave_sda ? "N" : ""); break; + + default: + break; } } else if (dev->pos == 9) { switch (dev->slave_read) { @@ -161,14 +171,16 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda) uint8_t i2c_gpio_get_scl(void *dev_handle) { - i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; + const i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; + return dev->prev_scl; } uint8_t i2c_gpio_get_sda(void *dev_handle) { - i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; + const i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle; + i2c_gpio_log(3, "I2C GPIO %s: read myscl=%d mysda=%d slavesda=%d\n", dev->bus_name, dev->prev_scl, dev->prev_sda, dev->slave_sda); return dev->prev_sda && dev->slave_sda; } diff --git a/src/device/ibm_5161.c b/src/device/ibm_5161.c index ea62c2abfa..762a379a11 100644 --- a/src/device/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -26,11 +26,11 @@ #include <86box/pci.h> #include <86box/timer.h> #include <86box/pit.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/machine.h> -typedef struct -{ +typedef struct ibm_5161_t { uint8_t regs[8]; } ibm_5161_t; @@ -45,8 +45,8 @@ ibm_5161_out(uint16_t port, uint8_t val, void *priv) static uint8_t ibm_5161_in(uint16_t port, void *priv) { - ibm_5161_t *dev = (ibm_5161_t *) priv; - uint8_t ret = 0xff; + const ibm_5161_t *dev = (ibm_5161_t *) priv; + uint8_t ret = 0xff; ret = dev->regs[port & 0x0007]; @@ -73,8 +73,11 @@ ibm_5161_in(uint16_t port, void *priv) 02-03 = not used 04-07 = switch position 1 = Off - 0 =On */ - ret = dev->regs[3] & 0x01; + 0 = On */ + ret = (dev->regs[3] & 0x01) | (((~(0xf - ((mem_size + isa_mem_size) >> 6))) & 0xf) << 4); + break; + + default: break; } @@ -82,18 +85,17 @@ ibm_5161_in(uint16_t port, void *priv) } static void -ibm_5161_close(void *p) +ibm_5161_close(void *priv) { - ibm_5161_t *dev = (ibm_5161_t *) p; + ibm_5161_t *dev = (ibm_5161_t *) priv; free(dev); } static void * -ibm_5161_init(const device_t *info) +ibm_5161_init(UNUSED(const device_t *info)) { - ibm_5161_t *dev = (ibm_5161_t *) malloc(sizeof(ibm_5161_t)); - memset(dev, 0, sizeof(ibm_5161_t)); + ibm_5161_t *dev = (ibm_5161_t *) calloc(1, sizeof(ibm_5161_t)); /* Extender Card Registers */ io_sethandler(0x0210, 0x0004, diff --git a/src/device/isamem.c b/src/device/isamem.c index 708274fcac..5b880d6eb4 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -112,7 +112,7 @@ #define EXTRAM_HIGH 1 #define EXTRAM_XMS 2 -typedef struct { +typedef struct emsreg_t { int8_t enabled; /* 1=ENABLED */ uint8_t page; /* page# in EMS RAM */ uint8_t frame; /* (varies with board) */ @@ -121,15 +121,15 @@ typedef struct { mem_mapping_t mapping; /* mapping entry for page */ } emsreg_t; -typedef struct { +typedef struct ext_ram_t { uint32_t base; uint8_t *ptr; } ext_ram_t; -typedef struct { +typedef struct memdev_t { const char *name; - uint8_t board : 6, /* board type */ - reserved : 2; + uint8_t board : 6; /* board type */ + uint8_t reserved : 2; uint8_t flags; #define FLAG_CONFIG 0x01 /* card is configured */ @@ -138,12 +138,12 @@ typedef struct { #define FLAG_EMS 0x40 /* card has EMS mode enabled */ uint16_t total_size; /* configured size in KB */ - uint32_t base_addr, /* configured I/O address */ - start_addr, /* configured memory start */ - frame_addr; /* configured frame address */ + uint32_t base_addr; /* configured I/O address */ + uint32_t start_addr; /* configured memory start */ + uint32_t frame_addr; /* configured frame address */ - uint16_t ems_size, /* EMS size in KB */ - ems_pages; /* EMS size in pages */ + uint16_t ems_size; /* EMS size in KB */ + uint16_t ems_pages; /* EMS size in pages */ uint32_t ems_start; /* start of EMS in RAM */ uint8_t *ram; /* allocated RAM buffer */ @@ -288,9 +288,9 @@ ems_writew(uint32_t addr, uint16_t val, void *priv) static uint8_t ems_read(uint16_t port, void *priv) { - memdev_t *dev = (memdev_t *) priv; - uint8_t ret = 0xff; - int vpage; + const memdev_t *dev = (memdev_t *) priv; + uint8_t ret = 0xff; + int vpage; /* Get the viewport page number. */ vpage = (port / EMS_PGSIZE); @@ -305,6 +305,9 @@ ems_read(uint16_t port, void *priv) case 0x0001: /* W/O */ break; + + default: + break; } #if ISAMEM_DEBUG @@ -383,6 +386,9 @@ ems_write(uint16_t port, uint8_t val, void *priv) if (val) dev->flags |= FLAG_CONFIG; break; + + default: + break; } } @@ -458,6 +464,9 @@ isamem_init(const device_t *info) if (!!device_get_config_int("speed")) dev->flags |= FLAG_FAST; break; + + default: + break; } /* Fix up the memory start address. */ @@ -471,6 +480,7 @@ isamem_init(const device_t *info) isamem_log(", FAST"); if (dev->flags & FLAG_WIDE) isamem_log(", 16BIT"); + isamem_log(")\n"); /* Force (back to) 8-bit bus if needed. */ @@ -617,6 +627,7 @@ isamem_init(const device_t *info) dev->base_addr, dev->ems_size, dev->ems_pages); if (dev->frame_addr > 0) isamem_log(", Frame=%05XH", dev->frame_addr); + isamem_log("\n"); /* diff --git a/src/device/isapnp.c b/src/device/isapnp.c index fcf6053aed..f9d10b3801 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -26,31 +26,24 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/isapnp.h> +#include <86box/plat_unused.h> #define CHECK_CURRENT_LD() \ - if (!dev->current_ld) { \ + if (!ld) { \ isapnp_log("ISAPnP: No logical device selected\n"); \ - break; \ + goto vendor_defined; \ } -#define CHECK_CURRENT_CARD() \ - if (1) { \ - card = dev->first_card; \ - while (card) { \ - if (card->enable && (card->state == PNP_STATE_CONFIG)) \ - break; \ - card = card->next; \ - } \ - if (!card) { \ - isapnp_log("ISAPnP: No card in CONFIG state\n"); \ - break; \ - } \ +#define CHECK_CURRENT_CARD() \ + if (!card) { \ + isapnp_log("ISAPnP: No card in CONFIG state\n"); \ + break; \ } -static const uint8_t pnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, - 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61, - 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, - 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39 }; +const uint8_t isapnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, + 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61, + 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, + 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39 }; static const device_t isapnp_device; #ifdef ENABLE_ISAPNP_LOG @@ -81,34 +74,49 @@ enum { typedef struct _isapnp_device_ { uint8_t number; uint8_t regs[256]; - uint8_t mem_upperlimit, irq_types, io_16bit, io_len[8]; + uint8_t mem_upperlimit; + uint8_t irq_types; + uint8_t io_16bit; + uint8_t io_len[8]; const isapnp_device_config_t *defaults; struct _isapnp_device_ *next; } isapnp_device_t; typedef struct _isapnp_card_ { - uint8_t enable, state, csn, id_checksum, serial_read, serial_read_pair, serial_read_pos, *rom; - uint16_t rom_pos, rom_size; + uint8_t enable; + uint8_t state; + uint8_t csn; + uint8_t ld; + uint8_t id_checksum; + uint8_t serial_read; + uint8_t serial_read_pair; + uint8_t serial_read_pos; + uint8_t *rom; + uint16_t rom_pos; + uint16_t rom_size; void *priv; /* ISAPnP memory and I/O addresses are awkwardly big endian, so we populate this structure whenever something on some device changes, and pass it on instead. */ isapnp_device_config_t config; - void (*config_changed)(uint8_t ld, isapnp_device_config_t *config, void *priv); - void (*csn_changed)(uint8_t csn, void *priv); + void (*config_changed)(uint8_t ld, isapnp_device_config_t *config, void *priv); + void (*csn_changed)(uint8_t csn, void *priv); uint8_t (*read_vendor_reg)(uint8_t ld, uint8_t reg, void *priv); - void (*write_vendor_reg)(uint8_t ld, uint8_t reg, uint8_t val, void *priv); + void (*write_vendor_reg)(uint8_t ld, uint8_t reg, uint8_t val, void *priv); isapnp_device_t *first_ld; struct _isapnp_card_ *next; } isapnp_card_t; typedef struct { - uint8_t reg, key_pos : 5; + uint8_t reg; + uint8_t key_pos : 5; uint16_t read_data_addr; - isapnp_card_t *first_card, *isolated_card, *current_ld_card; + isapnp_card_t *first_card; + isapnp_card_t *isolated_card; + isapnp_card_t *current_ld_card; isapnp_device_t *current_ld; } isapnp_t; @@ -116,41 +124,40 @@ static void isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) { /* Ignore card if it hasn't signed up for configuration changes. */ - if (!card->config_changed) + if ((card == NULL) || !card->config_changed) return; /* Populate config structure, performing endianness conversion as needed. */ card->config.activate = ld->regs[0x30] & 0x01; - uint8_t i; uint8_t reg_base; - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { reg_base = 0x40 + (8 * i); card->config.mem[i].base = (ld->regs[reg_base] << 16) | (ld->regs[reg_base + 1] << 8); card->config.mem[i].size = (ld->regs[reg_base + 3] << 16) | (ld->regs[reg_base + 4] << 8); if (ld->regs[reg_base + 2] & 0x01) /* upper limit */ card->config.mem[i].size -= card->config.mem[i].base; } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i)); card->config.mem32[i].base = (ld->regs[reg_base] << 24) | (ld->regs[reg_base + 1] << 16) | (ld->regs[reg_base + 2] << 8) | ld->regs[reg_base + 3]; card->config.mem32[i].size = (ld->regs[reg_base + 5] << 24) | (ld->regs[reg_base + 6] << 16) | (ld->regs[reg_base + 7] << 8) | ld->regs[reg_base + 8]; if (ld->regs[reg_base + 4] & 0x01) /* upper limit */ card->config.mem32[i].size -= card->config.mem32[i].base; } - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { reg_base = 0x60 + (2 * i); if (ld->regs[0x31] & 0x02) card->config.io[i].base = 0; /* let us handle I/O range check reads */ else card->config.io[i].base = (ld->regs[reg_base] << 8) | ld->regs[reg_base + 1]; } - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { reg_base = 0x70 + (2 * i); card->config.irq[i].irq = ld->regs[reg_base]; card->config.irq[i].level = ld->regs[reg_base + 1] & 0x02; card->config.irq[i].type = ld->regs[reg_base + 1] & 0x01; } - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { reg_base = 0x74 + i; card->config.dma[i].dma = ld->regs[reg_base]; } @@ -169,10 +176,9 @@ isapnp_reset_ld_config(isapnp_device_t *ld) /* Populate configuration registers. */ ld->regs[0x30] = !!config->activate; - uint8_t i; - uint8_t reg_base; + uint8_t reg_base; uint32_t size; - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { reg_base = 0x40 + (8 * i); ld->regs[reg_base] = config->mem[i].base >> 16; ld->regs[reg_base + 1] = config->mem[i].base >> 8; @@ -182,7 +188,7 @@ isapnp_reset_ld_config(isapnp_device_t *ld) ld->regs[reg_base + 3] = size >> 16; ld->regs[reg_base + 4] = size >> 8; } - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i)); ld->regs[reg_base] = config->mem32[i].base >> 24; ld->regs[reg_base + 1] = config->mem32[i].base >> 16; @@ -196,17 +202,17 @@ isapnp_reset_ld_config(isapnp_device_t *ld) ld->regs[reg_base + 7] = size >> 8; ld->regs[reg_base + 8] = size; } - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { reg_base = 0x60 + (2 * i); ld->regs[reg_base] = config->io[i].base >> 8; ld->regs[reg_base + 1] = config->io[i].base; } - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { reg_base = 0x70 + (2 * i); ld->regs[reg_base] = config->irq[i].irq; ld->regs[reg_base + 1] = (!!config->irq[i].level << 1) | !!config->irq[i].type; } - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { reg_base = 0x74 + i; ld->regs[reg_base] = config->dma[i].dma; } @@ -221,15 +227,14 @@ isapnp_reset_ld_regs(isapnp_device_t *ld) ld->regs[0x74] = ld->regs[0x75] = ISAPNP_DMA_DISABLED; /* Set the upper limit bit on memory ranges which require it. */ - uint8_t i; - for (i = 0; i < 4; i++) + for (uint8_t i = 0; i < 4; i++) ld->regs[0x42 + (8 * i)] |= !!(ld->mem_upperlimit & (1 << i)); ld->regs[0x7a] |= !!(ld->mem_upperlimit & (1 << 4)); - for (i = 1; i < 4; i++) + for (uint8_t i = 1; i < 4; i++) ld->regs[0x84 + (16 * i)] |= !!(ld->mem_upperlimit & (1 << (4 + i))); /* Set the default IRQ type bits. */ - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { if (ld->irq_types & (0x1 << (4 * i))) ld->regs[0x70 + (2 * i)] = 0x02; else if (ld->irq_types & (0x2 << (4 * i))) @@ -245,22 +250,21 @@ isapnp_reset_ld_regs(isapnp_device_t *ld) } static uint8_t -isapnp_read_rangecheck(uint16_t addr, void *priv) +isapnp_read_rangecheck(UNUSED(uint16_t addr), void *priv) { - isapnp_device_t *dev = (isapnp_device_t *) priv; + const isapnp_device_t *dev = (isapnp_device_t *) priv; + return (dev->regs[0x31] & 0x01) ? 0x55 : 0xaa; } static uint8_t -isapnp_read_data(uint16_t addr, void *priv) +isapnp_read_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint8_t reg) { - isapnp_t *dev = (isapnp_t *) priv; - uint8_t ret = 0xff; - uint8_t bit; - uint8_t next_shift; - isapnp_card_t *card; + uint8_t ret = 0xff; + uint8_t bit; + uint8_t next_shift; - switch (dev->reg) { + switch (reg) { case 0x01: /* Serial Isolation */ card = dev->first_card; while (card) { @@ -329,78 +333,52 @@ isapnp_read_data(uint16_t addr, void *priv) ret = 0x00; CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: Query LDN for CSN %02X device %02X\n", dev->current_ld_card->csn, dev->current_ld->number); - ret = dev->current_ld->number; + isapnp_log("ISAPnP: Query LDN for CSN %02X device %02X\n", card->csn, ld->number); + ret = ld->number; break; - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: + case 0x20 ... 0x2f: + case 0x38 ... 0x3f: + case 0xa9 ... 0xff: +vendor_defined: CHECK_CURRENT_CARD(); - isapnp_log("ISAPnP: Read vendor-defined register %02X from CSN %02X\n", dev->reg, card->csn); + isapnp_log("ISAPnP: Read vendor-defined register %02X from CSN %02X device %02X\n", reg, card->csn, ld ? ld->number : -1); if (card->read_vendor_reg) - ret = card->read_vendor_reg(0, dev->reg, card->priv); - break; - - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: Read vendor-defined register %02X from CSN %02X device %02X\n", dev->reg, dev->current_ld_card->csn, dev->current_ld->number); - if (dev->current_ld_card->read_vendor_reg) - ret = dev->current_ld_card->read_vendor_reg(dev->current_ld->number, dev->reg, dev->current_ld_card->priv); + ret = card->read_vendor_reg(ld ? ld->number : -1, reg, card->priv); break; default: - if (dev->reg >= 0x30) { + if (reg >= 0x30) { CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: Read register %02X from CSN %02X device %02X\n", dev->reg, dev->current_ld_card->csn, dev->current_ld->number); - ret = dev->current_ld->regs[dev->reg]; + isapnp_log("ISAPnP: Read register %02X from CSN %02X device %02X\n", reg, card->csn, ld->number); + ret = ld->regs[reg]; } break; } - isapnp_log("ISAPnP: read_data(%02X) = %02X\n", dev->reg, ret); + isapnp_log("ISAPnP: read_common(%02X) = %02X\n", reg, ret); return ret; } +static uint8_t +isapnp_read_data(UNUSED(uint16_t addr), void *priv) +{ + isapnp_t *dev = (isapnp_t *) priv; + isapnp_card_t *card = dev->first_card; + while (card) { + if (card->enable && (card->state == PNP_STATE_CONFIG)) + break; + card = card->next; + } + + isapnp_log("ISAPnP: read_data() => "); + return isapnp_read_common(dev, card, dev->current_ld, dev->reg); +} + static void isapnp_set_read_data(uint16_t addr, isapnp_t *dev) { @@ -418,7 +396,7 @@ isapnp_set_read_data(uint16_t addr, isapnp_t *dev) } static void -isapnp_write_addr(uint16_t addr, uint8_t val, void *priv) +isapnp_write_addr(UNUSED(uint16_t addr), uint8_t val, void *priv) { isapnp_t *dev = (isapnp_t *) priv; isapnp_card_t *card = dev->first_card; @@ -432,7 +410,7 @@ isapnp_write_addr(uint16_t addr, uint8_t val, void *priv) if (card->state == PNP_STATE_WAIT_FOR_KEY) { /* checking only the first card should be fine */ /* Check written value against LFSR key. */ - if (val == pnp_init_key[dev->key_pos]) { + if (val == isapnp_init_key[dev->key_pos]) { dev->key_pos++; if (!dev->key_pos) { isapnp_log("ISAPnP: Key unlocked, putting cards to SLEEP\n"); @@ -449,17 +427,14 @@ isapnp_write_addr(uint16_t addr, uint8_t val, void *priv) } static void -isapnp_write_data(uint16_t addr, uint8_t val, void *priv) +isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint8_t reg, uint8_t val) { - isapnp_t *dev = (isapnp_t *) priv; - isapnp_card_t *card; - isapnp_device_t *ld; - uint16_t io_addr; - uint16_t reset_cards = 0; + uint16_t io_addr; + uint16_t reset_cards = 0; - isapnp_log("ISAPnP: write_data(%02X)\n", val); + isapnp_log("ISAPnP: write_common(%02X, %02X)\n", reg, val); - switch (dev->reg) { + switch (reg) { case 0x00: /* Set RD_DATA Port */ isapnp_set_read_data((val << 2) | 3, dev); isapnp_log("ISAPnP: Read data port set to %04X\n", dev->read_data_addr); @@ -513,7 +488,7 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) while (card) { if (card->csn == val) { card->rom_pos = 0; - card->id_checksum = pnp_init_key[0]; + card->id_checksum = isapnp_init_key[0]; if (card->state == PNP_STATE_SLEEP) card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG; } else { @@ -538,6 +513,7 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x07: /* Logical Device Number */ CHECK_CURRENT_CARD(); + card->ld = val; ld = card->first_ld; while (ld) { if (ld->number == val) { @@ -557,10 +533,10 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x30: /* Activate */ CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: %sctivate CSN %02X device %02X\n", (val & 0x01) ? "A" : "Dea", dev->current_ld_card->csn, dev->current_ld->number); + isapnp_log("ISAPnP: %sctivate CSN %02X device %02X\n", (val & 0x01) ? "A" : "Dea", card->csn, ld->number); - dev->current_ld->regs[dev->reg] = val & 0x01; - isapnp_device_config_changed(dev->current_ld_card, dev->current_ld); + ld->regs[reg] = val & 0x01; + isapnp_device_config_changed(card, ld); break; @@ -568,80 +544,39 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) CHECK_CURRENT_LD(); for (uint8_t i = 0; i < 8; i++) { - if (!dev->current_ld->io_len[i]) + if (!ld->io_len[i]) continue; - io_addr = (dev->current_ld->regs[0x60 + (2 * i)] << 8) | dev->current_ld->regs[0x61 + (2 * i)]; - if (dev->current_ld->regs[dev->reg] & 0x02) - io_removehandler(io_addr, dev->current_ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); + io_addr = (ld->regs[0x60 + (2 * i)] << 8) | ld->regs[0x61 + (2 * i)]; + if (ld->regs[reg] & 0x02) + io_removehandler(io_addr, ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, ld); if (val & 0x02) - io_sethandler(io_addr, dev->current_ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, dev->current_ld); + io_sethandler(io_addr, ld->io_len[i], isapnp_read_rangecheck, NULL, NULL, NULL, NULL, NULL, ld); } - dev->current_ld->regs[dev->reg] = val & 0x03; - isapnp_device_config_changed(dev->current_ld_card, dev->current_ld); + ld->regs[reg] = val & 0x03; + isapnp_device_config_changed(card, ld); break; - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: + case 0x20 ... 0x2f: + case 0x38 ... 0x3f: + case 0xa9 ... 0xff: +vendor_defined: CHECK_CURRENT_CARD(); - isapnp_log("ISAPnP: Write %02X to vendor-defined register %02X on CSN %02X\n", val, dev->reg, card->csn); + isapnp_log("ISAPnP: Write %02X to vendor-defined register %02X on CSN %02X device %02X\n", val, reg, card->csn, ld ? ld->number : -1); if (card->write_vendor_reg) - card->write_vendor_reg(0, dev->reg, val, card->priv); - break; - - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: Write %02X to vendor-defined register %02X on CSN %02X device %02X\n", val, dev->reg, dev->current_ld_card->csn, dev->current_ld->number); - if (dev->current_ld_card->write_vendor_reg) - dev->current_ld_card->write_vendor_reg(dev->current_ld->number, dev->reg, val, dev->current_ld_card->priv); + card->write_vendor_reg(ld ? ld->number : -1, reg, val, card->priv); break; default: - if (dev->reg >= 0x40) { + if (reg >= 0x40) { CHECK_CURRENT_LD(); - isapnp_log("ISAPnP: Write %02X to register %02X on CSN %02X device %02X\n", val, dev->reg, dev->current_ld_card->csn, dev->current_ld->number); + isapnp_log("ISAPnP: Write %02X to register %02X on CSN %02X device %02X\n", val, reg, card->csn, ld->number); - switch (dev->reg) { + switch (reg) { case 0x42: case 0x4a: case 0x52: @@ -651,7 +586,7 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x94: case 0xa4: /* Read-only memory range length / upper limit bit. */ - val = (val & 0xfe) | (dev->current_ld->regs[dev->reg] & 0x01); + val = (val & 0xfe) | (ld->regs[reg] & 0x01); break; case 0x60: @@ -663,35 +598,56 @@ isapnp_write_data(uint16_t addr, uint8_t val, void *priv) case 0x6c: case 0x6e: /* Discard upper address bits if this I/O range can only decode 10-bit. */ - if (!(dev->current_ld->io_16bit & (1 << ((dev->reg >> 1) & 0x07)))) + if (!(ld->io_16bit & (1 << ((reg >> 1) & 0x07)))) val &= 0x03; break; case 0x71: case 0x73: /* Limit IRQ types to supported ones. */ - if ((val & 0x01) && !(dev->current_ld->irq_types & ((dev->reg == 0x71) ? 0x0c : 0xc0))) /* level, not supported = force edge */ + if ((val & 0x01) && !(ld->irq_types & ((reg == 0x71) ? 0x0c : 0xc0))) /* level, not supported = force edge */ val &= ~0x01; - else if (!(val & 0x01) && !(dev->current_ld->irq_types & ((dev->reg == 0x71) ? 0x03 : 0x30))) /* edge, not supported = force level */ + else if (!(val & 0x01) && !(ld->irq_types & ((reg == 0x71) ? 0x03 : 0x30))) /* edge, not supported = force level */ val |= 0x01; - if ((val & 0x02) && !(dev->current_ld->irq_types & ((dev->reg == 0x71) ? 0x05 : 0x50))) /* high, not supported = force low */ + if ((val & 0x02) && !(ld->irq_types & ((reg == 0x71) ? 0x05 : 0x50))) /* high, not supported = force low */ val &= ~0x02; - else if (!(val & 0x02) && !(dev->current_ld->irq_types & ((dev->reg == 0x71) ? 0x0a : 0xa0))) /* low, not supported = force high */ + else if (!(val & 0x02) && !(ld->irq_types & ((reg == 0x71) ? 0x0a : 0xa0))) /* low, not supported = force high */ val |= 0x02; break; + + default: + break; } - dev->current_ld->regs[dev->reg] = val; - isapnp_device_config_changed(dev->current_ld_card, dev->current_ld); + ld->regs[reg] = val; + isapnp_device_config_changed(card, ld); } break; } } +static void +isapnp_write_data(UNUSED(uint16_t addr), uint8_t val, void *priv) +{ + isapnp_t *dev = (isapnp_t *) priv; + isapnp_card_t *card = NULL; + if (!card) { + card = dev->first_card; + while (card) { + if (card->enable && (card->state == PNP_STATE_CONFIG)) + break; + card = card->next; + } + } + + isapnp_log("ISAPnP: write_data(%02X) => ", val); + isapnp_write_common(dev, card, dev->current_ld, dev->reg, val); +} + static void * -isapnp_init(const device_t *info) +isapnp_init(UNUSED(const device_t *info)) { isapnp_t *dev = (isapnp_t *) malloc(sizeof(isapnp_t)); memset(dev, 0, sizeof(isapnp_t)); @@ -779,22 +735,28 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) #ifdef ENABLE_ISAPNP_LOG uint16_t vendor = (card->rom[0] << 8) | card->rom[1]; isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]); + const char *df_priority[] = { "good", "acceptable", "sub-optimal", "unknown priority" }; + const char *mem_control[] = { "8-bit", "16-bit", "8/16-bit", "32-bit" }; + const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "unknown" }; + const char *dma_speed[] = { "compatibility", "Type A", "Type B", "Type F" }; #endif uint16_t i = 9; uint8_t existing = 0; - uint8_t ldn = 0; + uint8_t ldn = 0; uint8_t res; - uint8_t in_df = 0; - uint8_t irq = 0; - uint8_t io = 0; - uint8_t mem_range = 0; - uint8_t mem_range_32 = 0; - uint8_t irq_df = 0; - uint8_t io_df = 0; - uint8_t mem_range_df = 0; + uint8_t in_df = 0; + uint8_t irq = 0; + uint8_t dma = 0; + uint8_t io = 0; + uint8_t mem_range = 0; + uint8_t mem_range_32 = 0; + uint8_t irq_df = 0; + uint8_t dma_df = 0; + uint8_t io_df = 0; + uint8_t mem_range_df = 0; uint8_t mem_range_32_df = 0; uint32_t len; - isapnp_device_t *ld = NULL; + isapnp_device_t *ld = NULL; isapnp_device_t *prev_ld = NULL; /* Check if this is an existing card which already has logical devices. @@ -822,7 +784,10 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s Memory range %d uses upper limit = ", in_df ? ">" : "", mem_range); + isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X, align %d", + in_df ? ">" : "", mem_range, + *((uint16_t *) &card->rom[i + 10]) << 8, *((uint16_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint16_t *) &card->rom[i + 4]) << 8)) + (*((uint16_t *) &card->rom[i + 6]) << 8), + (*((uint16_t *) &card->rom[i + 8]) + 1) << 16); res = 1 << mem_range; mem_range++; } else { @@ -836,18 +801,27 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s 32-bit memory range %d uses upper limit = ", in_df ? ">" : "", mem_range_32); + isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", in_df ? ">" : "", mem_range_32, + *((uint32_t *) &card->rom[i + 16]) << 8, *((uint32_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint32_t *) &card->rom[i + 4]) << 8)) + (*((uint32_t *) &card->rom[i + 8]) << 8), + *((uint32_t *) &card->rom[i + 12])); res = 1 << (4 + mem_range_32); mem_range_32++; } - if (card->rom[i + 3] & 0x4) { - isapnp_log("yes\n"); +#ifdef ENABLE_ISAPNP_LOG + isapnp_log(" bytes, %swritable, %sread cacheable, %s, %s, %sshadowable, %sexpansion ROM\n", + (card->rom[i + 3] & 0x01) ? "not " : "", + (card->rom[i + 3] & 0x02) ? "not " : "", + (card->rom[i + 3] & 0x04) ? "upper limit" : "range length", + mem_control[(card->rom[i + 3] >> 3) & 0x03], + (card->rom[i + 3] & 0x20) ? "not " : "", + (card->rom[i + 3] & 0x40) ? "not " : ""); +#endif + + if (card->rom[i + 3] & 0x4) ld->mem_upperlimit |= res; - } else { - isapnp_log("no\n"); + else ld->mem_upperlimit &= ~res; - } break; @@ -858,11 +832,11 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) isapnp_log("ISAPnP: >%s ANSI identifier: \"%s\"\n", ldn ? ">" : "", &card->rom[i + 3]); card->rom[i + 3 + len] = res; break; +#endif default: isapnp_log("ISAPnP: >%s%s Large resource %02X (length %d)\n", ldn ? ">" : "", in_df ? ">" : "", res, (card->rom[i + 2] << 8) | card->rom[i + 1]); break; -#endif } i += 3; /* header */ @@ -871,7 +845,13 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) len = card->rom[i] & 0x07; switch (res) { - case 0x02: +#ifdef ENABLE_ISAPNP_LOG + case 0x01: /* PnP version */ + isapnp_log("ISAPnP: > PnP version %d.%d, vendor-specific version %02X\n", card->rom[i + 1] >> 4, card->rom[i + 1] & 0x0f, card->rom[i + 2]); + break; +#endif + + case 0x02: /* logical device */ #ifdef ENABLE_ISAPNP_LOG vendor = (card->rom[i + 1] << 8) | card->rom[i + 2]; isapnp_log("ISAPnP: > Logical device %02X: %c%c%c%02X%02X\n", ldn, '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[i + 3], card->rom[i + 4]); @@ -912,7 +892,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) ld->number = ldn++; /* Start the position counts over. */ - irq = io = mem_range = mem_range_32 = irq_df = io_df = mem_range_df = mem_range_32_df = 0; + irq = dma = io = mem_range = mem_range_32 = irq_df = dma_df = io_df = mem_range_df = mem_range_32_df = 0; break; @@ -944,7 +924,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) else /* specific */ res = card->rom[i + 3] & 0x0f; - isapnp_log("ISAPnP: >>%s IRQ index %d interrupt types = %01X\n", in_df ? ">" : "", irq, res); + isapnp_log("ISAPnP: >>%s IRQ index %d with mask %04X, types %01X\n", in_df ? ">" : "", irq, *((uint16_t *) &card->rom[i + 1]), res); ld->irq_types &= ~(0x0f << (4 * irq)); ld->irq_types |= res << (4 * irq); @@ -953,24 +933,39 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; +#ifdef ENABLE_ISAPNP_LOG + case 0x05: /* DMA */ + isapnp_log("ISAPnP: >>%s DMA index %d with mask %02X, %s, %sbus master, %scount by byte, %scount by word, %s speed\n", in_df ? ">" : "", dma++, card->rom[i + 1], + dma_transfer[card->rom[i + 2] & 3], + (card->rom[i + 2] & 0x04) ? "not " : "", + (card->rom[i + 2] & 0x08) ? "not " : "", + (card->rom[i + 2] & 0x10) ? "not " : "", + dma_speed[(card->rom[i + 2] >> 5) & 3]); + break; +#endif + case 0x06: /* start dependent function */ if (!ld) { isapnp_log("ISAPnP: >> Start dependent function with no logical device\n"); break; } - isapnp_log("ISAPnP: >> Start dependent function: %s\n", (((len == 0) || (card->rom[i + 1] == 1)) ? "acceptable" : ((card->rom[i + 1] == 0) ? "good" : ((card->rom[i + 1] == 2) ? "sub-optimal" : "unknown priority")))); +#ifdef ENABLE_ISAPNP_LOG + isapnp_log("ISAPnP: >> Start dependent function: %s\n", df_priority[(len < 1) ? 1 : (card->rom[i + 1] & 3)]); +#endif if (in_df) { /* We're in a dependent function and this is the next one starting. Walk positions back to the saved values. */ irq = irq_df; + dma = dma_df; io = io_df; mem_range = mem_range_df; mem_range_32 = mem_range_32_df; } else { /* Save current positions to restore at the next DF. */ irq_df = irq; + dma_df = dma; io_df = io; mem_range_df = mem_range; mem_range_32_df = mem_range_32; @@ -995,7 +990,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s I/O range %d %d-bit decode, %d ports\n", in_df ? ">" : "", io, (card->rom[i + 1] & 0x01) ? 16 : 10, card->rom[i + 7]); + isapnp_log("ISAPnP: >>%s I/O range %d with %d ports at %04X-%04X, align %d, %d-bit decode\n", in_df ? ">" : "", io, card->rom[i + 7], *((uint16_t *) &card->rom[i + 2]), *((uint16_t *) &card->rom[i + 4]), card->rom[i + 6], (card->rom[i + 1] & 0x01) ? 16 : 10); if (card->rom[i + 1] & 0x01) ld->io_16bit |= 1 << io; @@ -1022,11 +1017,9 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) card->rom_size = i + 2; break; -#ifdef ENABLE_ISAPNP_LOG default: isapnp_log("ISAPnP: >%s%s Small resource %02X (length %d)\n", ldn ? ">" : "", in_df ? ">" : "", res, card->rom[i] & 0x07); break; -#endif } i++; /* header */ @@ -1082,6 +1075,32 @@ isapnp_set_csn(void *priv, uint8_t csn) card->csn_changed(card->csn, card->priv); } +uint8_t +isapnp_read_reg(void *priv, uint8_t ldn, uint8_t reg) +{ + isapnp_card_t *card = (isapnp_card_t *) priv; + isapnp_device_t *ld = card->first_ld; + while (ld) { + if (ld->number == ldn) + break; + ld = ld->next; + } + return isapnp_read_common(device_get_priv(&isapnp_device), card, ld, reg); +} + +void +isapnp_write_reg(void *priv, uint8_t ldn, uint8_t reg, uint8_t val) +{ + isapnp_card_t *card = (isapnp_card_t *) priv; + isapnp_device_t *ld = card->first_ld; + while (ld) { + if (ld->number == ldn) + break; + ld = ld->next; + } + isapnp_write_common(device_get_priv(&isapnp_device), card, ld, reg, val); +} + void isapnp_set_device_defaults(void *priv, uint8_t ldn, const isapnp_device_config_t *config) { diff --git a/src/device/isartc.c b/src/device/isartc.c index d2127146dc..46f31c1373 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -90,7 +90,7 @@ #define ISARTC_DEBUG 0 -typedef struct { +typedef struct rtcdev_t { const char *name; /* board name */ uint8_t board; /* board type */ @@ -103,18 +103,18 @@ typedef struct { uint32_t base_addr; /* configured I/O address */ /* Fields for the specific driver. */ - void (*f_wr)(uint16_t, uint8_t, void *); + void (*f_wr)(uint16_t, uint8_t, void *); uint8_t (*f_rd)(uint16_t, void *); - int8_t year; /* register for YEAR value */ - char pad[3]; + int8_t year; /* register for YEAR value */ + char pad[3]; nvr_t nvr; /* RTC/NVR */ } rtcdev_t; /************************************************************************ - * * - * Driver for the NatSemi MM58167 chip. * - * * + * * + * Driver for the NatSemi MM58167 chip. * + * * ************************************************************************/ #define MM67_REGS 32 @@ -191,11 +191,11 @@ mm67_chkalrm(nvr_t *nvr, int8_t addr) static void mm67_tick(nvr_t *nvr) { - rtcdev_t *dev = (rtcdev_t *) nvr->data; - uint8_t *regs = nvr->regs; - int mon; - int year; - int f = 0; + const rtcdev_t *dev = (rtcdev_t *) nvr->data; + uint8_t *regs = nvr->regs; + int mon; + int year; + int f = 0; /* Update and set interrupt if needed. */ regs[MM67_SEC] = RTC_BCDINC(nvr->regs[MM67_SEC], 1); @@ -295,8 +295,8 @@ mm67_tick(nvr_t *nvr) static void mm67_time_get(nvr_t *nvr, struct tm *tm) { - rtcdev_t *dev = (rtcdev_t *) nvr->data; - uint8_t *regs = nvr->regs; + const rtcdev_t *dev = (rtcdev_t *) nvr->data; + const uint8_t *regs = nvr->regs; /* NVR is in BCD data mode. */ tm->tm_sec = RTC_DCB(regs[MM67_SEC]); @@ -325,9 +325,9 @@ mm67_time_get(nvr_t *nvr, struct tm *tm) static void mm67_time_set(nvr_t *nvr, struct tm *tm) { - rtcdev_t *dev = (rtcdev_t *) nvr->data; - uint8_t *regs = nvr->regs; - int year; + const rtcdev_t *dev = (rtcdev_t *) nvr->data; + uint8_t *regs = nvr->regs; + int year; /* NVR is in BCD data mode. */ regs[MM67_SEC] = RTC_BCD(tm->tm_sec); @@ -427,7 +427,6 @@ mm67_write(uint16_t port, uint8_t val, void *priv) { rtcdev_t *dev = (rtcdev_t *) priv; int reg = port - dev->base_addr; - int i; #if ISARTC_DEBUG isartc_log("ISARTC: write(%04x, %02x)\n", port - dev->base_addr, val); @@ -452,7 +451,7 @@ mm67_write(uint16_t port, uint8_t val, void *priv) case MM67_RSTRAM: if (val == 0xff) { - for (i = MM67_AL_MSEC; i <= MM67_AL_MON; i++) + for (uint8_t i = MM67_AL_MSEC; i <= MM67_AL_MON; i++) dev->nvr.regs[i] = RTC_BCD(0); dev->nvr.regs[MM67_DOW] = RTC_BCD(1); dev->nvr.regs[MM67_DOM] = RTC_BCD(1); @@ -500,9 +499,9 @@ mm67_write(uint16_t port, uint8_t val, void *priv) } /************************************************************************ - * * - * Generic code for all supported chips. * - * * + * * + * Generic code for all supported chips. * + * * ************************************************************************/ /* Initialize the device for use. */ @@ -609,9 +608,6 @@ isartc_close(void *priv) io_removehandler(dev->base_addr, dev->base_addrsz, dev->f_rd, NULL, NULL, dev->f_wr, NULL, NULL, dev); - if (dev->nvr.fn != NULL) - free(dev->nvr.fn); - free(dev); } @@ -793,7 +789,7 @@ isartc_reset(void) device_add(boards[isartc_type].dev); } -char * +const char * isartc_get_internal_name(int board) { return device_get_internal_name(boards[board].dev); diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 5395f3ac2f..bc4a1f3665 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -25,10 +25,13 @@ #include #include <86box/86box.h> #include "cpu.h" +#include "x86seg.h" #include <86box/timer.h> #include <86box/io.h> #include <86box/pic.h> #include <86box/pit.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/ppi.h> #include <86box/mem.h> #include <86box/device.h> @@ -41,6 +44,9 @@ #include <86box/video.h> #include <86box/keyboard.h> +#include <86box/dma.h> +#include <86box/pci.h> + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -80,7 +86,9 @@ #define KBC_VEN_ACER 0x20 #define KBC_VEN_NCR 0x24 #define KBC_VEN_ALI 0x28 -#define KBC_VEN_MASK 0x3c +#define KBC_VEN_SIEMENS 0x2c +#define KBC_VEN_COMPAQ 0x30 +#define KBC_VEN_MASK 0x7c #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 @@ -103,12 +111,31 @@ enum { STATE_SCAN_AUX /* KBC is waiting for the auxiliary command response. */ }; -typedef struct { - uint8_t state, command, command_phase, status, - wantdata, ib, ob, sc_or, - mem_addr, p1, p2, old_p2, - misc_flags, ami_flags, key_ctrl_queue_start, key_ctrl_queue_end, - val, channel, stat_hi, pending; +typedef struct atkbc_t { + uint8_t state; + uint8_t command; + uint8_t command_phase; + uint8_t status; + uint8_t wantdata; + uint8_t ib; + uint8_t ob; + uint8_t sc_or; + uint8_t mem_addr; + uint8_t p1; + uint8_t p2; + uint8_t old_p2; + uint8_t misc_flags; + uint8_t ami_flags; + uint8_t key_ctrl_queue_start; + uint8_t key_ctrl_queue_end; + uint8_t val; + uint8_t channel; + uint8_t stat_hi; + uint8_t pending; + uint8_t irq_state; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; uint8_t mem[0x100]; @@ -117,8 +144,9 @@ typedef struct { uint32_t flags; - /* Main timer. */ - pc_timer_t send_delay_timer; + /* Main timers. */ + pc_timer_t kbc_poll_timer; + pc_timer_t kbc_dev_poll_timer; /* P2 pulse callback timer. */ pc_timer_t pulse_cb; @@ -126,8 +154,8 @@ typedef struct { /* Local copies of the pointers to both ports for easier swapping (AMI '5' MegaKey). */ kbc_at_port_t *ports[2]; - uint8_t (*write60_ven)(void *p, uint8_t val); - uint8_t (*write64_ven)(void *p, uint8_t val); + uint8_t (*write60_ven)(void *priv, uint8_t val); + uint8_t (*write64_ven)(void *priv, uint8_t val); } atkbc_t; /* Keyboard controller ports. */ @@ -279,6 +307,8 @@ kbc_translate(atkbc_t *dev, uint8_t val) case 0x4d: t3100e_notify_set(0x0f); break; /* Right */ + default: + break; } kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off"); @@ -305,7 +335,7 @@ static void kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) { uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - int temp = (channel == 1) ? kbc_translate(dev, val) : val; + int temp = (channel == 1) ? kbc_translate(dev, val) : ((int) val); if (temp == -1) return; @@ -326,15 +356,15 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) dev->status |= STAT_MFULL; if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1); - picint_common(1 << 1, 0, 0); + picint_common(1 << 12, 0, 1, NULL); + picint_common(1 << 1, 0, 0, NULL); } else { if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1); - picint_common(1 << 12, 0, 0); + picint_common(1 << 1, 0, 1, NULL); + picint_common(1 << 12, 0, 0, NULL); } } else if (dev->mem[0x20] & 0x01) - picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ dev->ob = temp; } @@ -399,10 +429,14 @@ kbc_scan_kbd_at(atkbc_t *dev) kbc_ibf_process(dev); /* AT mode. */ } else { - // dev->t = dev->mem[0x28]; +#if 0 + dev->t = dev->mem[0x28]; +#endif if (dev->mem[0x2e] != 0x00) { - // if (!(dev->t & 0x02)) - // return; +#if 0 + if (!(dev->t & 0x02)) + return; +#endif dev->mem[0x2e] = 0x00; } dev->p2 &= 0xbf; @@ -422,7 +456,8 @@ kbc_scan_kbd_at(atkbc_t *dev) } } -static void write_p2(atkbc_t *dev, uint8_t val); +static void +write_p2(atkbc_t *dev, uint8_t val); static void kbc_at_poll_at(atkbc_t *dev) @@ -438,7 +473,7 @@ kbc_at_poll_at(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; - /* FALLTHROUGH */ + fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -466,11 +501,12 @@ kbc_at_poll_at(atkbc_t *dev) /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); - // dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto at_main_ibf; - break; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { @@ -559,7 +595,7 @@ kbc_at_poll_ps2(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; - /* FALLTHROUGH */ + fallthrough; case STATE_MAIN_IBF: default: ps2_main_ibf: @@ -608,11 +644,12 @@ kbc_at_poll_ps2(atkbc_t *dev) /* Keyboard controller command want to output a single byte. */ kbc_at_log("ATkbc: %02X coming from channel %i with high status %02X\n", dev->val, dev->channel, dev->stat_hi); kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi); - // dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#if 0 + dev->state = (dev->pending == 2) ? STATE_KBC_AMI_OUT : STATE_MAIN_IBF; +#endif dev->state = STATE_MAIN_IBF; dev->pending = 0; goto ps2_main_ibf; - break; case STATE_KBC_OUT: /* Keyboard controller command want to output multiple bytes. */ if (dev->status & STAT_IFULL) { @@ -662,10 +699,18 @@ kbc_at_poll(void *priv) { atkbc_t *dev = (atkbc_t *) priv; - timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); + timer_advance_u64(&dev->kbc_poll_timer, (100ULL * TIMER_USEC)); /* TODO: Implement the password security state. */ kbc_at_do_poll(dev); +} + +static void +kbc_at_dev_poll(void *priv) +{ + atkbc_t *dev = (atkbc_t *) priv; + + timer_advance_u64(&dev->kbc_dev_poll_timer, (100ULL * TIMER_USEC)); if ((kbc_at_ports[0] != NULL) && (kbc_at_ports[0]->priv != NULL)) kbc_at_ports[0]->poll(kbc_at_ports[0]->priv); @@ -686,10 +731,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* PS/2: Handle IRQ's. */ if (dev->misc_flags & FLAG_PS2) { /* IRQ 12 */ - picint_common(1 << 12, 0, val & 0x20); + picint_common(1 << 12, 0, val & 0x20, NULL); /* IRQ 1 */ - picint_common(1 << 1, 0, val & 0x10); + picint_common(1 << 1, 0, val & 0x10, NULL); } #endif @@ -703,7 +748,7 @@ write_p2(atkbc_t *dev, uint8_t val) /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if ((old ^ val) & 0x01) { /*Reset*/ + if (!cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); @@ -720,12 +765,40 @@ write_p2(atkbc_t *dev, uint8_t val) flushmmucache(); if (kbc_ven == KBC_VEN_ALI) smbase = 0x00030000; + /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L + and can find out what they actually did to make it boot from FFFFF0 + correctly despite A20 being gated when the CPU is reset, this will + have to do. */ + else if (kbc_ven == KBC_VEN_SIEMENS) + is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } } /* Do this here to avoid an infinite reset loop. */ dev->p2 = val; + + if (cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + if (!(val & 0x01)) { /* Pin 0 selected. */ + /* Pin 0 selected. */ + pclog("write_p2(): Pulse reset!\n"); + dma_reset(); + dma_set_at(1); + + device_reset_all(DEVICE_ALL); + + cpu_alt_reset = 0; + + pci_reset(); + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); + } + } } static void @@ -839,6 +912,9 @@ write64_generic(void *priv, uint8_t val) } break; + /* TODO: Make this command do nothing on the Regional HT6542, + or else, Efflixi's Award OPTi 495 BIOS gets a stuck key + in Norton Commander 3.0. */ case 0xaf: /* read keyboard version */ kbc_at_log("ATkbc: read keyboard version\n"); kbc_delay_to_ob(dev, kbc_award_revision, 0, 0x00); @@ -878,7 +954,7 @@ write64_generic(void *priv, uint8_t val) Bit 6: Mostly, display: 0 = CGA, 1 = MDA, inverted on Xi8088 and Acer KBC's; Intel AMI MegaKey KB-5: Used for green features, SMM handler expects it to be set; IBM PS/1 Model 2011: 0 = current FDD is 3.5", 1 = current FDD is 5.25"; - Comapq: 0 = Compaq dual-scan display, 1 = non-Compaq display. + Compaq: 0 = Compaq dual-scan display, 1 = non-Compaq display. Bit 5: Mostly, manufacturing jumper: 0 = installed (infinite loop at POST), 1 = not installed; NCR: power-on default speed: 0 = high, 1 = low; Compaq: System board DIP switch 5: 0 = ON, 1 = OFF. @@ -947,6 +1023,8 @@ write64_generic(void *priv, uint8_t val) } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) /* (B0 or F0) | (0x08 or 0x0c) */ kbc_delay_to_ob(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00); + else if (kbc_ven == KBC_VEN_COMPAQ) + kbc_delay_to_ob(dev, dev->p1 | (hasfpu ? 0x00 : 0x04), 0, 0x00); else /* (B0 or F0) | (0x04 or 0x44) */ kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00); @@ -990,6 +1068,9 @@ write64_generic(void *priv, uint8_t val) kbc_at_log("ATkbc: pulse %01X\n", val & 0x0f); pulse_output(dev, val & 0x0f); return 0; + + default: + break; } kbc_at_log("ATkbc: bad command %02X\n", val); @@ -1004,7 +1085,7 @@ write60_ami(void *priv, uint8_t val) switch (dev->command) { /* 0x40 - 0x5F are aliases for 0x60-0x7F */ case 0x40 ... 0x5f: - kbc_at_log("ATkbc: AMI - alias write to %08X\n", dev->command); + kbc_at_log("ATkbc: AMI - alias write to %02X\n", dev->command & 0x1f); dev->mem[(dev->command & 0x1f) + 0x20] = val; if (dev->command == 0x60) write_cmd(dev, val); @@ -1041,6 +1122,9 @@ write60_ami(void *priv, uint8_t val) kbc_at_do_poll = kbc_at_poll_at; } return 0; + + default: + break; } return 1; @@ -1140,7 +1224,7 @@ write64_ami(void *priv, uint8_t val) break; case 0xaf: /* set extended controller RAM */ - if (kbc_ven != KBC_VEN_ALI) { + if ((kbc_ven != KBC_VEN_SIEMENS) && (kbc_ven != KBC_VEN_ALI)) { kbc_at_log("ATkbc: set extended controller RAM\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; @@ -1244,20 +1328,59 @@ write64_ami(void *priv, uint8_t val) case 0xef: /* ??? - sent by AMI486 */ kbc_at_log("ATkbc: ??? - sent by AMI486\n"); return 0; + + default: + break; } return write64_generic(dev, val); } static uint8_t -write60_quadtel(void *priv, uint8_t val) +write64_siemens(void *priv, uint8_t val) { - atkbc_t *dev = (atkbc_t *) priv; + atkbc_t *dev = (atkbc_t *) priv; + + switch (val) { + case 0x92: /*Siemens Award - 92 sent by PCD-2L BIOS*/ + kbc_at_log("Siemens Award - 92 sent by PCD-2L BIOS\n"); + return 0; + + case 0x94: /*Siemens Award - 94 sent by PCD-2L BIOS*/ + kbc_at_log("Siemens Award - 94 sent by PCD-2L BIOS\n"); + return 0; + + case 0x9a: /*Siemens Award - 9A sent by PCD-2L BIOS*/ + kbc_at_log("Siemens Award - 9A sent by PCD-2L BIOS\n"); + return 0; + + case 0x9c: /*Siemens Award - 9C sent by PCD-2L BIOS*/ + kbc_at_log("Siemens Award - 9C sent by PCD-2L BIOS\n"); + return 0; + + case 0xa9: /*Siemens Award - A9 sent by PCD-2L BIOS*/ + kbc_at_log("Siemens Award - A9 sent by PCD-2L BIOS\n"); + return 0; + + default: + break; + } + + return write64_ami(dev, val); +} + +static uint8_t +write60_quadtel(void *priv, UNUSED(uint8_t val)) +{ + const atkbc_t *dev = (atkbc_t *) priv; switch (dev->command) { case 0xcf: /*??? - sent by MegaPC BIOS*/ kbc_at_log("ATkbc: ??? - sent by MegaPC BIOS\n"); return 0; + + default: + break; } return 1; @@ -1280,6 +1403,9 @@ write64_olivetti(void *priv, uint8_t val) kbc_delay_to_ob(dev, (0x0c | (is386 ? 0x00 : 0x80)) & 0xdf, 0, 0x00); dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); return 0; + + default: + break; } return write64_generic(dev, val); @@ -1300,6 +1426,9 @@ write64_quadtel(void *priv, uint8_t val) dev->wantdata = 1; dev->state = STATE_KBC_PARAM; return 0; + + default: + break; } return write64_generic(dev, val); @@ -1308,13 +1437,16 @@ write64_quadtel(void *priv, uint8_t val) static uint8_t write60_toshiba(void *priv, uint8_t val) { - atkbc_t *dev = (atkbc_t *) priv; + const atkbc_t *dev = (atkbc_t *) priv; switch (dev->command) { case 0xb6: /* T3100e - set color/mono switch */ kbc_at_log("ATkbc: T3100e - set color/mono switch\n"); t3100e_mono_set(val); return 0; + + default: + break; } return 1; @@ -1405,6 +1537,9 @@ write64_toshiba(void *priv, uint8_t val) dev->p1 = (t3100e_mono_get() & 1) ? 0xff : 0xbf; kbc_delay_to_ob(dev, dev->p1, 0, 0x00); return 0; + + default: + break; } return write64_generic(dev, val); @@ -1451,7 +1586,8 @@ kbc_at_process_cmd(void *priv) /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0x4b); - picintc(0x1002); + picintc(0x1000); + picintc(0x0002); } dev->status = (dev->status & 0x0f) | 0x60; @@ -1470,7 +1606,8 @@ kbc_at_process_cmd(void *priv) /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0xcf); - picintc(0x0002); + picintclevel(0x0002, &dev->irq_state); + dev->irq_state = 0; } dev->status = (dev->status & 0x0f) | 0x60; @@ -1650,6 +1787,9 @@ kbc_at_process_cmd(void *priv) if (dev->ib == 0xbb) break; + if (strstr(machine_get_internal_name(), "pb") != NULL) + cpu_override_dynarec = 1; + if (dev->misc_flags & FLAG_PS2) { set_enable_aux(dev, 1); if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) { @@ -1682,13 +1822,15 @@ static void kbc_at_write(uint16_t port, uint8_t val, void *priv) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t fast_a20 = (kbc_ven != KBC_VEN_SIEMENS); kbc_at_log("ATkbc: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val); switch (port) { case 0x60: dev->status &= ~STAT_CD; - if (dev->wantdata && (dev->command == 0xd1)) { + if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { kbc_at_log("ATkbc: write P2\n"); #if 0 @@ -1718,7 +1860,7 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) case 0x64: dev->status |= STAT_CD; - if (val == 0xd1) { + if (fast_a20 && (val == 0xd1)) { kbc_at_log("ATkbc: write P2\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; @@ -1726,6 +1868,9 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) return; } break; + + default: + break; } dev->ib = val; @@ -1748,7 +1893,9 @@ kbc_at_read(uint16_t port, void *priv) /* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit. This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) - picintc(1 << 1); + picintclevel(1 << 1, &dev->irq_state); + if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) + cpu_override_dynarec = 0; break; case 0x64: @@ -1797,8 +1944,13 @@ kbc_at_reset(void *priv) if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { dev->misc_flags |= FLAG_PS2; kbc_at_do_poll = kbc_at_poll_ps2; - } else + picintc(0x1000); + picintc(0x0002); + } else { kbc_at_do_poll = kbc_at_poll_at; + picintclevel(0x0002, &dev->irq_state); + dev->irq_state = 0; + } dev->misc_flags |= FLAG_CACHE; @@ -1820,10 +1972,9 @@ kbc_at_close(void *priv) atkbc_t *dev = (atkbc_t *) priv; int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1; - kbc_at_reset(dev); - /* Stop timers. */ - timer_disable(&dev->send_delay_timer); + timer_disable(&dev->kbc_dev_poll_timer); + timer_disable(&dev->kbc_poll_timer); for (int i = 0; i < max_ports; i++) { if (kbc_at_ports[i] != NULL) { @@ -1855,9 +2006,11 @@ kbc_at_init(const device_t *info) io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev); - timer_add(&dev->send_delay_timer, kbc_at_poll, dev, 1); + timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); timer_add(&dev->pulse_cb, pulse_poll, dev, 0); + timer_add(&dev->kbc_dev_poll_timer, kbc_at_dev_poll, dev, 1); + dev->write60_ven = NULL; dev->write64_ven = NULL; @@ -1865,10 +2018,18 @@ kbc_at_init(const device_t *info) kbc_award_revision = 0x42; switch (dev->flags & KBC_VEN_MASK) { + case KBC_VEN_SIEMENS: + kbc_ami_revision = '8'; + kbc_award_revision = 0x42; + dev->write60_ven = write60_ami; + dev->write64_ven = write64_siemens; + break; + case KBC_VEN_ACER: case KBC_VEN_GENERIC: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: + case KBC_VEN_COMPAQ: dev->write64_ven = write64_generic; break; @@ -1922,6 +2083,9 @@ kbc_at_init(const device_t *info) dev->write60_ven = write60_toshiba; dev->write64_ven = write64_toshiba; break; + + default: + break; } max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1; @@ -1955,6 +2119,20 @@ const device_t keyboard_at_device = { .config = NULL }; +const device_t keyboard_at_siemens_device = { + .name = "PC/AT Keyboard", + .internal_name = "keyboard_at", + .flags = DEVICE_KBC, + .local = KBC_TYPE_ISA | KBC_VEN_SIEMENS, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_at_ami_device = { .name = "PC/AT Keyboard (AMI)", .internal_name = "keyboard_at_ami", @@ -2025,6 +2203,20 @@ const device_t keyboard_at_ncr_device = { .config = NULL }; +const device_t keyboard_at_compaq_device = { + .name = "PC/AT Keyboard (Compaq)", + .internal_name = "keyboard_at_compaq", + .flags = DEVICE_KBC, + .local = KBC_TYPE_ISA | KBC_VEN_COMPAQ, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2", diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 2715f94fa8..c1041e6e14 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -38,6 +38,7 @@ #include <86box/snd_speaker.h> #include <86box/video.h> #include <86box/keyboard.h> +#include <86box/plat_fallthrough.h> #ifdef ENABLE_KBC_AT_DEV_LOG int kbc_at_dev_do_log = ENABLE_KBC_AT_DEV_LOG; @@ -118,12 +119,13 @@ kbc_at_dev_poll(void *priv) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) { + if (!dev->ignore && *dev->scan && (dev->port->out_new == -1) && + (dev->queue_start != dev->queue_end)) { kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask; } - if (!(*dev->scan) || dev->port->wantcmd) + if (dev->ignore || !(*dev->scan) || dev->port->wantcmd) dev->state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: @@ -135,7 +137,7 @@ kbc_at_dev_poll(void *priv) dev->port->wantcmd = 0; break; } - /* FALLTHROUGH */ + fallthrough; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then return to main loop #2. */ if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) { @@ -169,6 +171,8 @@ kbc_at_dev_poll(void *priv) if (dev->cmd_queue_start == dev->cmd_queue_end) dev->state = DEV_STATE_EXECUTE_BAT; break; + default: + break; } } @@ -196,8 +200,7 @@ kbc_at_dev_init(uint8_t inst) { atkbc_dev_t *dev; - dev = (atkbc_dev_t *) malloc(sizeof(atkbc_dev_t)); - memset(dev, 0x00, sizeof(atkbc_dev_t)); + dev = (atkbc_dev_t *) calloc(1, sizeof(atkbc_dev_t)); dev->port = kbc_at_ports[inst]; diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 9d15db79b1..5f9986d7bb 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -29,6 +29,25 @@ #include "cpu.h" int keyboard_scan; + +#ifdef _WIN32 +/* Windows: F8+F12 */ +uint16_t key_prefix_1_1 = 0x042; /* F8 */ +uint16_t key_prefix_1_2 = 0x000; /* Invalid */ +uint16_t key_prefix_2_1 = 0x000; /* Invalid */ +uint16_t key_prefix_2_2 = 0x000; /* Invalid */ +uint16_t key_uncapture_1 = 0x058; /* F12 */ +uint16_t key_uncapture_2 = 0x000; /* Invalid */ +#else +/* WxWidgets cannot do two regular keys.. CTRL+END */ +uint16_t key_prefix_1_1 = 0x01d; /* Left Ctrl */ +uint16_t key_prefix_1_2 = 0x11d; /* Right Ctrl */ +uint16_t key_prefix_2_1 = 0x000; /* Invalid */ +uint16_t key_prefix_2_2 = 0x000; /* Invalid */ +uint16_t key_uncapture_1 = 0x04f; /* Numpad End */ +uint16_t key_uncapture_2 = 0x14f; /* End */ +#endif + void (*keyboard_send)(uint16_t val); static int recv_key[512]; /* keyboard input buffer */ @@ -87,8 +106,8 @@ fake_shift_needed(uint16_t scan) void key_process(uint16_t scan, int down) { - scancode *codes = scan_table; - int c; + const scancode *codes = scan_table; + int c; if (!codes) return; @@ -167,6 +186,15 @@ keyboard_input(int down, uint16_t scan) case 0x138: /* Right Alt */ shift |= 0x40; break; + case 0x15b: /* Left Windows */ + shift |= 0x08; + break; + case 0x15c: /* Right Windows */ + shift |= 0x80; + break; + + default: + break; } } else { switch (scan & 0x1ff) { @@ -188,6 +216,12 @@ keyboard_input(int down, uint16_t scan) case 0x138: /* Right Alt */ shift &= ~0x40; break; + case 0x15b: /* Left Windows */ + shift &= ~0x08; + break; + case 0x15c: /* Right Windows */ + shift &= ~0x80; + break; case 0x03a: /* Caps Lock */ caps_lock ^= 1; break; @@ -197,13 +231,18 @@ keyboard_input(int down, uint16_t scan) case 0x046: scroll_lock ^= 1; break; + + default: + break; } } } /* NOTE: Shouldn't this be some sort of bit shift? An array of 8 unsigned 64-bit integers should be enough. */ - /* recv_key[scan >> 6] |= ((uint64_t) down << ((uint64_t) scan & 0x3fLL)); */ +#if 0 + recv_key[scan >> 6] |= ((uint64_t) down << ((uint64_t) scan & 0x3fLL)); +#endif /* pclog("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */ recv_key[scan & 0x1ff] = down; @@ -214,7 +253,7 @@ keyboard_input(int down, uint16_t scan) static uint8_t keyboard_do_break(uint16_t scan) { - scancode *codes = scan_table; + const scancode *codes = scan_table; /* TODO: The keyboard controller needs to report the AT flag to us here. */ if (is286 && ((keyboard_mode & 3) == 3)) { @@ -258,7 +297,7 @@ keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl) { - scancode *codes = scan_table; + const scancode *codes = scan_table; int i; @@ -312,7 +351,7 @@ keyboard_isfsenter(void) } int -keyboard_isfsenter_down(void) +keyboard_isfsenter_up(void) { return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x049] && !recv_key[0x149]); } @@ -325,20 +364,20 @@ keyboard_isfsexit(void) } int -keyboard_isfsexit_down(void) +keyboard_isfsexit_up(void) { return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x051] && !recv_key[0x151]); } -/* Do we have F8-F12 in the keyboard buffer? */ +/* Do we have the mouse uncapture combination in the keyboard buffer? */ int keyboard_ismsexit(void) { -#ifdef _WIN32 - /* Windows: F8+F12 */ - return (recv_key[0x042] && recv_key[0x058]); -#else - /* WxWidgets cannot do two regular keys.. CTRL+END */ - return ((recv_key[0x01D] || recv_key[0x11D]) && (recv_key[0x04F] || recv_key[0x14F])); -#endif + if ((key_prefix_2_1 != 0x000) || (key_prefix_2_2 != 0x000)) + return ((recv_key[key_prefix_1_1] || recv_key[key_prefix_1_2]) && + (recv_key[key_prefix_2_1] || recv_key[key_prefix_2_2]) && + (recv_key[key_uncapture_1] || recv_key[key_uncapture_2])); + else + return ((recv_key[key_prefix_1_1] || recv_key[key_prefix_1_2]) && + (recv_key[key_uncapture_1] || recv_key[key_uncapture_2])); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 516303137d..7accb2fd6c 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -8,9 +8,11 @@ * * Implementation of PS/2 series Mouse devices. * + * Authors: Miran Grca, + * Fred N. van Kempen, * - * - * Authors: Fred N. van Kempen, + * Copyright 2016-2023 Miran Grca. + * Copyright 2017-2023 Fred N. van Kempen. */ #include #include @@ -30,6 +32,8 @@ #define FIFO_SIZE 16 +#define BAT_COUNT 1000 + enum { KBD_84_KEY = 0, KBD_101_KEY, @@ -67,12 +71,14 @@ uint8_t keyboard_set3_all_break; /* Global keyboard mode: Bits 0 - 1 = scan code set. */ -uint8_t keyboard_mode = 0x02; +uint8_t keyboard_mode = 0x02; static atkbc_dev_t *SavedKbd = NULL; static uint8_t inv_cmd_response = 0xfa; +static uint16_t bat_counter = 0; + static const scancode scancode_set1[512] = { // clang-format off { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ @@ -491,8 +497,8 @@ static void keyboard_at_set_scancode_set(void) { switch (keyboard_mode) { - case 0x01: default: + case 0x01: keyboard_set_table(scancode_set1); break; @@ -517,10 +523,12 @@ static void add_data_kbd(uint16_t val) { atkbc_dev_t *dev = SavedKbd; - uint8_t fake_shift[4]; + uint8_t fake_shift[4] = { 0 }; uint8_t num_lock = 0; uint8_t shift_states = 0; + dev->ignore = 1; + keyboard_get_states(NULL, &num_lock, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; @@ -535,12 +543,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -556,12 +566,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -577,12 +589,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 B6\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xb6; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59; @@ -608,12 +622,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -630,12 +646,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -650,12 +668,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 36\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x36; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x59; add_data_vals(dev, fake_shift, 2); @@ -674,6 +694,8 @@ add_data_kbd(uint16_t val) kbc_at_dev_queue_add(dev, val, 1); break; } + + dev->ignore = 0; } void @@ -702,11 +724,16 @@ keyboard_at_bat(void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; - keyboard_at_set_defaults(dev); + if (bat_counter == 0x0000) { + keyboard_at_set_defaults(dev); - keyboard_scan = 1; + keyboard_scan = 1; - kbc_at_dev_queue_add(dev, 0xaa, 0); + kbc_at_dev_queue_add(dev, 0xaa, 0); + } else { + bat_counter--; + dev->state = DEV_STATE_EXECUTE_BAT; + } } static void @@ -849,7 +876,8 @@ keyboard_at_write(void *priv) case 0xf5: /* set defaults and disable keyboard */ case 0xf6: /* set defaults */ - keyboard_at_log("%s: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); + keyboard_at_log("%s: set defaults%s\n", + dev->name, (val == 0xf6) ? "" : " and disable keyboard"); keyboard_scan = !(val & 0x01); keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n", dev->name, val, keyboard_scan); @@ -924,6 +952,7 @@ keyboard_at_write(void *priv) case 0xff: /* reset */ kbc_at_dev_reset(dev, 1); + bat_counter = 1000; break; default: @@ -963,8 +992,10 @@ keyboard_at_init(const device_t *info) dev->fifo_mask = FIFO_SIZE - 1; - if (dev->port != NULL) + if (dev->port != NULL) { kbc_at_dev_reset(dev, 0); + bat_counter = 0x0000; + } keyboard_send = add_data_kbd; SavedKbd = dev; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index bdc1cc51bb..f65a6dffc7 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -54,28 +54,35 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -// Keyboard Types -#define KBD_TYPE_PC81 0 -#define KBD_TYPE_PC82 1 -#define KBD_TYPE_XT82 2 -#define KBD_TYPE_XT86 3 -#define KBD_TYPE_COMPAQ 4 -#define KBD_TYPE_TANDY 5 -#define KBD_TYPE_TOSHIBA 6 -#define KBD_TYPE_VTECH 7 -#define KBD_TYPE_OLIVETTI 8 -#define KBD_TYPE_ZENITH 9 -#define KBD_TYPE_PRAVETZ 10 -#define KBD_TYPE_XTCLONE 11 - -typedef struct { +/* Keyboard Types */ +enum { + KBD_TYPE_PC81 = 0, + KBD_TYPE_PC82, + KBD_TYPE_XT82, + KBD_TYPE_XT86, + KBD_TYPE_COMPAQ, + KBD_TYPE_TANDY, + KBD_TYPE_TOSHIBA, + KBD_TYPE_VTECH, + KBD_TYPE_OLIVETTI, + KBD_TYPE_ZENITH, + KBD_TYPE_PRAVETZ, + KBD_TYPE_HYUNDAI, + KBD_TYPE_XTCLONE +}; + +typedef struct xtkbd_t { int want_irq; int blocked; int tandy; - uint8_t pa, pb, pd, clock; + uint8_t pa; + uint8_t pb; + uint8_t pd; + uint8_t clock; uint8_t key_waiting; - uint8_t type, pravetz_flags; + uint8_t type; + uint8_t pravetz_flags; pc_timer_t send_delay_timer; } xtkbd_t; @@ -454,6 +461,9 @@ kbd_adddata(uint16_t val) case 0x54: /* SysRQ => toggle window */ t1000_syskey(0x00, 0x00, 0x08); break; + + default: + break; } } else t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ @@ -523,7 +533,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) switch (port) { case 0x61: /* Keyboard Control Register (aka Port B) */ - if (!(val & 0x80)) { + if (!(val & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) { new_clock = !!(val & 0x40); if (!kbd->clock && new_clock) { key_queue_start = key_queue_end = 0; @@ -533,14 +543,14 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } } kbd->pb = val; - if (!(kbd->pb & 0x80)) + if (!(kbd->pb & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) kbd->clock = !!(kbd->pb & 0x40); ppi.pb = val; timer_process(); - if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) && - (cassette != NULL)) + if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) && (cassette != NULL)) pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0); speaker_update(); @@ -578,23 +588,33 @@ kbd_write(uint16_t port, uint8_t val, void *priv) kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; } break; + + default: + break; } } static uint8_t kbd_read(uint16_t port, void *priv) { - xtkbd_t *kbd = (xtkbd_t *) priv; - uint8_t ret = 0xff; + const xtkbd_t *kbd = (xtkbd_t *) priv; + uint8_t ret = 0xff; switch (port) { case 0x60: /* Keyboard Data Register (aka Port A) */ - if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || - (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_ZENITH))) { - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_PRAVETZ)) + if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || + (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || + (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI))) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_HYUNDAI)) ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00); else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86)) - ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ + /* According to Ruud on the PCem forum, this is supposed to + return 0xFF on the XT. */ + ret = 0xff; else if (kbd->type == KBD_TYPE_ZENITH) { /* Zenith Data Systems Z-151 * SW1 switch settings: @@ -623,7 +643,8 @@ kbd_read(uint16_t port, void *priv) break; case 0x62: /* Switch Register (aka Port C) */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) { if (kbd->pb & 0x04) /* PB2 */ switch (mem_size + isa_mem_size) { case 64: @@ -638,8 +659,8 @@ kbd_read(uint16_t port, void *priv) } else ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4; - } else if (kbd->type == KBD_TYPE_OLIVETTI - || kbd->type == KBD_TYPE_ZENITH) { + } else if ((kbd->type == KBD_TYPE_OLIVETTI) || + (kbd->type == KBD_TYPE_ZENITH)) { /* Olivetti M19 or Zenith Data Systems Z-151 */ if (kbd->pb & 0x04) /* PB2 */ ret = kbd->pd & 0xbf; @@ -652,7 +673,7 @@ kbd_read(uint16_t port, void *priv) /* LaserXT = Always 512k RAM; LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) - if (kbd->type == KBD_TYPE_TOSHIBA) + if (kbd->type == KBD_TYPE_VTECH) ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00); else #endif @@ -663,7 +684,8 @@ kbd_read(uint16_t port, void *priv) /* This is needed to avoid error 131 (cassette error). This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) { if (cassette == NULL) ret |= (ppispeakon ? 0x10 : 0); else @@ -677,7 +699,7 @@ kbd_read(uint16_t port, void *priv) case 0x63: /* Keyboard Configuration Register (aka Port D) */ if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || - (kbd->type == KBD_TYPE_TOSHIBA)) + (kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_HYUNDAI)) ret = kbd->pd; break; @@ -686,6 +708,9 @@ kbd_read(uint16_t port, void *priv) ret = kbd->pravetz_flags; kbd_log("XTkbd: Port %02X in : %02X\n", port, ret); break; + + default: + break; } return ret; @@ -740,8 +765,7 @@ kbd_init(const device_t *info) (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || (kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) || - (kbd->type == KBD_TYPE_OLIVETTI)) { - + (kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI)) { /* DIP switch readout: bit set = OFF, clear = ON. */ if (kbd->type == KBD_TYPE_OLIVETTI) /* Olivetti M19 @@ -760,7 +784,8 @@ kbd_init(const device_t *info) /* Switches 3, 4 - memory size. */ if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || - (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA)) { + (kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_TOSHIBA)) { switch (mem_size) { case 256: kbd->pd |= 0x00; @@ -1055,6 +1080,20 @@ const device_t keyboard_xt_zenith_device = { .config = NULL }; +const device_t keyboard_xt_hyundai_device = { + .name = "Hyundai XT Keyboard", + .internal_name = "keyboard_x_hyundai", + .flags = 0, + .local = KBD_TYPE_HYUNDAI, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_xtclone_device = { .name = "XT (Clone) Keyboard", .internal_name = "keyboard_xtclone", diff --git a/src/device/mouse.c b/src/device/mouse.c index 9409fa3cb9..da4ed1c04e 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -19,7 +19,9 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2017-2018 Fred N. van Kempen. */ +#include #include +#include #include #include #include @@ -30,23 +32,25 @@ #include <86box/timer.h> #include <86box/gdbstub.h> #include <86box/mouse.h> +#include <86box/video.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct mouse_t { const device_t *device; } mouse_t; int mouse_type = 0; -int mouse_x; -int mouse_y; -int mouse_z; -int mouse_buttons; -int mouse_mode; +int mouse_input_mode; +int mouse_timed = 1; int mouse_tablet_in_proximity = 0; int tablet_tool_type = 1; /* 0 = Puck/Cursor, 1 = Pen */ double mouse_x_abs; double mouse_y_abs; +double mouse_sensitivity = 1.0; + pc_timer_t mouse_timer; /* mouse event timer */ static const device_t mouse_none_device = { @@ -83,23 +87,34 @@ static mouse_t mouse_devices[] = { { &mouse_internal_device }, { &mouse_logibus_device }, { &mouse_msinport_device }, -#if 0 +#ifdef USE_GENIBUS { &mouse_genibus_device }, #endif { &mouse_mssystems_device }, { &mouse_msserial_device }, { &mouse_ltserial_device }, { &mouse_ps2_device }, +#ifdef USE_WACOM { &mouse_wacom_device }, { &mouse_wacom_artpad_device }, +#endif { NULL } // clang-format on }; +static _Atomic double mouse_x; +static _Atomic double mouse_y; +static atomic_int mouse_z; +static atomic_int mouse_buttons; + +static int mouse_delta_b; +static int mouse_old_b; + static const device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; -static int (*mouse_dev_poll)(int x, int y, int z, int b, void *priv); +static int mouse_raw; +static int (*mouse_dev_poll)(void *priv); static void (*mouse_poll_ex)(void) = NULL; static double sample_rate = 200.0; @@ -122,84 +137,386 @@ mouse_log(const char *fmt, ...) # define mouse_log(fmt, ...) #endif -/* Initialize the mouse module. */ void -mouse_init(void) +mouse_clear_x(void) { - /* Initialize local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; + mouse_x = 0.0; +} - mouse_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; +void +mouse_clear_y(void) +{ + mouse_y = 0.0; } void -mouse_close(void) +mouse_clear_coords(void) { - if (mouse_curr == NULL) - return; + mouse_clear_x(); + mouse_clear_y(); - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; + mouse_z = 0; +} - timer_stop(&mouse_timer); +void +mouse_clear_buttons(void) +{ + mouse_buttons = 0x00; + mouse_old_b = 0x00; + + mouse_delta_b = 0x00; +} + +static double +mouse_scale_coord_x(double x, int mul) +{ + double ratio = 1.0; + + if (!mouse_raw) + ratio = ((double) monitors[0].mon_unscaled_size_x) / monitors[0].mon_res_x; + + if (mul) + x *= ratio; + else + x /= ratio; + + return x; +} + +static double +mouse_scale_coord_y(double y, int mul) +{ + double ratio = 1.0; + + if (!mouse_raw) + ratio = ((double) monitors[0].mon_efscrnsz_y) / monitors[0].mon_res_y; + + if (mul) + y *= ratio; + else + y /= ratio; + + return y; +} + +void +mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs) +{ + double real_x = atomic_load(&mouse_x); + double smax_x; + double rsmin_x; + double smin_x; + int ds_x; + int scaled_x; + + rsmin_x = mouse_scale_coord_x(min, 0); + if (abs) { + smax_x = mouse_scale_coord_x(max, 0) + ABS(rsmin_x); + max += ABSD(min); + real_x += rsmin_x; + smin_x = 0; + } else { + smax_x = mouse_scale_coord_x(max, 0); + smin_x = rsmin_x; + } + + smax_x = floor(smax_x); + smin_x = ceil(smin_x); + + /* Default the X overflow to 1. */ + if (o_x != NULL) + *o_x = 1; + + ds_x = mouse_scale_coord_x(real_x, 1); + + if (ds_x >= 0.0) + scaled_x = (int) floor(mouse_scale_coord_x(real_x, 1)); + else + scaled_x = (int) ceil(mouse_scale_coord_x(real_x, 1)); + + if (real_x > smax_x) { + if (abs) { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + } else { + *delta_x = max; + real_x -= smax_x; + } + } else if (real_x < smin_x) { + if (abs) { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + } else { + *delta_x = min; + real_x += ABSD(smin_x); + } + } else { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + if (o_x != NULL) + *o_x = 0; + } + + if (abs) + real_x -= rsmin_x; + + atomic_store(&mouse_x, real_x); +} + +/* It appears all host platforms give us y in the Microsoft format + (positive to the south), so for all non-Microsoft report formsts, + we have to invert that. */ +void +mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs) +{ + double real_y = atomic_load(&mouse_y); + double smax_y; + double rsmin_y; + double smin_y; + int ds_y; + int scaled_y; + + if (invert) + real_y = -real_y; + + rsmin_y = mouse_scale_coord_y(min, 0); + if (abs) { + smax_y = mouse_scale_coord_y(max, 0) + ABS(rsmin_y); + max += ABSD(min); + real_y += rsmin_y; + smin_y = 0; + } else { + smax_y = mouse_scale_coord_y(max, 0); + smin_y = rsmin_y; + } + + smax_y = floor(smax_y); + smin_y = ceil(smin_y); + + /* Default Y overflow to 1. */ + if (o_y != NULL) + *o_y = 1; + + ds_y = mouse_scale_coord_x(real_y, 1); + + if (ds_y >= 0.0) + scaled_y = (int) floor(mouse_scale_coord_x(real_y, 1)); + else + scaled_y = (int) ceil(mouse_scale_coord_x(real_y, 1)); + + if (real_y > smax_y) { + if (abs) { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + } else { + *delta_y = max; + real_y -= smax_y; + } + } else if (real_y < smin_y) { + if (abs) { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + } else { + *delta_y = min; + real_y += ABSD(smin_y); + } + } else { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + if (o_y != NULL) + *o_y = 0; + } + + if (abs) + real_y -= rsmin_y; + + if (invert) + real_y = -real_y; + + atomic_store(&mouse_y, real_y); +} + +/* It appears all host platforms give us y in the Microsoft format + (positive to the south), so for all non-Microsoft report formsts, + we have to invenrt that. */ +void +mouse_subtract_coords(int *delta_x, int *delta_y, int *o_x, int *o_y, + int min, int max, int invert, int abs) +{ + mouse_subtract_x(delta_x, o_x, min, max, abs); + mouse_subtract_y(delta_y, o_y, min, max, invert, abs); +} + +int +mouse_wheel_moved(void) +{ + int ret = !!(atomic_load(&mouse_z)); + + return ret; +} + +int +mouse_moved(void) +{ + int moved_x = !!((int) floor(ABSD(mouse_scale_coord_x(atomic_load(&mouse_x), 1)))); + int moved_y = !!((int) floor(ABSD(mouse_scale_coord_y(atomic_load(&mouse_y), 1)))); + + /* Convert them to integer so we treat < 1.0 and > -1.0 as 0. */ + int ret = (moved_x || moved_y); + + return ret; +} + +int +mouse_state_changed(void) +{ + int b; + int b_mask = (1 << mouse_nbut) - 1; + int wheel = (mouse_nbut >= 4); + int ret; + + b = atomic_load(&mouse_buttons); + mouse_delta_b = (b ^ mouse_old_b); + mouse_old_b = b; + + ret = mouse_moved() || ((atomic_load(&mouse_z) != 0) && wheel) || (mouse_delta_b & b_mask); + + return ret; +} + +int +mouse_mbut_changed(void) +{ + return !!(mouse_delta_b & 0x04); } static void -mouse_timer_poll(void *priv) +mouse_timer_poll(UNUSED(void *priv)) { - /* Poll at 255 Hz, maximum supported by PS/2 mic. */ + /* Poll at the specified sample rate. */ timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ - if (gdbstub_step == GDBSTUB_EXEC) + if (gdbstub_step == GDBSTUB_EXEC) { #endif - mouse_process(); + if (mouse_timed) + mouse_process(); +#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ + } +#endif +} + +static void +atomic_double_add(_Atomic double *var, double val) +{ + double temp = atomic_load(var); + + temp += val; + + atomic_store(var, temp); } void -mouse_set_sample_rate(double new_rate) +mouse_scale_fx(double x) { - timer_stop(&mouse_timer); + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} - sample_rate = new_rate; - timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); +void +mouse_scale_fy(double y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); } void -mouse_reset(void) +mouse_scale_x(int x) { - if (mouse_curr != NULL) - return; /* Mouse already initialized. */ + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} - mouse_log("MOUSE: reset(type=%d, '%s')\n", - mouse_type, mouse_devices[mouse_type].device->name); +void +mouse_scale_y(int y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); +} - /* Clear local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - mouse_mode = 0; +void +mouse_scalef(double x, double y) +{ + mouse_scale_fx(x); + mouse_scale_fy(y); +} - /* If no mouse configured, we're done. */ - if (mouse_type == 0) - return; +void +mouse_scale(int x, int y) +{ + mouse_scale_x(x); + mouse_scale_y(y); +} - timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); +void +mouse_scale_axis(int axis, int val) +{ + if (axis == 1) + mouse_scale_y(val); + else if (axis == 0) + mouse_scale_x(val); +} - /* Poll at 100 Hz, the default of a PS/2 mouse. */ - sample_rate = 100.0; - timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); +void +mouse_set_z(int z) +{ + atomic_fetch_add(&mouse_z, z); +} - mouse_curr = mouse_devices[mouse_type].device; +void +mouse_clear_z(void) +{ + atomic_store(&mouse_z, 0); +} - if (mouse_curr != NULL) - mouse_priv = device_add(mouse_curr); +void +mouse_subtract_z(int *delta_z, int min, int max, int invert) +{ + int z = atomic_load(&mouse_z); + int real_z = invert ? -z : z; + + if (mouse_z > max) { + *delta_z = max; + real_z -= max; + } else if (mouse_z < min) { + *delta_z = min; + real_z += ABS(min); + } else { + *delta_z = real_z; + real_z = 0; + } + + atomic_store(&mouse_z, invert ? -real_z : real_z); +} + +void +mouse_set_buttons_ex(int b) +{ + atomic_store(&mouse_buttons, b); +} + +int +mouse_get_buttons_ex(void) +{ + return atomic_load(&mouse_buttons); +} + +void +mouse_set_sample_rate(double new_rate) +{ + mouse_timed = (new_rate > 0.0); + + timer_stop(&mouse_timer); + + sample_rate = new_rate; + if (mouse_timed) + timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); } /* Callback from the hardware driver. */ @@ -210,9 +527,10 @@ mouse_set_buttons(int buttons) } void -mouse_set_poll_ex(void (*poll_ex)(void)) +mouse_get_abs_coords(double *x_abs, double *y_abs) { - mouse_poll_ex = poll_ex; + *x_abs = mouse_x_abs; + *y_abs = mouse_y_abs; } void @@ -221,24 +539,24 @@ mouse_process(void) if (mouse_curr == NULL) return; - if (mouse_poll_ex) + if ((mouse_input_mode >= 1) && mouse_poll_ex) mouse_poll_ex(); - else - mouse_poll(); - - if ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL)) { + else if ((mouse_input_mode == 0) && ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL))) { if (mouse_curr->poll != NULL) - mouse_curr->poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_x_abs, mouse_y_abs, mouse_priv); + mouse_curr->poll(mouse_priv); else - mouse_dev_poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_priv); - - /* Reset mouse deltas. */ - mouse_x = mouse_y = mouse_z = 0; + mouse_dev_poll(mouse_priv); } } void -mouse_set_poll(int (*func)(int, int, int, int, void *), void *arg) +mouse_set_poll_ex(void (*poll_ex)(void)) +{ + mouse_poll_ex = poll_ex; +} + +void +mouse_set_poll(int (*func)(void *), void *arg) { if (mouse_type != MOUSE_TYPE_INTERNAL) return; @@ -247,13 +565,13 @@ mouse_set_poll(int (*func)(int, int, int, int, void *), void *arg) mouse_priv = arg; } -char * +const char * mouse_get_name(int mouse) { - return ((char *) mouse_devices[mouse].device->name); + return (mouse_devices[mouse].device->name); } -char * +const char * mouse_get_internal_name(int mouse) { return device_get_internal_name(mouse_devices[mouse].device); @@ -300,3 +618,69 @@ mouse_get_ndev(void) { return ((sizeof(mouse_devices) / sizeof(mouse_t)) - 1); } + +void +mouse_set_raw(int raw) +{ + mouse_raw = raw; +} + +void +mouse_reset(void) +{ + if (mouse_curr != NULL) + return; /* Mouse already initialized. */ + + mouse_log("MOUSE: reset(type=%d, '%s')\n", + mouse_type, mouse_devices[mouse_type].device->name); + + /* Clear local data. */ + mouse_clear_coords(); + mouse_clear_buttons(); + mouse_input_mode = 0; + mouse_timed = 1; + + /* If no mouse configured, we're done. */ + if (mouse_type == 0) + return; + + timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); + + /* Poll at 100 Hz, the default of a PS/2 mouse. */ + sample_rate = 100.0; + timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); + + mouse_curr = mouse_devices[mouse_type].device; + + if ((mouse_type > 1) && (mouse_curr != NULL)) + mouse_priv = device_add(mouse_curr); +} + +void +mouse_close(void) +{ + if (mouse_curr == NULL) + return; + + mouse_curr = NULL; + mouse_priv = NULL; + mouse_nbut = 0; + mouse_dev_poll = NULL; + + timer_stop(&mouse_timer); +} + +/* Initialize the mouse module. */ +void +mouse_init(void) +{ + /* Initialize local data. */ + mouse_clear_coords(); + mouse_clear_buttons(); + + mouse_type = MOUSE_TYPE_NONE; + mouse_curr = NULL; + mouse_priv = NULL; + mouse_nbut = 0; + mouse_dev_poll = NULL; +} diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index 5025871d8c..554704c9d9 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -68,6 +68,7 @@ */ #include #include +#include #include #include #include @@ -80,6 +81,8 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/mouse.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> #include <86box/random.h> #define IRQ_MASK ((1 << 5) >> dev->irq) @@ -132,16 +135,24 @@ static const uint8_t periods[4] = { 30, 50, 100, 200 }; /* Our mouse device. */ typedef struct mouse { - uint8_t current_b, control_val, - config_val, sig_val, - command_val, pad; - - int8_t current_x, current_y; - - int base, irq, bn, flags, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, mouse_buttons_last, - toggle_counter, timer_enabled; + uint8_t current_b; + uint8_t control_val; + uint8_t config_val; + uint8_t sig_val; + uint8_t command_val; + uint8_t pad; + + int8_t current_x; + int8_t current_y; + + int base; + int irq; + int bn; + int flags; + int mouse_buttons; + int mouse_buttons_last; + int toggle_counter; + int timer_enabled; double period; pc_timer_t timer; /* mouse event timer */ @@ -215,6 +226,8 @@ lt_read(uint16_t port, void *priv) return (dev->control_val | 0x0F) & ~IRQ_MASK; else return 0xff; + + default: break; } @@ -249,6 +262,7 @@ ms_read(uint16_t port, void *priv) case INP_CTRL_COMMAND: value = dev->control_val; break; + default: bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); } @@ -263,6 +277,9 @@ ms_read(uint16_t port, void *priv) case INP_PORT_CONFIG: bm_log("ERROR: Unsupported read from port 0x%04x\n", port); break; + + default: + break; } bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); @@ -355,6 +372,9 @@ lt_write(uint16_t port, uint8_t val, void *priv) dev->control_val &= ~bit; /* Reset */ } break; + + default: + break; } } @@ -380,6 +400,7 @@ ms_write(uint16_t port, uint8_t val, void *priv) case INP_CTRL_READ_Y: dev->command_val = val & 0x07; break; + default: bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); } @@ -429,6 +450,7 @@ ms_write(uint16_t port, uint8_t val, void *priv) dev->control_val &= INP_PERIOD_MASK; dev->control_val |= (val & ~INP_PERIOD_MASK); return; + default: bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); } @@ -436,6 +458,7 @@ ms_write(uint16_t port, uint8_t val, void *priv) dev->control_val = val; break; + default: bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); } @@ -444,21 +467,30 @@ ms_write(uint16_t port, uint8_t val, void *priv) case INP_PORT_CONFIG: bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); break; + + default: + break; } } /* The emulator calls us with an update on the host mouse device. */ static int -bm_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) +bm_poll(void *priv) { mouse_t *dev = (mouse_t *) priv; - int xor ; + int delta_x; + int delta_y; + int xor; + int b = mouse_get_buttons_ex(); + + if (!mouse_capture && !video_fullscreen) + return 1; if (!(dev->flags & FLAG_ENABLED)) return 1; /* Mouse is disabled, do nothing. */ - if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) { - dev->mouse_buttons_last = b; + if (!mouse_state_changed()) { + dev->mouse_buttons_last = 0x00; return 1; /* State has not changed, do nothing. */ } @@ -472,36 +504,23 @@ bm_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) so update bits 6-3 here. */ /* If the mouse has moved, set bit 6. */ - if (x || y) + if (mouse_moved()) dev->mouse_buttons |= 0x40; /* Set bits 3-5 according to button state changes. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; + xor = ((dev->current_b ^ mouse_get_buttons_ex()) & 0x07) << 3; dev->mouse_buttons |= xor; } dev->mouse_buttons_last = b; - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) - x = 127; - if (x < -128) - x = -128; - - if (y > 127) - y = 127; - if (y < -128) - y = -128; - - if (dev->timer_enabled) { - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { + if (!dev->timer_enabled) { /* If the counters are not frozen, update them. */ if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); + + dev->current_x = (int8_t) delta_x; + dev->current_y = (int8_t) delta_y; dev->current_b = dev->mouse_buttons; } @@ -512,6 +531,7 @@ bm_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) bm_log("DEBUG: Data Interrupt Fired...\n"); } } + return 0; } @@ -522,32 +542,12 @@ bm_update_data(mouse_t *dev) { int delta_x; int delta_y; - int xor ; + int xor; /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { + if ((mouse_capture || video_fullscreen) && !(dev->flags & FLAG_HOLD)) { /* Update the deltas and the delays. */ - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); dev->current_x = (int8_t) delta_x; dev->current_y = (int8_t) delta_y; @@ -633,8 +633,6 @@ bm_init(const device_t *info) } mouse_set_buttons(dev->bn); - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; dev->mouse_buttons = 0; dev->mouse_buttons_last = 0; dev->sig_val = 0; /* the signature port value */ @@ -681,6 +679,8 @@ bm_init(const device_t *info) else bm_log("Standard MS/Logitech BusMouse initialized\n"); + mouse_set_sample_rate(0.0); + return dev; } diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 46144e02e6..c3a7310f0a 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -8,11 +8,12 @@ * * Implementation of PS/2 series Mouse devices. * + * Authors: Miran Grca, * - * - * Authors: Fred N. van Kempen, + * Copyright 2023 Miran Grca. */ #include +#include #include #include #include @@ -20,9 +21,12 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include "cpu.h" #include <86box/device.h> #include <86box/keyboard.h> #include <86box/mouse.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> enum { MODE_STREAM, @@ -72,56 +76,41 @@ static void ps2_report_coordinates(atkbc_dev_t *dev, int main) { uint8_t buff[3] = { 0x08, 0x00, 0x00 }; - int temp_z; - - if (dev->x > 255) { - dev->x = 255; - buff[0] |= 0x40; - } - if (dev->x < -256) { - dev->x = -256; - buff[0] |= 0x40; - } - if (dev->y > 255) { - dev->y = 255; - buff[0] |= 0x80; - } - if (dev->y < -256) { - dev->y = -256; - buff[0] |= 0x80; - } - if (dev->z < -8) - dev->z = -8; - if (dev->z > 7) - dev->z = 7; - - if (dev->x < 0) - buff[0] |= 0x10; - if (dev->y < 0) - buff[0] |= 0x20; - buff[0] |= (dev->b & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03)); - buff[1] = (dev->x & 0xff); - buff[2] = (dev->y & 0xff); + int delta_x; + int delta_y; + int overflow_x; + int overflow_y; + int b = mouse_get_buttons_ex(); + int delta_z; + + mouse_subtract_coords(&delta_x, &delta_y, &overflow_x, &overflow_y, + -256, 255, 1, 0); + mouse_subtract_z(&delta_z, -8, 7, 1); + + buff[0] |= (overflow_y << 7) | (overflow_x << 6) | + ((delta_y & 0x0100) >> 3) | ((delta_x & 0x0100) >> 4) | + (b & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03)); + buff[1] = (delta_x & 0x00ff); + buff[2] = (delta_y & 0x00ff); kbc_at_dev_queue_add(dev, buff[0], main); kbc_at_dev_queue_add(dev, buff[1], main); kbc_at_dev_queue_add(dev, buff[2], main); if (dev->flags & FLAG_INTMODE) { - temp_z = dev->z & 0x0f; + delta_z &= 0x0f; + if (dev->flags & FLAG_5BTN) { - if (mouse_buttons & 8) - temp_z |= 0x10; - if (mouse_buttons & 16) - temp_z |= 0x20; + if (b & 8) + delta_z |= 0x10; + if (b & 16) + delta_z |= 0x20; } else { /* The wheel coordinate is sign-extended. */ - if (temp_z & 0x08) - temp_z |= 0xf0; + if (delta_z & 0x08) + delta_z |= 0xf0; } - kbc_at_dev_queue_add(dev, temp_z, main); + kbc_at_dev_queue_add(dev, delta_z, main); } - - dev->x = dev->y = dev->z = 0; } static void @@ -131,7 +120,7 @@ ps2_set_defaults(atkbc_dev_t *dev) dev->rate = 100; mouse_set_sample_rate(100.0); dev->resolution = 2; - dev->flags &= 0x88; + dev->flags &= 0x188; mouse_scan = 0; } @@ -150,6 +139,7 @@ static void ps2_write(void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; + int b; uint8_t temp; uint8_t val; static uint8_t last_data[6] = { 0x00 }; @@ -208,15 +198,16 @@ ps2_write(void *priv) case 0xe9: /* status request */ mouse_ps2_log("%s: Status request\n", dev->name); + b = mouse_get_buttons_ex(); kbc_at_dev_queue_add(dev, 0xfa, 0); temp = (dev->flags & 0x20); if (mouse_scan) temp |= FLAG_ENABLED; - if (mouse_buttons & 1) + if (b & 1) temp |= 4; - if (mouse_buttons & 2) + if (b & 2) temp |= 1; - if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) + if ((b & 4) && (dev->flags & FLAG_INTELLI)) temp |= 2; kbc_at_dev_queue_add(dev, temp, 0); kbc_at_dev_queue_add(dev, dev->resolution, 0); @@ -286,6 +277,7 @@ ps2_write(void *priv) break; default: + mouse_ps2_log("%s: Bad command: %02X\n", dev->name, val); kbc_at_dev_queue_add(dev, 0xfe, 0); } } @@ -310,30 +302,18 @@ ps2_write(void *priv) } static int -ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) +ps2_poll(void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3; - if (!mouse_scan || (!x && !y && !z && (b == dev->b))) - return 0xff; - - if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) { - dev->x = x; - dev->y = -y; - dev->z = -z; - dev->b = b; - } else { - dev->x += x; - dev->y -= y; - dev->z -= z; - dev->b = b; - } + int cond = (!mouse_capture && !video_fullscreen) || (!mouse_scan || !mouse_state_changed()) || + ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) >= (FIFO_SIZE - packet_size))); - if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) + if (!cond && (dev->mode == MODE_STREAM)) ps2_report_coordinates(dev, 1); - return 0; + return cond; } /* @@ -357,9 +337,6 @@ mouse_ps2_init(const device_t *info) if (i > 4) dev->flags |= FLAG_EXPLORER; - if (i >= 4) - i = 3; - mouse_ps2_log("%s: buttons=%d\n", dev->name, i); /* Tell them how many buttons we have. */ diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 37dc6b4a07..08aee09d86 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -10,10 +10,11 @@ * * TODO: Add the Genius Serial Mouse. * + * Authors: Miran Grca, * - * - * Authors: Fred N. van Kempen, + * Copyright 2023 Miran Grca. */ +#include #include #include #include @@ -26,51 +27,79 @@ #include <86box/timer.h> #include <86box/serial.h> #include <86box/mouse.h> +#include <86box/plat.h> +#include <86box/version.h> #define SERMOUSE_PORT 0 /* attach to Serial0 */ enum { - PHASE_IDLE, - PHASE_ID, - PHASE_DATA, - PHASE_STATUS, - PHASE_DIAGNOSTIC, - PHASE_FORMAT_AND_REVISION, - PHASE_COPYRIGHT_STRING, - PHASE_BUTTONS, - PHASE_ACK, - PHASE_BAUD_RATE + STATE_RESET, + STATE_BAUD_RATE, + STATE_DORMANT, + STATE_IDLE, + STATE_COMMAND, + STATE_DATA, + STATE_TRANSMIT, + STATE_TRANSMIT_REPORT, + STATE_SKIP_REPORT }; enum { - REPORT_PHASE_PREPARE, - REPORT_PHASE_TRANSMIT + FORMAT_BP1_ABS = 0x01, + FORMAT_BP1_REL, + FORMAT_MM_SERIES = 0x13, + FORMAT_PB_3BYTE, + FORMAT_PB_5BYTE, + FORMAT_MSYSTEMS = 0x15, /* Alias for FORMAT_PB_5BYTE. */ + FORMAT_MS, + FORMAT_HEX, + FORMAT_MS_4BYTE, + FORMAT_MS_WHEEL, + FORMATS_NUM }; -typedef struct { - const char *name; /* name of this device */ - int8_t type, /* type of this device */ - port; - uint8_t flags, but, /* device flags */ - want_data, - status, format, - prompt, on_change, - id_len, id[255], - data_len, data[5]; - int abs_x, abs_y, - rel_x, rel_y, - rel_z, - oldb, lastb; - - int command_pos, command_phase, - report_pos, report_phase, - command_enabled, report_enabled; - double transmit_period, report_period, - auto_period; - pc_timer_t command_timer, report_timer; - - serial_t *serial; +typedef struct mouse_t { + const char *name; /* name of this device */ + + uint8_t id[252]; + uint8_t buf[256]; + + uint8_t flags; /* device flags */ + uint8_t but; + uint8_t rts_toggle; + uint8_t status; + uint8_t format; + uint8_t prompt; + + uint8_t continuous; + uint8_t ib; + uint8_t command; + uint8_t buf_len; + uint8_t report_mode; + uint8_t id_len; + uint8_t buf_pos; + uint8_t rev; + + int8_t type; /* type of this device */ + int8_t port; + + int state; + + int bps; + int rps; + + double transmit_period; + double report_period; + double cur_period; + double min_bit_period; + double acc_time; + double host_transmit_period; + + pc_timer_t timer; + + serial_t * serial; } mouse_t; + #define FLAG_INPORT 0x80 /* device is MS InPort */ #define FLAG_3BTN 0x20 /* enable 3-button mode */ #define FLAG_SCALED 0x10 /* enable delta scaling */ @@ -97,184 +126,191 @@ mouse_serial_log(const char *fmt, ...) #endif static void -sermouse_timer_on(mouse_t *dev, double period, int report) +sermouse_set_period(mouse_t *dev, double period) { - pc_timer_t *timer; - int *enabled; - - if (report) { - timer = &dev->report_timer; - enabled = &dev->report_enabled; - } else { - timer = &dev->command_timer; - enabled = &dev->command_enabled; - } + dev->cur_period = period; /* Needed for the recalculation of the timings. */ - timer_on_auto(timer, period); + timer_stop(&dev->timer); - *enabled = 1; + if (period > 0.0) + timer_on_auto(&dev->timer, 10000.0); } -static double -sermouse_transmit_period(mouse_t *dev, int bps, int rps) +static void +sermouse_transmit_byte(mouse_t *dev, int do_next) { - double dbps = (double) bps; - double temp = 0.0; - int word_len; + if (dev->buf_pos == 0) + dev->acc_time = 0.0; - switch (dev->format) { - case 0: - case 1: /* Mouse Systems and Three Byte Packed formats: 8 data, no parity, 2 stop, 1 start */ - word_len = 11; - break; - case 2: /* Hexadecimal format - 8 data, no parity, 1 stop, 1 start - number of stop bits is a guess because - it is not documented anywhere. */ - word_len = 10; - break; - case 3: - case 6: /* Bit Pad One formats: 7 data, even parity, 2 stop, 1 start */ - word_len = 11; - break; - case 5: /* MM Series format: 8 data, odd parity, 1 stop, 1 start */ - word_len = 11; - break; - default: - case 7: /* Microsoft-compatible format: 7 data, no parity, 1 stop, 1 start */ - word_len = 9; - break; - } + serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); - if (rps == -1) - temp = (double) word_len; - else { - temp = (double) rps; - temp = (9600.0 - (temp * 33.0)); - temp /= rps; - } - temp = (1000000.0 / dbps) * temp; + if (do_next) { + dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len; - return temp; + if (dev->buf_pos != 0) + sermouse_set_period(dev, dev->transmit_period); + } } -/* Callback from serial driver: RTS was toggled. */ static void -sermouse_callback(struct serial_s *serial, void *priv) +sermouse_transmit(mouse_t *dev, int len, int from_report, int to_report) { - mouse_t *dev = (mouse_t *) priv; - - /* Start a timer to wake us up in a little while. */ - dev->command_pos = 0; - dev->command_phase = PHASE_ID; - if (dev->id[0] != 'H') - dev->format = 7; - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - timer_stop(&dev->command_timer); -#ifdef USE_NEW_DYNAREC - sermouse_timer_on(dev, cpu_use_dynarec ? 5000.0 : dev->transmit_period, 0); -#else - sermouse_timer_on(dev, dev->transmit_period, 0); -#endif + dev->state = to_report ? STATE_TRANSMIT_REPORT : STATE_TRANSMIT; + dev->buf_pos = 0; + dev->buf_len = len; + + if (from_report) { + if (dev->acc_time > dev->report_period) + dev->acc_time -= dev->report_period; + + /* We have too little time left, pretend it's zero and handle + schedule the next report at byte period. */ + if (dev->acc_time < dev->min_bit_period) + sermouse_set_period(dev, dev->transmit_period); + /* We have enough time, schedule the next report at report period, + subtract the accumulated time from the total period, and add + one byte period (the first byte delay). */ + else + sermouse_set_period(dev, dev->report_period - dev->acc_time + dev->transmit_period); + } else + sermouse_set_period(dev, dev->transmit_period); } static uint8_t -sermouse_data_msystems(mouse_t *dev, int x, int y, int b) +sermouse_report_msystems(mouse_t *dev) { - dev->data[0] = 0x80; - dev->data[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */ - dev->data[0] |= (b & 0x02) ? 0x00 : 0x01; /* middle button */ - dev->data[0] |= (b & 0x04) ? 0x00 : 0x02; /* right button */ - dev->data[1] = x; - dev->data[2] = -y; - dev->data[3] = x; /* same as byte 1 */ - dev->data[4] = -y; /* same as byte 2 */ + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x00 : 0x02; /* middle button */ + else + dev->buf[0] |= 0x02; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x00 : 0x01; /* right button */ + dev->buf[1] = delta_x; + dev->buf[2] = delta_y; + dev->buf[3] = delta_x; /* same as byte 1 */ + dev->buf[4] = delta_y; /* same as byte 2 */ return 5; } static uint8_t -sermouse_data_3bp(mouse_t *dev, int x, int y, int b) +sermouse_report_3bp(mouse_t *dev) { - dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - dev->data[1] = x; - dev->data[2] = -y; + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + dev->buf[1] = delta_x; + dev->buf[2] = delta_y; return 3; } static uint8_t -sermouse_data_mmseries(mouse_t *dev, int x, int y, int b) +sermouse_report_mmseries(mouse_t *dev) { - if (x < -127) - x = -127; - if (y < -127) - y = -127; - - dev->data[0] = 0x80; - if (x >= 0) - dev->data[0] |= 0x10; - /* It appears we have inverted Y polarity. */ - if (y < 0) - dev->data[0] |= 0x08; - dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - dev->data[1] = abs(x) & 0x7f; - dev->data[2] = abs(y) & 0x7f; + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -127, 127, 1, 0); + + dev->buf[0] = 0x80; + if (delta_x >= 0) + dev->buf[0] |= 0x10; + if (delta_y >= 0) + dev->buf[0] |= 0x08; + + dev->buf[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + dev->buf[1] = ABS(delta_x) & 0x7f; + dev->buf[2] = ABS(delta_y) & 0x7f; + mouse_serial_log("MM series mouse report: %02X %02X %02X\n", dev->buf[0], dev->buf[1], dev->buf[2]); return 3; } static uint8_t -sermouse_data_bp1(mouse_t *dev, int x, int y, int b) +sermouse_report_bp1(mouse_t *dev, int abs) { - dev->data[0] = 0x80; - dev->data[0] |= (b & 0x01) ? 0x10 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x08 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x04 : 0x00; /* right button */ - dev->data[1] = (x & 0x3f); - dev->data[2] = (x >> 6); - dev->data[3] = (y & 0x3f); - dev->data[4] = (y >> 6); + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -2048, 2047, 1, abs); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x10 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x08 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x04 : 0x00; /* right button */ + dev->buf[1] = (delta_x & 0x3f); + dev->buf[2] = ((delta_x >> 6) & 0x3f); + dev->buf[3] = (delta_y & 0x3f); + dev->buf[4] = ((delta_y >> 6) & 0x3f); return 5; } static uint8_t -sermouse_data_ms(mouse_t *dev, int x, int y, int z, int b) +sermouse_report_ms(mouse_t *dev) { uint8_t len; + int delta_x = 0; + int delta_y = 0; + int delta_z = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); + mouse_subtract_z(&delta_z, -8, 7, 1); - dev->data[0] = 0x40; - dev->data[0] |= (((y >> 6) & 0x03) << 2); - dev->data[0] |= ((x >> 6) & 0x03); + dev->buf[0] = 0x40; + dev->buf[0] |= (((delta_y >> 6) & 0x03) << 2); + dev->buf[0] |= ((delta_x >> 6) & 0x03); if (b & 0x01) - dev->data[0] |= 0x20; + dev->buf[0] |= 0x20; if (b & 0x02) - dev->data[0] |= 0x10; - dev->data[1] = x & 0x3F; - dev->data[2] = y & 0x3F; + dev->buf[0] |= 0x10; + dev->buf[1] = delta_x & 0x3f; + dev->buf[2] = delta_y & 0x3f; + mouse_serial_log("Microsoft serial mouse report: %02X %02X %02X\n", dev->buf[0], dev->buf[1], dev->buf[2]); if (dev->but == 3) { len = 3; - if (dev->type == MOUSE_TYPE_LT3BUTTON) { + if (dev->format == FORMAT_MS) { if (b & 0x04) { - dev->data[3] = 0x20; + dev->buf[3] = 0x20; len++; } } else { - if ((b ^ dev->oldb) & 0x04) { + if (mouse_mbut_changed()) { /* Microsoft 3-button mice send a fourth byte of 0x00 when the middle button has changed. */ - dev->data[3] = 0x00; + dev->buf[3] = 0x00; len++; } } } else if (dev->but == 4) { - len = 4; - dev->data[3] = z & 0x0F; + len = 4; + + dev->buf[3] = delta_z & 0x0f; if (b & 0x04) - dev->data[3] |= 0x10; + dev->buf[3] |= 0x10; } else len = 3; @@ -282,461 +318,500 @@ sermouse_data_ms(mouse_t *dev, int x, int y, int z, int b) } static uint8_t -sermouse_data_hex(mouse_t *dev, int x, int y, int b) +sermouse_report_hex(mouse_t *dev) { char ret[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t but = 0x00; + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); but |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + if (dev->but >= 3) + but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ but |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - sprintf(ret, "%02X%02X%01X", (int8_t) y, (int8_t) x, but & 0x0f); + sprintf(ret, "%01X%02X%02X", but & 0x0f, (int8_t) delta_x, (int8_t) delta_y); - for (uint8_t i = 0; i < 5; i++) - dev->data[i] = ret[4 - i]; + memcpy(dev->buf, ret, 5); return 5; } -static void -sermouse_report(int x, int y, int z, int b, mouse_t *dev) +static int +sermouse_report(mouse_t *dev) { int len = 0; - memset(dev->data, 0, 5); - - /* If the mouse is 2-button, ignore the middle button. */ - if (dev->but == 2) - b &= ~0x04; + memset(dev->buf, 0, 5); switch (dev->format) { - case 0: - len = sermouse_data_msystems(dev, x, y, b); + case FORMAT_PB_5BYTE: + len = sermouse_report_msystems(dev); break; - case 1: - len = sermouse_data_3bp(dev, x, y, b); + case FORMAT_PB_3BYTE: + len = sermouse_report_3bp(dev); break; - case 2: - len = sermouse_data_hex(dev, x, y, b); + case FORMAT_HEX: + len = sermouse_report_hex(dev); break; - case 3: /* Relative */ - len = sermouse_data_bp1(dev, x, y, b); + case FORMAT_BP1_REL: + len = sermouse_report_bp1(dev, 0); break; - case 5: - len = sermouse_data_mmseries(dev, x, y, b); + case FORMAT_MM_SERIES: + len = sermouse_report_mmseries(dev); break; - case 6: /* Absolute */ - len = sermouse_data_bp1(dev, dev->abs_x, dev->abs_y, b); + case FORMAT_BP1_ABS: + len = sermouse_report_bp1(dev, 1); break; - case 7: - len = sermouse_data_ms(dev, x, y, z, b); + case FORMAT_MS: + case FORMAT_MS_4BYTE: + case FORMAT_MS_WHEEL: + len = sermouse_report_ms(dev); + break; + + default: break; } - dev->data_len = len; + return len; } static void -sermouse_command_phase_idle(mouse_t *dev) +sermouse_transmit_report(mouse_t *dev, int from_report) { - dev->command_pos = 0; - dev->command_phase = PHASE_IDLE; - dev->command_enabled = 0; + if (mouse_capture && mouse_state_changed()) + sermouse_transmit(dev, sermouse_report(dev), from_report, 1); + else { + if (dev->prompt || dev->continuous) + sermouse_set_period(dev, 0.0); + else { + dev->state = STATE_SKIP_REPORT; + /* Not in prompt or continuous mode and there have been no changes, + skip the next report entirely. */ + if (from_report) { + if (dev->acc_time > dev->report_period) + dev->acc_time -= dev->report_period; + + if (dev->acc_time < dev->min_bit_period) + sermouse_set_period(dev, dev->report_period); + else + sermouse_set_period(dev, (dev->report_period * 2.0) - dev->acc_time); + } else + sermouse_set_period(dev, dev->report_period); + } + } } -static void -sermouse_command_pos_check(mouse_t *dev, int len) +static int +sermouse_poll(void *priv) { - if (++dev->command_pos == len) - sermouse_command_phase_idle(dev); - else - timer_on_auto(&dev->command_timer, dev->transmit_period); + mouse_t *dev = (mouse_t *) priv; + + if (!mouse_capture || dev->prompt || !dev->continuous || (dev->state != STATE_IDLE)) + return 1; + + sermouse_transmit_report(dev, 0); + return (dev->cur_period == 0.0) ? 1 : 0; } -static uint8_t -sermouse_last_button_status(mouse_t *dev) +static void +ltsermouse_set_prompt_mode(mouse_t *dev, int prompt) { - uint8_t ret = 0x00; - - if (dev->oldb & 0x01) - ret |= 0x04; - if (dev->oldb & 0x02) - ret |= 0x02; - if (dev->oldb & 0x04) - ret |= 0x01; + dev->prompt = prompt; - return ret; + if (prompt || dev->continuous) + sermouse_set_period(dev, 0.0); + else + sermouse_set_period(dev, dev->transmit_period); } static void -sermouse_update_delta(mouse_t *dev, int *local, int *global) +ltsermouse_set_report_period(mouse_t *dev, int rps) { - int min; - int max; + /* Limit the reports rate according to the baud rate. */ + if (rps == 0) { + sermouse_set_period(dev, 0.0); - if (dev->format == 3) { - min = -2048; - max = 2047; + dev->report_period = 0.0; + dev->continuous = 1; } else { - min = -128; - max = 127; +#if 0 + if (rps > dev->max_rps) + rps = dev->max_rps; +#endif + + dev->continuous = 0; + dev->report_period = 1000000.0 / ((double) rps); + /* Actual spacing between reports. */ } +} - if (*global > max) { - *local = max; - *global -= max; - } else if (*global < min) { - *local = min; - *global += -min; - } else { - *local = *global; - *global = 0; +static void +ltsermouse_update_report_period(mouse_t *dev) +{ + ltsermouse_set_report_period(dev, dev->rps); + + ltsermouse_set_prompt_mode(dev, 0); + mouse_serial_log("ltsermouse_update_report_period(): %i, %i\n", dev->continuous, dev->prompt); + if (dev->continuous) + dev->state = STATE_IDLE; + else { + sermouse_transmit_report(dev, 0); + dev->state = STATE_TRANSMIT_REPORT; } } -static uint8_t -sermouse_update_data(mouse_t *dev) +static void +ltsermouse_switch_baud_rate(mouse_t *dev, int next_state) { - uint8_t ret = 0; - int delta_x; - int delta_y; - int delta_z; + double word_lens[FORMATS_NUM] = { + [FORMAT_BP1_ABS] = 7.0 + 1.0, /* 7 data bits + even parity */ + [FORMAT_BP1_REL] = 7.0 + 1.0, /* 7 data bits + even parity */ + [FORMAT_MM_SERIES] = 8.0 + 1.0, /* 8 data bits + odd parity */ + [FORMAT_PB_3BYTE] = 8.0, /* 8 data bits + no parity */ + [FORMAT_PB_5BYTE] = 8.0, /* 8 data bits + no parity */ + [FORMAT_MS] = 7.0, /* 7 datas bits + no parity */ + [FORMAT_HEX] = 8.0, /* 8 data bits + no parity */ + [FORMAT_MS_4BYTE] = 7.0, /* 7 datas bits + no parity */ + [FORMAT_MS_WHEEL] = 7.0 }; /* 7 datas bits + no parity */ + double word_len = word_lens[dev->format]; + + word_len += 1.0 + 2.0; /* 1 start bit + 2 stop bits */ + +#if 0 + dev->max_rps = (int) floor(((double) dev->bps) / (word_len * num_words)); +#endif - /* Update the deltas and the delays. */ - sermouse_update_delta(dev, &delta_x, &dev->rel_x); - sermouse_update_delta(dev, &delta_y, &dev->rel_y); - sermouse_update_delta(dev, &delta_z, &dev->rel_z); + if (next_state == STATE_BAUD_RATE) + dev->transmit_period = dev->host_transmit_period; + else + dev->transmit_period = 1000000.0 / ((double) dev->bps); - sermouse_report(delta_x, delta_y, delta_z, dev->oldb, dev); + dev->min_bit_period = dev->transmit_period; - mouse_serial_log("delta_x = %i, delta_y = %i, delta_z = %i, dev->oldb = %02X\n", - delta_x, delta_y, delta_z, dev->oldb); + dev->transmit_period *= word_len; + /* The transmit period for the entire report, we're going to need this in ltsermouse_set_report_period(). */ +#if 0 + dev->report_transmit_period = dev->transmit_period * num_words; +#endif - if (delta_x || delta_y || delta_z || (dev->oldb != dev->lastb) || !dev->on_change) - ret = 1; + ltsermouse_set_report_period(dev, dev->rps); - dev->lastb = dev->oldb; + if (!dev->continuous && (next_state != STATE_BAUD_RATE)) { + if (dev->prompt) + ltsermouse_set_prompt_mode(dev, 0); - mouse_serial_log("sermouse_update_data(): ret = %i\n", ret); + sermouse_transmit_report(dev, 0); + } - return ret; + dev->state = next_state; } -static double -sermouse_report_period(mouse_t *dev) +static int +sermouse_next_state(mouse_t *dev) { - if (dev->report_period == 0) - return dev->transmit_period; + int ret = STATE_IDLE; + + if (dev->prompt || (dev->rps == 0)) + ret = STATE_IDLE; else - return dev->report_period; -} + ret = STATE_TRANSMIT; -static void -sermouse_report_prepare(mouse_t *dev) -{ - if (sermouse_update_data(dev)) { - /* Start sending data. */ - dev->report_phase = REPORT_PHASE_TRANSMIT; - dev->report_pos = 0; - sermouse_timer_on(dev, dev->transmit_period, 1); - } else { - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - } + return ret; } static void -sermouse_report_timer(void *priv) +ltsermouse_process_command(mouse_t *dev) { - mouse_t *dev = (mouse_t *) priv; + int cmd_to_rps[9] = { 10, 20, 35, 70, 150, 0, -1, 100, 50 }; + int b; + uint8_t format_codes[FORMATS_NUM] = { + [FORMAT_BP1_ABS] = 0x0c, + [FORMAT_BP1_REL] = 0x06, + [FORMAT_MM_SERIES] = 0x0a, + [FORMAT_PB_3BYTE] = 0x00, + [FORMAT_PB_5BYTE] = 0x02, + [FORMAT_MS] = 0x0e, + [FORMAT_HEX] = 0x04, + [FORMAT_MS_4BYTE] = 0x08, /* Guess */ + [FORMAT_MS_WHEEL] = 0x08 }; /* Guess */ + const char *copr = "\r\n(C) " COPYRIGHT_YEAR " 86Box, Revision 3.0"; + + mouse_serial_log("ltsermouse_process_command(): %02X\n", dev->ib); + dev->command = dev->ib; + + switch (dev->command) { + case 0x20: + /* Auto Baud Selection */ + dev->bps = (int) floor(1000000.0 / dev->host_transmit_period); + dev->transmit_period = dev->host_transmit_period; + + dev->buf[0] = 0x06; + sermouse_transmit(dev, 1, 0, 0); + + ltsermouse_switch_baud_rate(dev, STATE_BAUD_RATE); + break; - if (dev->report_phase == REPORT_PHASE_PREPARE) - sermouse_report_prepare(dev); - else { - /* If using the Mouse Systems format, update data because - the last two bytes are the X and Y delta since bytes 1 - and 2 were transmitted. */ - if (!dev->format && (dev->report_pos == 3)) - sermouse_update_data(dev); - serial_write_fifo(dev->serial, dev->data[dev->report_pos]); - if (++dev->report_pos == dev->data_len) { - if (!dev->report_enabled) - sermouse_report_prepare(dev); - else { - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - dev->report_phase = REPORT_PHASE_PREPARE; - } - } else - sermouse_timer_on(dev, dev->transmit_period, 1); - } -} + case 0x4a: /* Report Rate Selection commands */ + case 0x4b: + case 0x4c: + case 0x52: + case 0x4d: + case 0x51: + case 0x4e: + case 0x4f: + dev->report_mode = dev->command; + dev->rps = cmd_to_rps[dev->command - 0x4a]; + ltsermouse_update_report_period(dev); + break; -/* Callback timer expired, now send our "mouse ID" to the serial port. */ -static void -sermouse_command_timer(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; + case 0x44: + /* Select Prompt Mode */ + dev->report_mode = dev->command; + ltsermouse_set_prompt_mode(dev, 1); + dev->state = STATE_IDLE; + break; + case 0x50: + /* Promopt to send a report (also enters Prompt Mode). */ + if (!dev->prompt) { + dev->report_mode = 0x44; + ltsermouse_set_prompt_mode(dev, 1); + } + sermouse_transmit_report(dev, 0); + dev->state = STATE_TRANSMIT_REPORT; + break; - switch (dev->command_phase) { - case PHASE_ID: - serial_write_fifo(dev->serial, dev->id[dev->command_pos]); - sermouse_command_pos_check(dev, dev->id_len); - if ((dev->command_phase == PHASE_IDLE) && (dev->type != MOUSE_TYPE_MSYSTEMS)) { - /* This resets back to Microsoft-compatible mode. */ - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); + case 0x41: + /* Absolute Bit Pad One Packed Binary Format */ + mouse_clear_coords(); + fallthrough; + case 0x42: /* Relative Bit Pad One Packed Binary Format */ + case 0x53: /* MM Series Data Format */ + case 0x54: /* Three Byte Packed Binary Format */ + case 0x55: /* Five Byte Packed Binary Format (Mouse Systems-compatible) */ + case 0x56: /* Microsoft Compatible Format */ + case 0x57: /* Hexadecimal Format */ + case 0x58: /* Microsoft Compatible Format (3+1 byte 3-button, from the FreeBSD source code) */ + if ((dev->rev >= 0x02) && ((dev->command != 0x58) || (dev->rev > 0x04))) { + dev->format = dev->command & 0x1f; + ltsermouse_switch_baud_rate(dev, sermouse_next_state(dev)); } break; - case PHASE_ACK: - serial_write_fifo(dev->serial, 0x06); - /* FALLTHROUGH */ - case PHASE_BAUD_RATE: - sermouse_command_phase_idle(dev); - sermouse_timer_on(dev, dev->report_period, 1); - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); - break; - case PHASE_DATA: - serial_write_fifo(dev->serial, dev->data[dev->command_pos]); - sermouse_command_pos_check(dev, dev->data_len); - break; - case PHASE_STATUS: - serial_write_fifo(dev->serial, dev->status); - sermouse_command_phase_idle(dev); - break; - case PHASE_DIAGNOSTIC: - if (dev->command_pos) - serial_write_fifo(dev->serial, 0x00); - else - serial_write_fifo(dev->serial, sermouse_last_button_status(dev)); - sermouse_command_pos_check(dev, 3); + + case 0x2a: + if (dev->rev >= 0x03) { + /* Programmable Baud Rate Selection */ + dev->state = STATE_DATA; + } break; - case PHASE_FORMAT_AND_REVISION: - serial_write_fifo(dev->serial, 0x10 | (dev->format << 1)); - sermouse_command_phase_idle(dev); + + case 0x73: + /* Status */ + dev->buf[0] = dev->prompt ? 0x4f : 0x0f; + sermouse_transmit(dev, 1, 0, 0); break; - case PHASE_BUTTONS: - serial_write_fifo(dev->serial, dev->but); - sermouse_command_phase_idle(dev); + case 0x05: + /* Diagnostic */ + b = mouse_get_buttons_ex(); + dev->buf[0] = ((b & 0x01) << 2) | ((b & 0x06) >> 1); + dev->buf[1] = dev->buf[2] = 0x00; + sermouse_transmit(dev, 3, 0, 0); break; - default: - sermouse_command_phase_idle(dev); + + case 0x66: + if (dev->rev >= 0x20) { + /* Format and Revision Number */ + dev->buf[0] = format_codes[dev->format]; + dev->buf[0] |= 0x10; /* Revision 3.0, 0x00 would be Revision 2.0 */ + sermouse_transmit(dev, 1, 0, 0); + } break; - } -} -static int -sermouse_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) -{ - mouse_t *dev = (mouse_t *) priv; + case 0x74: + /* Format and Mode in ASCII */ + if (dev->rev >= 0x03) { + dev->buf[0] = dev->format | 0x40; + dev->buf[1] = dev->report_mode; + sermouse_transmit(dev, 2, 0, 0); + } + break; - if (!x && !y && !z && (b == dev->oldb)) { - dev->oldb = b; - return 1; - } + case 0x63: + /* Copyright and Revision in ASCII */ + if (dev->rev >= 0x03) { + memcpy(&(dev->buf[0]), copr, strlen(copr) + 1); + sermouse_transmit(dev, strlen(copr) + 1, 0, 0); + } else { + memcpy(&(dev->buf[0]), copr, strlen(copr)); + sermouse_transmit(dev, strlen(copr), 0, 0); + } + dev->buf[29] = dev->rev | 0x30; + break; - dev->oldb = b; - dev->abs_x += x; - dev->abs_y += y; - if (dev->abs_x < 0) - dev->abs_x = 0; - if (dev->abs_x > 4095) - dev->abs_x = 4095; - if (dev->abs_y < 0) - dev->abs_y = 0; - if (dev->abs_y > 4095) - dev->abs_y = 4095; - - if (dev->format == 3) { - if (x > 2047) - x = 2047; - if (y > 2047) - y = 2047; - if (x < -2048) - x = -2048; - if (y < -2048) - y = -2048; - } else { - if (x > 127) - x = 127; - if (y > 127) - y = 127; - if (x < -128) - x = -128; - if (y < -128) - y = -128; - } + case 0x64: + /* Dormant State */ + dev->state = STATE_DORMANT; + break; - dev->rel_x += x; - dev->rel_y += y; - dev->rel_z += z; + case 0x6b: + /* Buttons - 86Box-specific command. */ + dev->state = dev->but; + break; - return 0; + default: + break; + } } static void -ltsermouse_prompt_mode(mouse_t *dev, int prompt) +ltsermouse_process_data(mouse_t *dev) { - dev->prompt = prompt; - dev->status &= 0xBF; - if (prompt) - dev->status |= 0x40; + mouse_serial_log("ltsermouse_process_data(): %02X (command = %02X)\n", dev->ib, dev->command); + + switch(dev->command) { + case 0x2a: + switch (dev->ib) { + default: + fallthrough; + case 0x6e: + dev->bps = 1200; + break; + case 0x6f: + dev->bps = 2400; + break; + case 0x70: + dev->bps = 4800; + break; + case 0x71: + dev->bps = 9600; + break; + } + ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT); + break; + default: + dev->state = STATE_IDLE; + break; + } } static void -ltsermouse_command_phase(mouse_t *dev, int phase) +sermouse_reset(mouse_t *dev, int callback) { - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, dev->transmit_period, 0); + sermouse_set_period(dev, 0.0); + + dev->bps = 1200; + dev->rps = 0; + dev->prompt = 0; + if (dev->id[0] == 'H') + dev->format = FORMAT_MSYSTEMS; + else switch (dev->but) { + default: + case 2: + dev->format = FORMAT_MS; + break; + case 3: + dev->format = (dev->type == MOUSE_TYPE_LT3BUTTON) ? FORMAT_MS : FORMAT_MS_4BYTE; + break; + case 4: + dev->format = FORMAT_MS_WHEEL; + break; + } + + ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE); } static void -ltsermouse_set_report_period(mouse_t *dev, int rps) +sermouse_timer(void *priv) { - dev->report_period = sermouse_transmit_period(dev, 9600, rps); - timer_stop(&dev->report_timer); - sermouse_timer_on(dev, dev->report_period, 1); - ltsermouse_prompt_mode(dev, 0); - dev->report_phase = REPORT_PHASE_PREPARE; + mouse_t *dev = (mouse_t *) priv; +#ifdef ENABLE_MOUSE_SERIAL_LOG + int old_state = dev->state; +#endif + + switch (dev->state) { + case STATE_RESET: + /* All three mice default to continuous reporting. */ + sermouse_reset(dev, 0); + break; + case STATE_DATA: + ltsermouse_process_data(dev); + break; + case STATE_COMMAND: + ltsermouse_process_command(dev); + break; + case STATE_SKIP_REPORT: + if (!dev->prompt && !dev->continuous) + sermouse_transmit_report(dev, (dev->state == STATE_TRANSMIT_REPORT)); + else + dev->state = STATE_IDLE; + break; + case STATE_TRANSMIT_REPORT: + case STATE_TRANSMIT: + case STATE_BAUD_RATE: + sermouse_transmit_byte(dev, 1); + + if (dev->buf_pos == 0) { + if (!dev->prompt && !dev->continuous) + sermouse_transmit_report(dev, (dev->state == STATE_TRANSMIT_REPORT)); + else + dev->state = STATE_IDLE; + } + break; + default: + break; + } + + mouse_serial_log("sermouse_timer(): %02i -> %02i\n", old_state, dev->state); } static void -ltsermouse_switch_baud_rate(mouse_t *dev, int phase) +ltsermouse_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) { - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, 10000.0, 0); + mouse_t *dev = (mouse_t *) priv; + + mouse_serial_log("ltsermouse_write(): %02X\n", data); + + dev->ib = data; + + switch (dev->state) { + case STATE_RESET: + case STATE_BAUD_RATE: + break; + case STATE_TRANSMIT_REPORT: + case STATE_TRANSMIT: + case STATE_SKIP_REPORT: + sermouse_set_period(dev, 0.0); + fallthrough; + default: + dev->state = STATE_COMMAND; + fallthrough; + case STATE_DATA: + sermouse_timer(dev); + break; + } } +/* Callback from serial driver: RTS was toggled. */ static void -ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data) +sermouse_callback(UNUSED(struct serial_s *serial), void *priv) { mouse_t *dev = (mouse_t *) priv; - /* Stop reporting when we're processing a command. */ - dev->report_phase = REPORT_PHASE_PREPARE; - - if (dev->want_data) - switch (dev->want_data) { - case 0x2A: - dev->data_len--; - dev->want_data = 0; - switch (data) { - default: - mouse_serial_log("Serial mouse: Invalid period %02X, using 1200 bps\n", data); - /*FALLTHROUGH*/ - case 0x6E: - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - break; - case 0x6F: - dev->transmit_period = sermouse_transmit_period(dev, 2400, -1); - break; - case 0x70: - dev->transmit_period = sermouse_transmit_period(dev, 4800, -1); - break; - case 0x71: - dev->transmit_period = sermouse_transmit_period(dev, 9600, -1); - break; - } - ltsermouse_switch_baud_rate(dev, PHASE_BAUD_RATE); - break; - } - else - switch (data) { - case 0x20: - sermouse_timer_on(dev, 0.0, 1); - dev->transmit_period = dev->auto_period; - ltsermouse_switch_baud_rate(dev, PHASE_ACK); - break; - case 0x2A: - sermouse_timer_on(dev, 0.0, 1); - dev->want_data = data; - dev->data_len = 1; - break; - case 0x44: /* Set prompt mode */ - ltsermouse_prompt_mode(dev, 1); - break; - case 0x50: - if (!dev->prompt) - ltsermouse_prompt_mode(dev, 1); - sermouse_update_data(dev); - ltsermouse_command_phase(dev, PHASE_DATA); - break; - case 0x73: /* Status */ - ltsermouse_command_phase(dev, PHASE_STATUS); - break; - case 0x4A: /* Report Rate Selection commands */ - ltsermouse_set_report_period(dev, 10); - break; - case 0x4B: - ltsermouse_set_report_period(dev, 20); - break; - case 0x4C: - ltsermouse_set_report_period(dev, 35); - break; - case 0x52: - ltsermouse_set_report_period(dev, 50); - break; - case 0x4D: - ltsermouse_set_report_period(dev, 70); - break; - case 0x51: - ltsermouse_set_report_period(dev, 100); - break; - case 0x4E: - ltsermouse_set_report_period(dev, 150); - break; - case 0x4F: - ltsermouse_prompt_mode(dev, 0); - dev->report_period = 0; - timer_stop(&dev->report_timer); - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); - break; - case 0x41: - dev->format = 6; /* Aboslute Bit Pad One Format */ - dev->abs_x = dev->abs_y = 0; - break; - case 0x42: - dev->format = 3; /* Relative Bit Pad One Format */ - break; - case 0x53: - dev->format = 5; /* MM Series Format */ - break; - case 0x54: - dev->format = 1; /* Three Byte Packed Binary Format */ - break; - case 0x55: /* This is the Mouse Systems-compatible format */ - dev->format = 0; /* Five Byte Packed Binary Format */ - break; - case 0x56: - dev->format = 7; /* Microsoft Compatible Format */ - break; - case 0x57: - dev->format = 2; /* Hexadecimal Format */ - break; - case 0x05: - ltsermouse_command_phase(dev, PHASE_DIAGNOSTIC); - break; - case 0x66: - ltsermouse_command_phase(dev, PHASE_FORMAT_AND_REVISION); - break; - case 0x6B: - ltsermouse_command_phase(dev, PHASE_BUTTONS); - break; - } + sermouse_reset(dev, 1); + + memcpy(dev->buf, dev->id, dev->id_len); + sermouse_transmit(dev, dev->id_len, 0, 0); } static void -ltsermouse_transmit_period(serial_t *serial, void *priv, double transmit_period) +ltsermouse_transmit_period(UNUSED(serial_t *serial), void *priv, double transmit_period) { mouse_t *dev = (mouse_t *) priv; - dev->auto_period = transmit_period; + dev->host_transmit_period = transmit_period; } static void @@ -744,18 +819,8 @@ sermouse_speed_changed(void *priv) { mouse_t *dev = (mouse_t *) priv; - if (dev->report_enabled) { - timer_stop(&dev->report_timer); - if (dev->report_phase == REPORT_PHASE_TRANSMIT) - sermouse_timer_on(dev, dev->transmit_period, 1); - else - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - } - - if (dev->command_enabled) { - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, dev->transmit_period, 0); - } + if (dev->cur_period != 0.0) + sermouse_set_period(dev, dev->cur_period); } static void @@ -775,29 +840,39 @@ static void * sermouse_init(const device_t *info) { mouse_t *dev; + void (*rcr_callback)(struct serial_s *serial, void *priv); + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data); + void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period); dev = (mouse_t *) malloc(sizeof(mouse_t)); memset(dev, 0x00, sizeof(mouse_t)); dev->name = info->name; dev->but = device_get_config_int("buttons"); + dev->rev = device_get_config_int("revision"); + + if (info->local == 0) + dev->rts_toggle = 1; + else + dev->rts_toggle = device_get_config_int("rts_toggle"); + if (dev->but > 2) dev->flags |= FLAG_3BTN; if (info->local == MOUSE_TYPE_MSYSTEMS) { - dev->on_change = 1; dev->format = 0; dev->type = info->local; dev->id_len = 1; dev->id[0] = 'H'; } else { - dev->on_change = !info->local; dev->format = 7; dev->status = 0x0f; dev->id_len = 1; dev->id[0] = 'M'; + if (info->local) + dev->rev = device_get_config_int("revision"); switch (dev->but) { - case 2: default: + case 2: dev->type = info->local ? MOUSE_TYPE_LOGITECH : MOUSE_TYPE_MICROSOFT; break; case 3: @@ -814,41 +889,73 @@ sermouse_init(const device_t *info) } } - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - dev->auto_period = dev->transmit_period; - - /* Default: Continuous reporting = no delay between reports. */ - dev->report_phase = REPORT_PHASE_PREPARE; - dev->report_period = 0; - - /* Default: Doing nothing - command transmit timer deactivated. */ - dev->command_phase = PHASE_IDLE; - dev->port = device_get_config_int("port"); /* Attach a serial port to the mouse. */ - if (info->local) - dev->serial = serial_attach_ex(dev->port, sermouse_callback, ltsermouse_write, ltsermouse_transmit_period, NULL, dev); - else - dev->serial = serial_attach(dev->port, sermouse_callback, NULL, dev); + rcr_callback = dev->rts_toggle ? sermouse_callback : NULL; + dev_write = (info->local == 1) ? ltsermouse_write : NULL; + transmit_period_callback = (info->local == 1) ? ltsermouse_transmit_period : NULL; + + dev->serial = serial_attach_ex(dev->port, rcr_callback, dev_write, + transmit_period_callback, NULL, dev); mouse_serial_log("%s: port=COM%d\n", dev->name, dev->port + 1); - timer_add(&dev->report_timer, sermouse_report_timer, dev, 0); - timer_add(&dev->command_timer, sermouse_command_timer, dev, 0); + timer_add(&dev->timer, sermouse_timer, dev, 0); - if (info->local == MOUSE_TYPE_MSYSTEMS) { - sermouse_timer_on(dev, dev->transmit_period, 1); - dev->report_enabled = 1; - } + /* The five second delay allows the mouse to execute internal initializations. */ + sermouse_set_period(dev, 5000000.0); /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); + mouse_set_buttons(dev->but); /* Return our private data to the I/O layer. */ - return (dev); + return dev; } +static const device_config_t msssermouse_config[] = { + // clang-format off + { + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "COM1", .value = 0 }, + { .description = "COM2", .value = 1 }, + { .description = "COM3", .value = 2 }, + { .description = "COM4", .value = 3 }, + { .description = "" } + } + }, + { + .name = "buttons", + .description = "Buttons", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 2, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Two", .value = 2 }, + { .description = "Three", .value = 3 }, + { .description = "" } + } + }, + { + .name = "rts_toggle", + .description = "RTS toggle", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t mssermouse_config[] = { // clang-format off { @@ -918,6 +1025,29 @@ static const device_config_t ltsermouse_config[] = { { .description = "" } } }, + { + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "LOGIMOUSE R7 1.0", .value = 1 }, + { .description = "LOGIMOUSE R7 2.0", .value = 2 }, + { .description = "LOGIMOUSE C7 3.0", .value = 3 }, + { .description = "Logitech MouseMan", .value = 4 }, + { .description = "" } + } + }, + { + .name = "rts_toggle", + .description = "Microsoft-compatible RTS toggle", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -933,7 +1063,7 @@ const device_t mouse_mssystems_device = { { .poll = sermouse_poll }, .speed_changed = sermouse_speed_changed, .force_redraw = NULL, - .config = mssermouse_config + .config = msssermouse_config }; const device_t mouse_msserial_device = { diff --git a/src/device/mouse_wacom_tablet.c b/src/device/mouse_wacom_tablet.c index fa5c4651f4..d299d8bab3 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -66,37 +66,49 @@ static const uint32_t wacom_resolution_values[4] = { 1270 }; -typedef struct { +typedef struct mouse_wacom_t { const char *name; /* name of this device */ - int8_t type, /* type of this device */ - port; - uint8_t flags, but, /* device flags */ - status, bits, - data_rec[0x200]; - int abs_x, abs_y, - rel_x, rel_y, - oldb, b; + int8_t type; /* type of this device */ + int8_t port; + uint8_t flags; /* device flags */ + uint8_t but; + uint8_t status; + uint8_t bits; + uint8_t data_rec[0x200]; + int abs_x; + int abs_y; + int rel_x; + int rel_y; + int oldb; + int b; Fifo8 data; - int data_rec_pos, mode, interval; - int increment, suppressed_increment; + int data_rec_pos; + int mode; + int interval; + int increment; + int suppressed_increment; int transmission_stopped; int reset; - int transmit_id, transmit_id_pending; + int transmit_id; + int transmit_id_pending; int pressure_mode; - int suppressed, measurement; + int suppressed; + int measurement; int remote_req; - uint32_t x_res, y_res; - const wacom_tablet_id* tablet_type; + uint32_t x_res; + uint32_t y_res; + const wacom_tablet_id *tablet_type; - int last_abs_x, last_abs_y; /* Suppressed/Increment Mode. */ + int last_abs_x; /* Suppressed/Increment Mode. */ + int last_abs_y; /* Suppressed/Increment Mode. */ union { uint32_t settings; /* Settings DWORD */ /* We don't target any architectures except x86/x64/ARM32/ARM64. (The ABIs for those are explicit in little-endian bit ordering) */ - struct { + struct settings_bits { uint8_t remote_mode : 1; uint8_t bitpad_two_cursor_data : 1; uint8_t mm961_orientation : 1; @@ -128,7 +140,8 @@ typedef struct { }; double transmit_period; - double old_tsc, reset_tsc; + double old_tsc; + double reset_tsc; pc_timer_t report_timer; serial_t *serial; @@ -197,9 +210,12 @@ wacom_process_settings_dword(mouse_wacom_t *wacom, uint32_t dword) case 3: wacom->transmit_period = wacom_transmit_period(wacom, 19200, -1); break; + + default: + break; } - mouse_mode = !wacom->settings_bits.coord_sys; + mouse_input_mode = !wacom->settings_bits.coord_sys; wacom->x_res = wacom->y_res = wacom_resolution_values[wacom->settings_bits.resolution]; } @@ -219,7 +235,7 @@ wacom_reset(mouse_wacom_t *wacom) wacom->settings_bits.remote_mode = wacom->remote_req = 0; wacom->settings_bits.out_of_range_data = 0; - mouse_mode = 1; + mouse_input_mode = 1; wacom_process_settings_dword(wacom, 0xA21BC800); } @@ -241,11 +257,11 @@ wacom_reset_artpad(mouse_wacom_t *wacom) wacom->settings_bits.out_of_range_data = 0; wacom_process_settings_dword(wacom, 0xE203C000); - mouse_mode = 1; + mouse_input_mode = 1; } static void -wacom_callback(struct serial_s *serial, void *priv) +wacom_callback(UNUSED(struct serial_s *serial), void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; @@ -265,13 +281,16 @@ wacom_callback(struct serial_s *serial, void *priv) case 3: wacom->transmit_period = wacom_transmit_period(wacom, 19200, -1); break; + + default: + break; } timer_stop(&wacom->report_timer); timer_on_auto(&wacom->report_timer, wacom->transmit_period); } static void -wacom_write(struct serial_s *serial, void *priv, uint8_t data) +wacom_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; static int special_command = 0; @@ -295,6 +314,8 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data) wacom->data_rec[wacom->data_rec_pos++] = data; break; } + default: + break; } special_command = 0; return; @@ -343,8 +364,8 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data) } else if (!memcmp(wacom->data_rec, "IT", 2)) { sscanf((const char *) wacom->data_rec, "IT%d", &wacom->interval); } else if (!memcmp(wacom->data_rec, "DE", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { - sscanf((const char *) wacom->data_rec, "DE%d", &mouse_mode); - mouse_mode = !mouse_mode; + sscanf((const char *) wacom->data_rec, "DE%d", &mouse_input_mode); + mouse_input_mode = !mouse_input_mode; plat_mouse_capture(0); } else if (!memcmp(wacom->data_rec, "SU", 2)) { sscanf((const char *) wacom->data_rec, "SU%d", &wacom->suppressed_increment); @@ -403,9 +424,17 @@ wacom_write(struct serial_s *serial, void *priv, uint8_t data) } static int -wacom_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) +wacom_poll(void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; + int delta_x; + int delta_y; + int b = mouse_get_buttons_ex(); + double abs_x; + double abs_y; + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -32768, 32767, 0, 0); + mouse_get_abs_coords(&abs_x, &abs_y); if (wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) { wacom->abs_x = abs_x * 5039. * (wacom->x_res / 1000.); @@ -421,8 +450,8 @@ wacom_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) wacom->abs_x = 0; if (wacom->abs_y < 0) wacom->abs_y = 0; - wacom->rel_x = x; - wacom->rel_y = y; + wacom->rel_x = delta_x; + wacom->rel_y = delta_y; } if (wacom->b != b) wacom->oldb = wacom->b; @@ -491,7 +520,7 @@ wacom_transmit_prepare(mouse_wacom_t *wacom, int x, int y) data[1] = ((x & 0x3F80) >> 7) & 0x7F; data[0] |= (((x & 0xC000) >> 14) & 3); - if (mouse_mode == 0 && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { + if (mouse_input_mode == 0 && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { data[0] |= (!!(x < 0)) << 2; data[3] |= (!!(y < 0)) << 2; } @@ -534,7 +563,7 @@ wacom_report_timer(void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; double milisecond_diff = ((double) (tsc - wacom->old_tsc)) / cpuclock * 1000.0; - int relative_mode = (mouse_mode == 0); + int relative_mode = (mouse_input_mode == 0); int x = (relative_mode ? wacom->rel_x : wacom->abs_x); int y = (relative_mode ? wacom->rel_y : wacom->abs_y); int x_diff = abs(relative_mode ? wacom->rel_x : (wacom->abs_x - wacom->last_abs_x)); @@ -563,8 +592,8 @@ wacom_report_timer(void *priv) return; switch (wacom->mode) { - case WACOM_MODE_STREAM: default: + case WACOM_MODE_STREAM: break; case WACOM_MODE_POINT: diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c new file mode 100644 index 0000000000..165962f307 --- /dev/null +++ b/src/device/nec_mate_unk.c @@ -0,0 +1,75 @@ +/* + * 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. + * + * Implementation of the NEC Mate NX MA30D/23D Unknown Readout. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020-2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/plat_unused.h> + +static uint8_t +nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) +{ + /* Expected by this NEC machine. + + It writes something on ports 3D6C, 3D6D, and 3D6E, then expects to read + 2Ah from port 3D6D. Then it repeats this with ports 6A, 6B, and 6C. + */ + return 0x2a; +} + +static void +nec_mate_unk_close(void *priv) +{ + uint8_t *dev = (uint8_t *) priv; + + free(dev); +} + +static void * +nec_mate_unk_init(const device_t *info) +{ + /* We have to return something non-NULL. */ + uint8_t *dev = (uint8_t *) calloc(1, sizeof(uint8_t)); + + io_sethandler(0x006b, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x3d6d, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + + return dev; +} + +const device_t nec_mate_unk_device = { + .name = "NEC Mate NX MA30D/23D Unknown Readout", + .internal_name = "nec_mate_unk", + .flags = 0, + .local = 0, + .init = nec_mate_unk_init, + .close = nec_mate_unk_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index e54cdea74f..c1f5511622 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -41,20 +41,22 @@ #define AGP_BRIDGE_VIA_598 0x11068598 #define AGP_BRIDGE_VIA_691 0x11068691 #define AGP_BRIDGE_VIA_8601 0x11068601 +#define AGP_BRIDGE_SIS_5XXX 0x10390001 #define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9) #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) #define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106) -#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_ALI_M5243) +#define AGP_BRIDGE_SIS(x) (((x) >> 16) == 0x1039) +#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_SIS_5XXX) -typedef struct -{ +typedef struct pci_bridge_t { uint32_t local; - uint8_t type, ctl; + uint8_t type; + uint8_t ctl; uint8_t regs[256]; uint8_t bus_index; - int slot; + uint8_t slot; } pci_bridge_t; #ifdef ENABLE_PCI_BRIDGE_LOG @@ -134,6 +136,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) val |= 0x02; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0xc3; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x27; else val &= 0x67; break; @@ -194,7 +198,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x22: case 0x24: case 0x26: - val &= 0xf0; + val &= 0xf0; /* SiS datasheets say 0Fh for 1Ch but that's clearly an erratum since the + definition of the bits is identical to the other vendors' AGP bridges. */ break; case 0x3c: @@ -205,6 +210,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x3e: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x0c; + else if (AGP_BRIDGE_SIS(dev->local)) + val &= 0x0e; else if (dev->local == AGP_BRIDGE_ALI_M5247) val &= 0x0f; else if (dev->local == AGP_BRIDGE_ALI_M5243) @@ -352,6 +359,9 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) return; } break; + + default: + break; } dev->regs[addr] = val; @@ -360,8 +370,8 @@ 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_t *dev = (pci_bridge_t *) priv; - uint8_t ret; + const pci_bridge_t *dev = (pci_bridge_t *) priv; + uint8_t ret; if (func > 0) ret = 0xff; @@ -434,6 +444,9 @@ pci_bridge_reset(void *priv) dev->regs[0x06] = 0x20; dev->regs[0x07] = 0x02; break; + + default: + break; } /* class */ @@ -477,7 +490,6 @@ pci_bridge_init(const device_t *info) uint8_t interrupt_count; uint8_t interrupt_mask; uint8_t slot_count; - uint8_t i; pci_bridge_t *dev = (pci_bridge_t *) malloc(sizeof(pci_bridge_t)); memset(dev, 0, sizeof(pci_bridge_t)); @@ -488,24 +500,29 @@ pci_bridge_init(const device_t *info) pci_bridge_reset(dev); - dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev); + pci_add_bridge(AGP_BRIDGE(dev->local), pci_bridge_read, pci_bridge_write, dev, &dev->slot); interrupt_count = sizeof(interrupts); interrupt_mask = interrupt_count - 1; if (dev->slot < 32) { - for (i = 0; i < interrupt_count; i++) + for (uint8_t i = 0; i < interrupt_count; i++) interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); } - pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]); + pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], + interrupts[1], interrupts[2], interrupts[3]); if (info->local == PCI_BRIDGE_DEC_21150) slot_count = 9; /* 9 bus masters */ else slot_count = 1; /* AGP bridges always have 1 slot */ - for (i = 0; i < slot_count; i++) { + for (uint8_t i = 0; i < slot_count; i++) { /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ - pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]); + pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, i, interrupts[i & interrupt_mask], + interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], + interrupts[(i + 3) & interrupt_mask]); pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], @@ -658,3 +675,17 @@ const device_t via_vt8601_agp_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sis_5xxx_agp_device = { + .name = "SiS 5591/(5)600 AGP Bridge", + .internal_name = "via_5xxx_agp", + .flags = DEVICE_PCI, + .local = AGP_BRIDGE_SIS_5XXX, + .init = pci_bridge_init, + .close = NULL, + .reset = pci_bridge_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/phoenix_486_jumper.c b/src/device/phoenix_486_jumper.c index d5e833404c..a3c891c908 100644 --- a/src/device/phoenix_486_jumper.c +++ b/src/device/phoenix_486_jumper.c @@ -1,148 +1,151 @@ -/* - * 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. - * - * Implementation of the Phoenix 486 Jumper Readout - * - * - * - * Authors: Tiseno100 - * - * Copyright 2020 Tiseno100 - */ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/chipset.h> - -/* - Bit 7 = Super I/O chip: 1 = enabled, 0 = disabled; - Bit 6 = Graphics card: 1 = standalone, 0 = on-board; - Bit 5 = ???? (if 1, siren and hangs); - Bit 4 = ????; - Bit 3 = ????; - Bit 2 = ????; - Bit 1 = ????; - Bit 0 = ????. -*/ - -typedef struct -{ - uint8_t type, jumper; -} phoenix_486_jumper_t; - -#ifdef ENABLE_PHOENIX_486_JUMPER_LOG -int phoenix_486_jumper_do_log = ENABLE_PHOENIX_486_JUMPER_LOG; - -static void -phoenix_486_jumper_log(const char *fmt, ...) -{ - va_list ap; - - if (phoenix_486_jumper_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define phoenix_486_jumper_log(fmt, ...) -#endif - -static void -phoenix_486_jumper_write(uint16_t addr, uint8_t val, void *priv) -{ - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; - phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val); - if (dev->type == 1) - dev->jumper = val & 0xbf; - else - dev->jumper = val; -} - -static uint8_t -phoenix_486_jumper_read(uint16_t addr, void *priv) -{ - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; - phoenix_486_jumper_log("Phoenix 486 Jumper: Read %02x\n", dev->jumper); - return dev->jumper; -} - -static void -phoenix_486_jumper_reset(void *priv) -{ - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; - - if (dev->type == 1) - dev->jumper = 0x00; - else { - dev->jumper = 0x9f; - if (gfxcard[0] != 0x01) - dev->jumper |= 0x40; - } -} - -static void -phoenix_486_jumper_close(void *priv) -{ - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; - - free(dev); -} - -static void * -phoenix_486_jumper_init(const device_t *info) -{ - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t)); - memset(dev, 0, sizeof(phoenix_486_jumper_t)); - - dev->type = info->local; - - phoenix_486_jumper_reset(dev); - - io_sethandler(0x0078, 0x0001, phoenix_486_jumper_read, NULL, NULL, phoenix_486_jumper_write, NULL, NULL, dev); - - return dev; -} - -const device_t phoenix_486_jumper_device = { - .name = "Phoenix 486 Jumper Readout", - .internal_name = "phoenix_486_jumper", - .flags = 0, - .local = 0, - .init = phoenix_486_jumper_init, - .close = phoenix_486_jumper_close, - .reset = phoenix_486_jumper_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t phoenix_486_jumper_pci_device = { - .name = "Phoenix 486 Jumper Readout (PCI machines)", - .internal_name = "phoenix_486_jumper_pci", - .flags = 0, - .local = 1, - .init = phoenix_486_jumper_init, - .close = phoenix_486_jumper_close, - .reset = phoenix_486_jumper_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; +/* + * 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. + * + * Implementation of the Phoenix 486 Jumper Readout. + * + * + * + * Authors: Miran Grca, + * Tiseno100, + * + * Copyright 2020-2023 Miran Grca. + * Copyright 2020-2023 Tiseno100. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/plat_unused.h> + +/* + Bit 7 = Super I/O chip: 1 = enabled, 0 = disabled; + Bit 6 = Graphics card: 1 = standalone, 0 = on-board; + Bit 5 = ???? (if 1, siren and hangs); + Bit 4 = ????; + Bit 3 = ????; + Bit 2 = ????; + Bit 1 = ????; + Bit 0 = ????. +*/ + +typedef struct phoenix_486_jumper_t { + uint8_t type; + uint8_t jumper; +} phoenix_486_jumper_t; + +#ifdef ENABLE_PHOENIX_486_JUMPER_LOG +int phoenix_486_jumper_do_log = ENABLE_PHOENIX_486_JUMPER_LOG; + +static void +phoenix_486_jumper_log(const char *fmt, ...) +{ + va_list ap; + + if (phoenix_486_jumper_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define phoenix_486_jumper_log(fmt, ...) +#endif + +static void +phoenix_486_jumper_write(UNUSED(uint16_t addr), uint8_t val, void *priv) +{ + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; + phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val); + if (dev->type == 1) + dev->jumper = val & 0xbf; + else + dev->jumper = val; +} + +static uint8_t +phoenix_486_jumper_read(UNUSED(uint16_t addr), void *priv) +{ + const phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; + + phoenix_486_jumper_log("Phoenix 486 Jumper: Read %02x\n", dev->jumper); + return dev->jumper; +} + +static void +phoenix_486_jumper_reset(void *priv) +{ + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; + + if (dev->type == 1) + dev->jumper = 0x00; + else { + dev->jumper = 0x9f; + if (gfxcard[0] != 0x01) + dev->jumper |= 0x40; + } +} + +static void +phoenix_486_jumper_close(void *priv) +{ + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; + + free(dev); +} + +static void * +phoenix_486_jumper_init(const device_t *info) +{ + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t)); + memset(dev, 0, sizeof(phoenix_486_jumper_t)); + + dev->type = info->local; + + phoenix_486_jumper_reset(dev); + + io_sethandler(0x0078, 0x0001, phoenix_486_jumper_read, NULL, NULL, phoenix_486_jumper_write, NULL, NULL, dev); + + return dev; +} + +const device_t phoenix_486_jumper_device = { + .name = "Phoenix 486 Jumper Readout", + .internal_name = "phoenix_486_jumper", + .flags = 0, + .local = 0, + .init = phoenix_486_jumper_init, + .close = phoenix_486_jumper_close, + .reset = phoenix_486_jumper_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t phoenix_486_jumper_pci_device = { + .name = "Phoenix 486 Jumper Readout (PCI machines)", + .internal_name = "phoenix_486_jumper_pci", + .flags = 0, + .local = 1, + .init = phoenix_486_jumper_init, + .close = phoenix_486_jumper_close, + .reset = phoenix_486_jumper_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/postcard.c b/src/device/postcard.c index 8475f76fcb..dbae3232a1 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -29,11 +29,13 @@ #include <86box/postcard.h> #include "cpu.h" +uint8_t postcard_codes[POSTCARDS_NUM]; + static uint16_t postcard_port; -static uint8_t postcard_written; -static uint8_t postcard_code; -static uint8_t postcard_prev_code; -#define UISTR_LEN 13 +static uint8_t postcard_written[POSTCARDS_NUM]; +static uint8_t postcard_ports_num = 1; +static uint8_t postcard_prev_codes[POSTCARDS_NUM]; +#define UISTR_LEN 32 static char postcard_str[UISTR_LEN]; /* UI output string */ extern void ui_sb_bugui(char *__str); @@ -61,12 +63,48 @@ int postcard_do_log = 0; static void postcard_setui(void) { - if (!postcard_written) - sprintf(postcard_str, "POST: -- --"); - else if (postcard_written == 1) - sprintf(postcard_str, "POST: %02X --", postcard_code); - else - sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code); + if (postcard_ports_num > 1) { + char ps[2][POSTCARDS_NUM][3] = { { { 0 }, + { 0 }, + } }; + + for (uint8_t i = 0; i < POSTCARDS_NUM; i++) { + if (!postcard_written[i]) { + snprintf(ps[0][i], sizeof(ps[0][i]), "--"); + snprintf(ps[1][i], sizeof(ps[1][i]), "--"); + } else if (postcard_written[i] == 1) { + snprintf(ps[0][i], sizeof(ps[0][i]), "%02X", postcard_codes[i]); + snprintf(ps[1][i], sizeof(ps[1][i]), "--"); + } else { + snprintf(ps[0][i], sizeof(ps[0][i]), "%02X", postcard_codes[i]); + snprintf(ps[1][i], sizeof(ps[1][i]), "%02X", postcard_prev_codes[i]); + } + } + + switch (postcard_ports_num) { + default: + case 2: + snprintf(postcard_str, sizeof(postcard_str), "POST: %s%s %s%s", + ps[0][0], ps[0][1], ps[1][0], ps[1][1]); + break; + case 3: + snprintf(postcard_str, sizeof(postcard_str), "POST: %s/%s%s %s/%s%s", + ps[0][0], ps[0][1], ps[0][2], ps[1][0], ps[1][1], ps[1][2]); + break; + case 4: + snprintf(postcard_str, sizeof(postcard_str), "POST: %s%s/%s%s %s%s/%s%s", + ps[0][0], ps[0][1], ps[0][2], ps[0][3], + ps[1][0], ps[1][1], ps[1][2], ps[1][3]); + break; + } + } else { + if (!postcard_written[0]) + snprintf(postcard_str, sizeof(postcard_str), "POST: -- --"); + else if (postcard_written[0] == 1) + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --", postcard_codes[0]); + else + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]); + } ui_sb_bugui(postcard_str); @@ -79,30 +117,33 @@ postcard_setui(void) static void postcard_reset(void) { - postcard_written = 0; - postcard_code = postcard_prev_code = 0x00; + memset(postcard_written, 0x00, POSTCARDS_NUM * sizeof(uint8_t)); + + memset(postcard_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t)); + memset(postcard_prev_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t)); postcard_setui(); } static void -postcard_write(uint16_t port, uint8_t val, void *priv) +postcard_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { - if (postcard_written && (val == postcard_code)) + if (postcard_written[port & POSTCARD_MASK] && + (val == postcard_codes[port & POSTCARD_MASK])) return; - postcard_prev_code = postcard_code; - postcard_code = val; - if (postcard_written < 2) - postcard_written++; + postcard_prev_codes[port & POSTCARD_MASK] = postcard_codes[port & POSTCARD_MASK]; + postcard_codes[port & POSTCARD_MASK] = val; + if (postcard_written[port & POSTCARD_MASK] < 2) + postcard_written[port & POSTCARD_MASK]++; postcard_setui(); } static void * -postcard_init(const device_t *info) +postcard_init(UNUSED(const device_t *info)) { - postcard_reset(); + postcard_ports_num = 1; if (machine_has_bus(machine, MACHINE_BUS_MCA)) postcard_port = 0x680; /* MCA machines */ @@ -110,16 +151,21 @@ postcard_init(const device_t *info) postcard_port = 0x190; /* ISA PS/2 machines */ else if (strstr(machines[machine].name, " IBM XT ")) postcard_port = 0x60; /* IBM XT */ - else if (strstr(machines[machine].name, " IBM PCjr")) + else if (strstr(machines[machine].name, " IBM PCjr")) { postcard_port = 0x10; /* IBM PCjr */ - else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI)) + postcard_ports_num = 3; /* IBM PCjr error ports 11h and 12h */ + } else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI)) postcard_port = 0x84; /* ISA Compaq machines */ + else if (strstr(machines[machine].name, "Olivetti")) + postcard_port = 0x378; /* Olivetti machines */ else postcard_port = 0x80; /* AT and clone machines */ postcard_log("POST card initializing on port %04Xh\n", postcard_port); + postcard_reset(); + if (postcard_port) - io_sethandler(postcard_port, 1, + io_sethandler(postcard_port, postcard_ports_num, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); return postcard_write; @@ -129,7 +175,7 @@ static void postcard_close(UNUSED(void *priv)) { if (postcard_port) - io_removehandler(postcard_port, 1, + io_removehandler(postcard_port, postcard_ports_num, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); } diff --git a/src/device/serial.c b/src/device/serial.c index bc4b3053d3..37aadf8fec 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -12,11 +12,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ @@ -35,23 +33,28 @@ #include <86box/pic.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/fifo.h> #include <86box/serial.h> #include <86box/mouse.h> serial_port_t com_ports[SERIAL_MAX]; enum { - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8, - SERIAL_INT_TIMEOUT = 16 + SERIAL_INT_LSR = 1, + SERIAL_INT_TIMEOUT = 2, + SERIAL_INT_RECEIVE = 4, + SERIAL_INT_TRANSMIT = 8, + SERIAL_INT_MSR = 16, + SERIAL_INT_RX_DMA_TC = 32, + SERIAL_INT_TX_DMA_TC = 64 }; +void serial_update_ints(serial_t *dev); + static int next_inst = 0; static serial_device_t serial_devices[SERIAL_MAX]; -// #define ENABLE_SERIAL_CONSOLE 1 +static void serial_xmit_d_empty_evt(void *priv); #ifdef ENABLE_SERIAL_LOG int serial_do_log = ENABLE_SERIAL_LOG; @@ -74,16 +77,25 @@ serial_log(const char *fmt, ...) void serial_reset_port(serial_t *dev) { + if (dev->type >= SERIAL_16550) { + if (dev->fifo_enabled) + fifo_reset_evt(dev->xmit_fifo); + else + fifo_reset(dev->xmit_fifo); + } + dev->lsr = 0x60; /* Mark that both THR/FIFO and TXSR are empty. */ dev->iir = dev->ier = dev->lcr = dev->fcr = 0; + dev->fifo_enabled = 0; - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->xmit_fifo_end = dev->rcvr_fifo_end = 0; - dev->rcvr_fifo_full = 0; - dev->baud_cycles = 0; - dev->out_new = 0xffff; - memset(dev->xmit_fifo, 0, 16); - memset(dev->rcvr_fifo, 0, 16); + dev->baud_cycles = 0; + dev->out_new = 0xffff; + + dev->txsr_empty = 1; + dev->thr_empty = 1; + + serial_update_ints(dev); + dev->irq_state = 0; } void @@ -102,42 +114,35 @@ serial_transmit_period(serial_t *dev) dev->sd->transmit_period_callback(dev, dev->sd->priv, dev->transmit_period); } +void +serial_do_irq(serial_t *dev, int set) +{ + if (dev->irq != 0xff) { + if (set || (dev->irq_state != !!set)) + picint_common(1 << dev->irq, !!(dev->type >= SERIAL_16450), set, &dev->irq_state); + if (dev->type < SERIAL_16450) + dev->irq_state = !!set; + } +} + void serial_update_ints(serial_t *dev) { - int stat = 0; - - dev->iir = 1; - - if ((dev->ier & 4) && (dev->int_status & SERIAL_INT_LSR)) { - /* Line status interrupt */ - stat = 1; - dev->iir = 6; - } else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_TIMEOUT)) { - /* Received data available */ - stat = 1; - dev->iir = 0x0c; - } else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_RECEIVE)) { - /* Received data available */ - stat = 1; - dev->iir = 4; - } else if ((dev->ier & 2) && (dev->int_status & SERIAL_INT_TRANSMIT)) { - /* Transmit data empty */ - stat = 1; - dev->iir = 2; - } else if ((dev->ier & 8) && (dev->int_status & SERIAL_INT_MSR)) { - /* Modem status interrupt */ - stat = 1; - dev->iir = 0; + /* TODO: The IRQ priorities are 6 - we need to find a way to treat timeout and receive + as equal and still somehow distinguish them. */ + uint8_t ier_map[7] = { 0x04, 0x01, 0x01, 0x02, 0x08, 0x40, 0x80 }; + uint8_t iir_map[7] = { 0x06, 0x0c, 0x04, 0x02, 0x00, 0x0e, 0x0a }; + + dev->iir = (dev->iir & 0xf0) | 0x01; + + for (uint8_t i = 0; i < 7; i++) { + if ((dev->ier & ier_map[i]) && (dev->int_status & (1 << i))) { + dev->iir = (dev->iir & 0xf0) | iir_map[i]; + break; + } } - if (stat && (dev->irq != 0xff) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))) { - if (dev->type >= SERIAL_16450) - picintlevel(1 << dev->irq); - else - picint(1 << dev->irq); - } else - picintc(1 << dev->irq); + serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))); } static void @@ -154,56 +159,48 @@ serial_receive_timer(void *priv) { serial_t *dev = (serial_t *) priv; - // serial_log("serial_receive_timer()\n"); + serial_log("serial_receive_timer()\n"); timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period); - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { + if (dev->fifo_enabled) { /* FIFO mode. */ - if (dev->out_new != 0xffff) { /* We have received a byte into the RSR. */ /* Clear FIFO timeout. */ serial_clear_timeout(dev); - if (dev->rcvr_fifo_full) { - /* Overrun - just discard the byte in the RSR. */ - serial_log("FIFO overrun\n"); - dev->lsr |= 0x02; - } else { - /* We can input data into the FIFO. */ - dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff); - // dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f; - /* Do not wrap around, makes sure it still triggers the interrupt - at 16 bytes. */ - dev->rcvr_fifo_end++; - - serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff), - abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos), - dev->rcvr_fifo_end, dev->rcvr_fifo_pos); - dev->out_new = 0xffff; + fifo_write_evt((uint8_t) (dev->out_new & 0xff), dev->rcvr_fifo); + dev->out_new = 0xffff; - if (abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos) >= dev->rcvr_fifo_len) { - /* We have >= trigger level bytes, raise Data Ready interrupt. */ - serial_log("We have >= %i bytes in the FIFO, data ready!\n", dev->rcvr_fifo_len); - dev->lsr |= 0x01; - dev->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } +#if 0 + pclog("serial_receive_timer(): lsr = %02X, ier = %02X, iir = %02X, int_status = %02X\n", + dev->lsr, dev->ier, dev->iir, dev->int_status); +#endif + + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } + } else { + /* Non-FIFO mode. */ + if (dev->out_new != 0xffff) { + /* We have received a byte into the RSR. */ + serial_log("Byte received: %04X\n", dev->out_new); - /* Now wrap around. */ - dev->rcvr_fifo_end &= 0x0f; + /* Indicate overrun. */ + if (dev->lsr & 0x01) + dev->lsr |= 0x02; - if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos) - dev->rcvr_fifo_full = 1; + dev->dat = (uint8_t) (dev->out_new & 0xff); + dev->out_new = 0xffff; - timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); - } + /* Raise Data Ready interrupt. */ + dev->lsr |= 0x01; + dev->int_status |= SERIAL_INT_RECEIVE; + + serial_update_ints(dev); } } - - serial_update_ints(dev); } static void @@ -211,26 +208,8 @@ write_fifo(serial_t *dev, uint8_t dat) { serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, - ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? (dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { - /* FIFO mode. */ - - /* This is the first phase, we are sending the data to the RSR (Receiver Shift - Register), from where it's going to get dispatched to the FIFO. */ - } else { - /* Non-FIFO mode. */ - - /* Indicate overrun. */ - if (dev->lsr & 0x01) - dev->lsr |= 0x02; - - /* Raise Data Ready interrupt. */ - serial_log("To RHR: %02X\n", dat); - dev->lsr |= 0x01; - dev->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } + ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? + fifo_get_count(dev->rcvr_fifo) : 0); /* Do this here, because in non-FIFO mode, this is read directly. */ dev->out_new = (uint16_t) dat; @@ -239,7 +218,10 @@ write_fifo(serial_t *dev, uint8_t dat) void serial_write_fifo(serial_t *dev, uint8_t dat) { - serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); + serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, + (dev->type >= SERIAL_16550) && dev->fifo_enabled, + ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? + fifo_get_count(dev->rcvr_fifo) : 0); if (!(dev->mctrl & 0x10)) write_fifo(dev, dat); @@ -252,48 +234,43 @@ serial_transmit(serial_t *dev, uint8_t val) write_fifo(dev, val); else if (dev->sd->dev_write) dev->sd->dev_write(dev, dev->sd->priv, val); + #ifdef ENABLE_SERIAL_CONSOLE if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') { fputc(val, stdout); if (val == '\n') fflush(stdout); - } else { + } else fprintf(stdout, "[%02X]", val); - } #endif } static void serial_move_to_txsr(serial_t *dev) { - if (dev->fifo_enabled) { - dev->txsr = dev->xmit_fifo[0]; - if (dev->xmit_fifo_pos > 0) { - /* Move the entire fifo forward by one byte. */ - for (uint8_t i = 1; i < 16; i++) - dev->xmit_fifo[i - 1] = dev->xmit_fifo[i]; - /* Decrease FIFO position. */ - dev->xmit_fifo_pos--; - } - } else { + dev->txsr_empty = 0; + if (dev->fifo_enabled) + dev->txsr = fifo_read_evt(dev->xmit_fifo); + else { dev->txsr = dev->thr; dev->thr = 0; + dev->thr_empty = 1; + serial_xmit_d_empty_evt(dev); } dev->lsr &= ~0x40; - serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", dev->xmit_fifo_pos & 0x0f); + serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", + fifo_get_count(dev->xmit_fifo) & 0x0f); - if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) { + if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) { /* Update interrupts to signal THRE and that TXSR is no longer empty. */ - dev->lsr |= 0x20; - dev->int_status |= SERIAL_INT_TRANSMIT; serial_update_ints(dev); } if (dev->transmit_enabled & 2) dev->baud_cycles++; else dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */ - if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) + if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) dev->transmit_enabled &= ~1; /* Stop moving. */ dev->transmit_enabled |= 2; /* Start transmitting. */ } @@ -304,20 +281,18 @@ serial_process_txsr(serial_t *dev) serial_log("serial_process_txsr(): FIFO %sabled\n", dev->fifo_enabled ? "en" : "dis"); serial_transmit(dev, dev->txsr); dev->txsr = 0; + dev->txsr_empty = 1; + serial_xmit_d_empty_evt(dev); /* Reset BAUDOUT cycle count. */ dev->baud_cycles = 0; /* If FIFO is enabled and there are bytes left to transmit, continue with the FIFO, otherwise stop. */ - if (dev->fifo_enabled && (dev->xmit_fifo_pos != 0x0)) + if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) != 0x0)) dev->transmit_enabled |= 1; - else { - /* Both FIFO/THR and TXSR are empty. */ - /* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */ - if (dev->lsr & 0x20) - dev->lsr |= 0x40; + /* Both FIFO/THR and TXSR are empty. */ + else dev->transmit_enabled &= ~2; - } - dev->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(dev); } @@ -357,9 +332,7 @@ serial_timeout_timer(void *priv) { serial_t *dev = (serial_t *) priv; -#ifdef ENABLE_SERIAL_LOG serial_log("serial_timeout_timer()\n"); -#endif dev->lsr |= 0x01; dev->int_status |= SERIAL_INT_TIMEOUT; @@ -371,9 +344,7 @@ serial_device_timeout(void *priv) { serial_t *dev = (serial_t *) priv; -#ifdef ENABLE_SERIAL_LOG serial_log("serial_device_timeout()\n"); -#endif if (!dev->fifo_enabled) { dev->lsr |= 0x10; @@ -385,23 +356,23 @@ serial_device_timeout(void *priv) static void serial_update_speed(serial_t *dev) { + serial_log("serial_update_speed(%lf)\n", dev->transmit_period); timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period); if (dev->transmit_enabled & 3) timer_on_auto(&dev->transmit_timer, dev->transmit_period); - if (timer_is_enabled(&dev->timeout_timer)) + if (timer_is_on(&dev->timeout_timer)) timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); } static void serial_reset_fifo(serial_t *dev) { - dev->lsr = (dev->lsr & 0xfe) | 0x60; - dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | SERIAL_INT_TRANSMIT; + fifo_reset_evt(dev->xmit_fifo); + fifo_reset_evt(dev->rcvr_fifo); + serial_update_ints(dev); - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; } void @@ -471,13 +442,12 @@ serial_set_clock_src(serial_t *dev, double clock_src) } void -serial_write(uint16_t addr, uint8_t val, void *p) +serial_write(uint16_t addr, uint8_t val, void *priv) { - serial_t *dev = (serial_t *) p; + serial_t *dev = (serial_t *) priv; uint8_t new_msr; uint8_t old; - // serial_log("UART: Write %02X to port %02X\n", val, addr); serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr); cycles -= ISA_CYCLES(8); @@ -491,21 +461,22 @@ serial_write(uint16_t addr, uint8_t val, void *p) return; } - /* Indicate FIFO/THR is no longer empty. */ - dev->lsr &= 0x9f; - dev->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(dev); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) { + if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) < 16)) { /* FIFO mode, begin transmitting. */ timer_on_auto(&dev->transmit_timer, dev->transmit_period); dev->transmit_enabled |= 1; /* Start moving. */ - dev->xmit_fifo[dev->xmit_fifo_pos++] = val; - } else { + fifo_write_evt(val, dev->xmit_fifo); + } else if (!dev->fifo_enabled) { + /* Indicate THR is no longer empty. */ + dev->lsr &= 0x9f; + dev->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(dev); + /* Non-FIFO mode, begin transmitting. */ timer_on_auto(&dev->transmit_timer, dev->transmit_period); dev->transmit_enabled |= 1; /* Start moving. */ dev->thr = val; + dev->thr_empty = 0; } break; case 1: @@ -526,40 +497,45 @@ serial_write(uint16_t addr, uint8_t val, void *p) serial_reset_fifo(dev); dev->fcr = val & 0xf9; dev->fifo_enabled = val & 0x01; + /* TODO: When switching modes, shouldn't we reset the LSR + based on the new conditions? */ if (!dev->fifo_enabled) { - memset(dev->rcvr_fifo, 0, 14); - memset(dev->xmit_fifo, 0, 16); - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; - dev->rcvr_fifo_len = 1; + fifo_reset(dev->xmit_fifo); + fifo_reset(dev->rcvr_fifo); break; } if (val & 0x02) { - memset(dev->rcvr_fifo, 0, 14); - dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_end = 0; - dev->rcvr_fifo_full = 0; + if (dev->fifo_enabled) + fifo_reset_evt(dev->rcvr_fifo); + else + fifo_reset(dev->rcvr_fifo); } if (val & 0x04) { - memset(dev->xmit_fifo, 0, 16); - dev->xmit_fifo_pos = 0; + if (dev->fifo_enabled) + fifo_reset_evt(dev->xmit_fifo); + else + fifo_reset(dev->xmit_fifo); } switch ((val >> 6) & 0x03) { case 0: - dev->rcvr_fifo_len = 1; + fifo_set_trigger_len(dev->rcvr_fifo, 1); break; case 1: - dev->rcvr_fifo_len = 4; + fifo_set_trigger_len(dev->rcvr_fifo, 4); break; case 2: - dev->rcvr_fifo_len = 8; + fifo_set_trigger_len(dev->rcvr_fifo, 8); break; case 3: - dev->rcvr_fifo_len = 14; + fifo_set_trigger_len(dev->rcvr_fifo, 14); + break; + + default: break; } + fifo_set_trigger_len(dev->xmit_fifo, 16); dev->out_new = 0xffff; - serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len); + serial_log("FIFO now %sabled\n", dev->fifo_enabled ? "en" : "dis"); } break; case 3: @@ -585,11 +561,13 @@ serial_write(uint16_t addr, uint8_t val, void *p) break; case 4: if ((val & 2) && !(dev->mctrl & 2)) { - if (dev->sd && dev->sd->rcr_callback) + if (dev->sd && dev->sd->rcr_callback) { + serial_log("RTS toggle callback\n"); dev->sd->rcr_callback(dev, dev->sd->priv); + } } if (!(val & 8) && (dev->mctrl & 8)) - picintc(1 << dev->irq); + serial_do_irq(dev, 0); if ((val ^ dev->mctrl) & 0x10) serial_reset_fifo(dev); dev->mctrl = val; @@ -609,8 +587,9 @@ serial_write(uint16_t addr, uint8_t val, void *p) dev->msr = new_msr; - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; + /* TODO: Why reset the FIFO's here?! */ + fifo_reset(dev->xmit_fifo); + fifo_reset(dev->rcvr_fifo); } break; case 5: @@ -624,8 +603,10 @@ serial_write(uint16_t addr, uint8_t val, void *p) serial_update_ints(dev); break; case 6: - // dev->msr = (val & 0xf0) | (dev->msr & 0x0f); - // dev->msr = val; +#if 0 + dev->msr = (val & 0xf0) | (dev->msr & 0x0f); + dev->msr = val; +#endif /* The actual condition bits of the MSR are read-only, but the delta bits are undocumentedly writable, and the PCjr BIOS uses them to raise MSR interrupts. */ dev->msr = (dev->msr & 0xf0) | (val & 0x0f); @@ -637,13 +618,15 @@ serial_write(uint16_t addr, uint8_t val, void *p) if (dev->type >= SERIAL_16450) dev->scratch = val; break; + default: + break; } } uint8_t -serial_read(uint16_t addr, void *p) +serial_read(uint16_t addr, void *priv) { - serial_t *dev = (serial_t *) p; + serial_t *dev = (serial_t *) priv; uint8_t ret = 0; cycles -= ISA_CYCLES(8); @@ -655,41 +638,16 @@ serial_read(uint16_t addr, void *p) break; } - /* Clear timeout. */ - serial_clear_timeout(dev); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { + if (dev->fifo_enabled) { /* FIFO mode. */ + serial_clear_timeout(dev); + ret = fifo_read_evt(dev->rcvr_fifo); - if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) { - /* There is data in the FIFO. */ - ret = dev->rcvr_fifo[dev->rcvr_fifo_pos]; - dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f; - - /* Make sure to clear the FIFO full condition. */ - dev->rcvr_fifo_full = 0; - - if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) { - /* Amount of data in the FIFO below trigger level, - clear Data Ready interrupt. */ - dev->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } - - /* Make sure the Data Ready bit of the LSR is set if we still have - bytes left in the FIFO. */ - if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) { - dev->lsr |= 0x01; - /* There are bytes left in the FIFO, activate the FIFO Timeout timer. */ - timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); - } else - dev->lsr &= 0xfe; - } + if (dev->lsr & 0x01) + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); } else { /* Non-FIFO mode. */ - - ret = (uint8_t) (dev->out_new & 0xffff); - dev->out_new = 0xffff; + ret = dev->dat; /* Always clear Data Ready interrupt. */ dev->lsr &= 0xfe; @@ -697,7 +655,7 @@ serial_read(uint16_t addr, void *p) serial_update_ints(dev); } - // serial_log("Read data: %02X\n", ret); + serial_log("Read data: %02X\n", ret); break; case 1: if (dev->lcr & 0x80) @@ -736,9 +694,10 @@ serial_read(uint16_t addr, void *p) case 7: ret = dev->scratch; break; + default: + break; } - // serial_log("UART: Read %02X from port %02X\n", ret, addr); serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr); return ret; } @@ -780,29 +739,48 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq) dev->irq = irq; } -serial_t * -serial_attach(int port, - void (*rcr_callback)(struct serial_s *serial, void *p), - void (*dev_write)(struct serial_s *serial, void *p, uint8_t data), - void *priv) +static void +serial_rcvr_d_empty_evt(void *priv) { - serial_device_t *sd = &serial_devices[port]; + serial_t *dev = (serial_t *) priv; - sd->rcr_callback = rcr_callback; - sd->dev_write = dev_write; - sd->transmit_period_callback = NULL; - sd->lcr_callback = NULL; - sd->priv = priv; + dev->lsr = (dev->lsr & 0xfe) | (fifo_get_empty(dev->rcvr_fifo) ? 0 : 1); +} - return sd->serial; +static void +serial_rcvr_d_overrun_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1); +} + +static void +serial_rcvr_d_ready_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(dev); +} + +static void +serial_xmit_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + uint8_t is_empty = dev->fifo_enabled ? fifo_get_empty(dev->xmit_fifo) : dev->thr_empty; + + dev->lsr = (dev->lsr & 0x9f) | (is_empty << 5) | ((dev->txsr_empty && is_empty) << 6); + dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | (is_empty ? SERIAL_INT_TRANSMIT : 0); } serial_t * serial_attach_ex(int port, - void (*rcr_callback)(struct serial_s *serial, void *p), - void (*dev_write)(struct serial_s *serial, void *p, uint8_t data), - void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period), - void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t data_bits), + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period), + void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t data_bits), void *priv) { serial_device_t *sd = &serial_devices[port]; @@ -831,6 +809,9 @@ serial_close(void *priv) next_inst--; + if (com_ports[dev->inst].enabled) + fifo_close(dev->rcvr_fifo); + free(dev); } @@ -839,27 +820,33 @@ serial_reset(void *priv) { serial_t *dev = (serial_t *) priv; - timer_disable(&dev->transmit_timer); - timer_disable(&dev->timeout_timer); - timer_disable(&dev->receive_timer); + if (com_ports[dev->inst].enabled) { + timer_disable(&dev->transmit_timer); + timer_disable(&dev->timeout_timer); + timer_disable(&dev->receive_timer); - dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00; - dev->iir = dev->ier = dev->lcr = dev->msr = 0x00; - dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00; - dev->fifo_enabled = dev->rcvr_fifo_len = dev->bits = dev->data_bits = 0x00; - dev->baud_cycles = dev->rcvr_fifo_full = dev->txsr = dev->out = 0x00; + dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00; + dev->iir = dev->ier = dev->lcr = dev->msr = 0x00; + dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00; + dev->fifo_enabled = dev->bits = 0x000; + dev->data_bits = dev->baud_cycles = 0x00; + dev->txsr = 0x00; + dev->txsr_empty = 0x01; + dev->thr_empty = 0x0001; - dev->dlab = dev->out_new = 0x0000; + dev->dlab = dev->out_new = 0x0000; - dev->rcvr_fifo_pos = dev->xmit_fifo_pos = dev->rcvr_fifo_end = dev->xmit_fifo_end = 0x00; + if (dev->rcvr_fifo != NULL) + fifo_reset(dev->rcvr_fifo); - serial_reset_port(dev); + serial_reset_port(dev); - dev->dlab = 96; - dev->fcr = 0x06; + dev->dlab = 96; + dev->fcr = 0x06; - serial_transmit_period(dev); - serial_update_speed(dev); + serial_transmit_period(dev); + serial_update_speed(dev); + } } static void * @@ -876,7 +863,6 @@ serial_init(const device_t *info) memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t)); dev->sd = &(serial_devices[next_inst]); dev->sd->serial = dev; - serial_reset_port(dev); if (next_inst == 3) serial_setup(dev, COM4_ADDR, COM4_IRQ); else if (next_inst == 2) @@ -898,6 +884,22 @@ serial_init(const device_t *info) timer_add(&dev->receive_timer, serial_receive_timer, dev, 0); serial_transmit_period(dev); serial_update_speed(dev); + + dev->rcvr_fifo = fifo64_init(); + fifo_set_priv(dev->rcvr_fifo, dev); + fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt); + fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt); + fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt); + fifo_reset_evt(dev->rcvr_fifo); + fifo_set_len(dev->rcvr_fifo, 16); + + dev->xmit_fifo = fifo64_init(); + fifo_set_priv(dev->xmit_fifo, dev); + fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt); + fifo_reset_evt(dev->xmit_fifo); + fifo_set_len(dev->xmit_fifo, 16); + + serial_reset_port(dev); } next_inst++; @@ -914,7 +916,7 @@ serial_set_next_inst(int ni) void serial_standalone_init(void) { - for (; next_inst < SERIAL_MAX;) + while (next_inst < SERIAL_MAX) device_add_inst(&ns8250_device, next_inst + 1); }; diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index 441d3e339e..1b1c5e3bf3 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -25,10 +25,12 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/fifo.h> #include <86box/timer.h> #include <86box/serial.h> #include <86box/serial_passthrough.h> #include <86box/plat_serial_passthrough.h> +#include <86box/plat_unused.h> #define ENABLE_SERIAL_PASSTHROUGH_LOG 1 #ifdef ENABLE_SERIAL_PASSTHROUGH_LOG @@ -61,7 +63,7 @@ serial_passthrough_init(void) } static void -serial_passthrough_write(serial_t *s, void *priv, uint8_t val) +serial_passthrough_write(UNUSED(serial_t *s), void *priv, uint8_t val) { plat_serpt_write(priv, val); } @@ -77,7 +79,7 @@ host_to_serial_cb(void *priv) * can never fetch the bytes in time, so check if the fifo is full if in * fifo mode or if lsr has bit 0 set if not in fifo mode */ if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { - if (dev->serial->rcvr_fifo_full) { + if (fifo_get_full(dev->serial->rcvr_fifo)) { goto no_write_to_machine; } } else { @@ -86,44 +88,58 @@ host_to_serial_cb(void *priv) } } if (plat_serpt_read(dev, &byte)) { - // printf("got byte %02X\n", byte); +#if 0 + printf("got byte %02X\n", byte); +#endif serial_write_fifo(dev->serial, byte); - // serial_set_dsr(dev->serial, 1); +#if 0 + serial_set_dsr(dev->serial, 1); +#endif } no_write_to_machine: - // serial_device_timeout(dev->serial); +#if 0 + serial_device_timeout(dev->serial); +#endif timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) dev->bits); } static void -serial_passthrough_rcr_cb(struct serial_s *serial, void *priv) +serial_passthrough_rcr_cb(UNUSED(struct serial_s *serial), void *priv) { serial_passthrough_t *dev = (serial_passthrough_t *) priv; timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) dev->bits); - // serial_clear_fifo(dev->serial); +#if 0 + serial_clear_fifo(dev->serial); +#endif } static void serial_passthrough_speed_changed(void *priv) { serial_passthrough_t *dev = (serial_passthrough_t *) priv; + if (!dev) + return; timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / dev->baudrate) * (double) dev->bits); - // serial_clear_fifo(dev->serial); +#if 0 + serial_clear_fifo(dev->serial); +#endif } static void serial_passthrough_dev_close(void *priv) { serial_passthrough_t *dev = (serial_passthrough_t *) priv; + if (!dev) + return; /* Detach passthrough device from COM port */ - if (dev && dev->serial && dev->serial->sd) + if (dev->serial && dev->serial->sd) memset(dev->serial->sd, 0, sizeof(serial_device_t)); plat_serpt_close(dev); @@ -131,28 +147,28 @@ serial_passthrough_dev_close(void *priv) } void -serial_passthrough_transmit_period(serial_t *serial, void *p, double transmit_period) +serial_passthrough_transmit_period(UNUSED(serial_t *serial), void *priv, double transmit_period) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode != SERPT_MODE_HOSTSER) return; dev->baudrate = 1000000.0 / transmit_period; - serial_passthrough_speed_changed(p); + serial_passthrough_speed_changed(priv); plat_serpt_set_params(dev); } void -serial_passthrough_lcr_callback(serial_t *serial, void *p, uint8_t lcr) +serial_passthrough_lcr_callback(serial_t *serial, void *priv, uint8_t lcr) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode != SERPT_MODE_HOSTSER) return; dev->bits = serial->bits; dev->data_bits = ((lcr & 0x03) + 5); - serial_passthrough_speed_changed(p); + serial_passthrough_speed_changed(priv); plat_serpt_set_params(dev); } @@ -173,6 +189,10 @@ serial_passthrough_dev_init(const device_t *info) /* Attach passthrough device to a COM port */ dev->serial = serial_attach_ex(dev->port, serial_passthrough_rcr_cb, serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev); + if (!dev->serial) { + free(dev); + return NULL; + } strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023); #ifdef _WIN32 @@ -350,12 +370,12 @@ static const device_config_t serial_passthrough_config[] = { // clang-format on const device_t serial_passthrough_device = { - .name = "Serial Passthrough Device", - .flags = 0, - .local = 0, - .init = serial_passthrough_dev_init, - .close = serial_passthrough_dev_close, - .reset = NULL, + .name = "Serial Passthrough Device", + .flags = 0, + .local = 0, + .init = serial_passthrough_dev_init, + .close = serial_passthrough_dev_close, + .reset = NULL, { .poll = NULL }, .speed_changed = serial_passthrough_speed_changed, .force_redraw = NULL, diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 9ca89456a2..349de470db 100644 --- a/src/device/smbus_ali7101.c +++ b/src/device/smbus_ali7101.c @@ -28,6 +28,7 @@ #include <86box/timer.h> #include <86box/i2c.h> #include <86box/smbus.h> +#include <86box/plat_fallthrough.h> #ifdef ENABLE_SMBUS_ALI7101_LOG int smbus_ali7101_do_log = ENABLE_SMBUS_ALI7101_LOG; @@ -79,6 +80,9 @@ smbus_ali7101_read(uint16_t addr, void *priv) case 0x07: ret = dev->cmd; break; + + default: + break; } smbus_ali7101_log("SMBus ALI7101: read(%02X) = %02x\n", addr, ret); @@ -189,8 +193,7 @@ smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) case 0x4: /* block R/W */ timer_bytes++; /* count the SMBus length byte now */ - - /* fall-through */ + fallthrough; default: /* unknown */ dev->next_stat = 0x20; /* raise DEV_ERR */ @@ -223,6 +226,9 @@ smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) case 0x07: dev->cmd = val; break; + + default: + break; } if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */ diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 670a9adf45..6f2b1632e4 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -27,6 +27,7 @@ #include <86box/timer.h> #include <86box/i2c.h> #include <86box/smbus.h> +#include <86box/plat_fallthrough.h> #ifdef ENABLE_SMBUS_PIIX4_LOG int smbus_piix4_do_log = ENABLE_SMBUS_PIIX4_LOG; @@ -83,6 +84,9 @@ smbus_piix4_read(uint16_t addr, void *priv) if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) dev->index = 0; break; + + default: + break; } smbus_piix4_log("SMBus PIIX4: read(%02X) = %02x\n", addr, ret); @@ -191,8 +195,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) i2c_write(i2c_smbus, smbus_addr, dev->cmd); timer_bytes++; } - - /* fall-through */ + fallthrough; case 0xc: /* I2C process call */ if (!read) { /* word write (only when writing) */ @@ -210,8 +213,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) case 0x5: /* block R/W */ timer_bytes++; /* count the SMBus length byte now */ - - /* fall-through */ + fallthrough; case 0xd: /* I2C block R/W */ i2c_write(i2c_smbus, smbus_addr, dev->cmd); @@ -243,8 +245,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) /* command write */ i2c_write(i2c_smbus, smbus_addr, dev->cmd); timer_bytes++; - - /* fall-through */ + fallthrough; case 0xe: /* I2C with 7-bit address */ if (!read) { /* word write (only when writing) */ @@ -309,6 +310,9 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE) dev->index = 0; break; + + default: + break; } if (dev->next_stat) { /* schedule dispatch of any pending status register update */ diff --git a/src/device/smbus_sis5595.c b/src/device/smbus_sis5595.c new file mode 100644 index 0000000000..b76b38e170 --- /dev/null +++ b/src/device/smbus_sis5595.c @@ -0,0 +1,386 @@ +/* + * 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. + * + * Implementation of a generic SiS 5595-compatible SMBus host + * controller. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2020-2021 RichardG. + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/i2c.h> +#include <86box/pci.h> +#include <86box/smbus.h> +#include <86box/plat_fallthrough.h> + +#ifdef ENABLE_SMBUS_SIS5595_LOG +int smbus_sis5595_do_log = ENABLE_SMBUS_SIS5595_LOG; + +static void +smbus_sis5595_log(const char *fmt, ...) +{ + va_list ap; + + if (smbus_sis5595_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define smbus_sis5595_log(fmt, ...) +#endif + +static void +smbus_sis5595_irq(smbus_sis5595_t *dev, int raise) +{ + if (dev->irq_enable) { + if (raise) + pci_set_mirq(6, 1, &dev->irq_state); + else + pci_clear_mirq(6, 1, &dev->irq_state); + } +} + +void +smbus_sis5595_irq_enable(void *priv, uint8_t enable) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (!enable && dev->irq_enable) + pci_clear_mirq(6, 1, &dev->irq_state); + + dev->irq_enable = enable; +} + +uint8_t +smbus_sis5595_read_index(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + return dev->index; +} + +uint8_t +smbus_sis5595_read_data(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t ret = 0x00; + + switch (dev->index) { + case 0x00: + ret = dev->stat & 0xff; + break; + case 0x01: + ret = dev->stat >> 8; + break; + + case 0x02: + ret = dev->ctl & 0xff; + break; + case 0x03: + ret = dev->ctl >> 8; + break; + + case 0x04: + ret = dev->addr; + break; + + case 0x05: + ret = dev->cmd; + break; + + case 0x06: + ret = dev->block_ptr; + break; + + case 0x07: + ret = dev->count; + break; + + case 0x08 ... 0x0f: + ret = dev->data[(dev->index & 0x07) + (dev->block_ptr << 3)]; + if (dev->index == 0x0f) { + dev->block_ptr = (dev->block_ptr + 1) & 3; + smbus_sis5595_irq(dev, dev->block_ptr != 0x00); + } + break; + + case 0x10: + ret = dev->saved_addr; + break; + + case 0x11: + ret = dev->data0; + break; + + case 0x12: + ret = dev->data1; + break; + + case 0x13: + ret = dev->alias; + break; + + case 0xff: + ret = dev->reg_ff & 0xc0; + break; + + default: + break; + } + + smbus_sis5595_log("SMBus SIS5595: read(%02X) = %02x\n", addr, ret); + + return ret; +} + +void +smbus_sis5595_write_index(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + dev->index = val; +} + +void +smbus_sis5595_write_data(void *priv, uint8_t val) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + uint8_t smbus_addr; + uint8_t cmd; + uint8_t read; + uint16_t prev_stat; + uint16_t timer_bytes = 0; + + smbus_sis5595_log("SMBus SIS5595: write(%02X, %02X)\n", addr, val); + + prev_stat = dev->next_stat; + dev->next_stat = 0x0000; + switch (dev->index) { + case 0x00: + dev->stat &= ~(val & 0xf0); + /* Make sure IDLE is set if we're not busy or errored. */ + if (dev->stat == 0x04) + dev->stat = 0x00; + break; + case 0x01: + dev->stat &= ~(val & 0x07); + break; + + case 0x02: + dev->ctl = (dev->ctl & 0xff00) | val; + if (val & 0x20) { /* cancel an in-progress command if KILL is set */ + if (prev_stat) { /* cancel only if a command is in progress */ + timer_disable(&dev->response_timer); + dev->stat = 0x80; /* raise FAILED */ + } + } else if (val & 0x10) { + /* dispatch command if START is set */ + timer_bytes++; /* address */ + + smbus_addr = (dev->addr >> 1); + read = dev->addr & 0x01; + + cmd = (dev->ctl >> 1) & 0x7; + smbus_sis5595_log("SMBus SIS5595: addr=%02X read=%d protocol=%X cmd=%02X " + "data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, + dev->data0, dev->data1); + + /* Raise DEV_ERR if no device is at this address, or if the device returned + NAK when starting the transfer. */ + if (!i2c_start(i2c_smbus, smbus_addr, read)) { + dev->next_stat = 0x0020; + break; + } + + dev->next_stat = 0x0040; /* raise INTER (command completed) by default */ + + /* Decode the command protocol. */ + dev->block_ptr = 0x01; + switch (cmd) { + case 0x0: /* quick R/W */ + break; + + case 0x1: /* byte R/W */ + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x2: /* byte data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) /* byte read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + timer_bytes++; + + break; + + case 0x3: /* word data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) { /* word read */ + dev->data[0] = i2c_read(i2c_smbus, smbus_addr); + dev->data[1] = i2c_read(i2c_smbus, smbus_addr); + } else { /* word write */ + i2c_write(i2c_smbus, smbus_addr, dev->data[0]); + i2c_write(i2c_smbus, smbus_addr, dev->data[1]); + } + timer_bytes += 2; + + break; + + case 0x5: /* block R/W */ + dev->block_ptr = 0x00; + timer_bytes++; /* count the SMBus length byte now */ + fallthrough; + + default: /* unknown */ + dev->next_stat = 0x0010; /* raise DEV_ERR */ + timer_bytes = 0; + break; + } + + /* Finish transfer. */ + i2c_stop(i2c_smbus, smbus_addr); + } + break; + case 0x03: + dev->ctl = (dev->ctl & 0x00ff) | (val << 8); + break; + + case 0x04: + dev->addr = val; + break; + + case 0x05: + dev->cmd = val; + break; + + case 0x08 ... 0x0f: + dev->data[dev->index & 0x07] = val; + break; + + case 0x10: + dev->saved_addr = val; + break; + + case 0x11: + dev->data0 = val; + break; + + case 0x12: + dev->data1 = val; + break; + + case 0x13: + dev->alias = val & 0xfe; + break; + + case 0xff: + dev->reg_ff = val & 0x3f; + break; + + default: + break; + } + + if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */ + dev->stat = 0x08; /* raise HOST_BUSY while waiting */ + timer_disable(&dev->response_timer); + /* delay = ((half clock for start + half clock for stop) + (bytes * (8 bits + ack))) * 60us period measured on real VIA 686B */ + timer_set_delay_u64(&dev->response_timer, (1 + (timer_bytes * 9)) * 60 * TIMER_USEC); + } +} + +static void +smbus_sis5595_response(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + /* Dispatch the status register update. */ + dev->stat = dev->next_stat; +} + +static void +smbus_sis5595_reset(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + timer_disable(&dev->response_timer); + dev->stat = 0x0000; + dev->block_ptr = 0x01; +} + +static void * +smbus_sis5595_init(const device_t *info) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) malloc(sizeof(smbus_sis5595_t)); + memset(dev, 0, sizeof(smbus_sis5595_t)); + + dev->local = info->local; + + /* We save the I2C bus handle on dev but use i2c_smbus for all operations because + dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */ + i2c_smbus = dev->i2c = i2c_addbus("smbus_sis5595"); + + timer_add(&dev->response_timer, smbus_sis5595_response, dev, 0); + + smbus_sis5595_reset(dev); + + return dev; +} + +static void +smbus_sis5595_close(void *priv) +{ + smbus_sis5595_t *dev = (smbus_sis5595_t *) priv; + + if (i2c_smbus == dev->i2c) + i2c_smbus = NULL; + i2c_removebus(dev->i2c); + + free(dev); +} + +const device_t sis5595_smbus_device = { + .name = "SiS 5595-compatible SMBus Host Controller", + .internal_name = "sis5595_smbus", + .flags = DEVICE_AT, + .local = 0, + .init = smbus_sis5595_init, + .close = smbus_sis5595_close, + .reset = smbus_sis5595_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/unittester.c b/src/device/unittester.c new file mode 100644 index 0000000000..e52f3b56fe --- /dev/null +++ b/src/device/unittester.c @@ -0,0 +1,635 @@ +/* + * 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. + * + * Debug device for assisting in unit testing. + * See doc/specifications/86box-unit-tester.md for more info. + * If modifying the protocol, you MUST modify the specification + * and increment the version number. + * + * + * + * Authors: GreaseMonkey, + * + * Copyright 2024 GreaseMonkey. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/plat.h> +#include <86box/unittester.h> +#include <86box/video.h> + +enum fsm1_value { + UT_FSM1_WAIT_8, + UT_FSM1_WAIT_6, + UT_FSM1_WAIT_B, + UT_FSM1_WAIT_o, + UT_FSM1_WAIT_x, +}; +enum fsm2_value { + UT_FSM2_IDLE, + UT_FSM2_WAIT_IOBASE_0, + UT_FSM2_WAIT_IOBASE_1, +}; + +/* Status bit mask */ +#define UT_STATUS_AWAITING_READ (1 << 0) +#define UT_STATUS_AWAITING_WRITE (1 << 1) +#define UT_STATUS_IDLE (1 << 2) +#define UT_STATUS_UNSUPPORTED_CMD (1 << 3) + +/* Command list */ +enum unittester_cmd { + UT_CMD_NOOP = 0x00, + UT_CMD_CAPTURE_SCREEN_SNAPSHOT = 0x01, + UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE = 0x02, + UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE = 0x03, + UT_CMD_EXIT = 0x04, +}; + +struct unittester_state { + /* I/O port settings */ + uint16_t trigger_port; + uint16_t iobase_port; + + /* Trigger port finite state machines */ + /* FSM1: "86Box" string detection */ + enum fsm1_value fsm1; + /* FSM2: IOBASE port selection, once trigger is activated */ + enum fsm2_value fsm2; + uint16_t fsm2_new_iobase; + + /* Command and data handling state */ + uint8_t status; + enum unittester_cmd cmd_id; + uint32_t write_offs; + uint32_t write_len; + uint64_t read_offs; + uint64_t read_len; + + /* Screen snapshot state */ + /* Monitor to take snapshot on */ + uint8_t snap_monitor; + /* Main image width + height */ + uint16_t snap_img_width; + uint16_t snap_img_height; + /* Fully overscanned image width + height */ + uint16_t snap_overscan_width; + uint16_t snap_overscan_height; + /* Offset of actual image within overscanned area */ + uint16_t snap_img_xoffs; + uint16_t snap_img_yoffs; + + /* Command-specific state */ + /* 0x02: Read Screen Snapshot Rectangle */ + /* 0x03: Verify Screen Snapshot Rectangle */ + uint16_t read_snap_width; + uint16_t read_snap_height; + int16_t read_snap_xoffs; + int16_t read_snap_yoffs; + uint32_t read_snap_crc; + + /* 0x04: Exit */ + uint8_t exit_code; +}; +static struct unittester_state unittester; +static const struct unittester_state unittester_defaults = { + .trigger_port = 0x0080, + .iobase_port = 0xFFFF, + .fsm1 = UT_FSM1_WAIT_8, + .fsm2 = UT_FSM2_IDLE, + .status = UT_STATUS_IDLE, + .cmd_id = UT_CMD_NOOP, +}; + +static const device_config_t unittester_config[] = { + { .name = "exit_enabled", + .description = "Enable 0x04 \"Exit 86Box\" command", + .type = CONFIG_BINARY, + .default_int = 1, + .default_string = "" }, + { .type = CONFIG_END } +}; + +/* Kept separate, as we will be reusing this object */ +static bitmap_t *unittester_screen_buffer = NULL; + +static bool unittester_exit_enabled = true; + +#ifdef ENABLE_UNITTESTER_LOG +int unittester_do_log = ENABLE_UNITTESTER_LOG; + +static void +unittester_log(const char *fmt, ...) +{ + va_list ap; + + if (unittester_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define unittester_log(fmt, ...) +#endif + +static uint8_t +unittester_read_snap_rect_idx(uint64_t offs) +{ + /* WARNING: If the width is somehow 0 and wasn't caught earlier, you'll probably get a divide by zero crash. */ + uint32_t idx = (offs & 0x3); + int64_t x = (offs >> 2) % unittester.read_snap_width; + int64_t y = (offs >> 2) / unittester.read_snap_width; + x += unittester.read_snap_xoffs; + y += unittester.read_snap_yoffs; + + if (x < 0 || y < 0 || x >= unittester.snap_overscan_width || y >= unittester.snap_overscan_height) { + /* Out of range! */ + return (idx == 3 ? 0xFF : 0x00); + } else { + /* In range */ + return (unittester_screen_buffer->line[y][x] & 0x00FFFFFF) >> (idx * 8); + } +} + +static void +unittester_write(uint16_t port, uint8_t val, UNUSED(void *priv)) +{ + if (port == unittester.iobase_port + 0x00) { + /* Command port */ + /* unittester_log("[UT] W %02X Command\n", val); */ + + unittester.write_offs = 0; + unittester.write_len = 0; + unittester.read_offs = 0; + unittester.read_len = 0; + + switch (val) { + /* 0x00: No-op */ + case UT_CMD_NOOP: + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + + /* 0x01: Capture Screen Snapshot */ + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + unittester.cmd_id = UT_CMD_CAPTURE_SCREEN_SNAPSHOT; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 1; + break; + + /* 0x02: Read Screen Snapshot Rectangle */ + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + unittester.cmd_id = UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 8; + break; + + /* 0x03: Verify Screen Snapshot Rectangle */ + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + unittester.cmd_id = UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 8; + break; + + /* 0x04: Exit */ + case UT_CMD_EXIT: + unittester.cmd_id = UT_CMD_EXIT; + unittester.status = UT_STATUS_AWAITING_WRITE; + unittester.write_len = 1; + break; + + /* Unsupported command - terminate here */ + default: + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE | UT_STATUS_UNSUPPORTED_CMD; + break; + } + + } else if (port == unittester.iobase_port + 0x01) { + /* Data port */ + /* unittester_log("[UT] W %02X Data\n", val); */ + + /* Skip if not awaiting */ + if ((unittester.status & UT_STATUS_AWAITING_WRITE) == 0) + return; + + switch (unittester.cmd_id) { + case UT_CMD_EXIT: + switch (unittester.write_offs) { + case 0: + unittester.exit_code = val; + break; + default: + break; + } + break; + + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + switch (unittester.write_offs) { + case 0: + unittester.snap_monitor = val; + break; + default: + break; + } + break; + + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + switch (unittester.write_offs) { + case 0: + unittester.read_snap_width = (uint16_t) val; + break; + case 1: + unittester.read_snap_width |= ((uint16_t) val) << 8; + break; + case 2: + unittester.read_snap_height = (uint16_t) val; + break; + case 3: + unittester.read_snap_height |= ((uint16_t) val) << 8; + break; + case 4: + unittester.read_snap_xoffs = (uint16_t) val; + break; + case 5: + unittester.read_snap_xoffs |= ((uint16_t) val) << 8; + break; + case 6: + unittester.read_snap_yoffs = (uint16_t) val; + break; + case 7: + unittester.read_snap_yoffs |= ((uint16_t) val) << 8; + break; + default: + break; + } + break; + + /* This should not be reachable, but just in case... */ + default: + break; + } + + /* Advance write buffer */ + unittester.write_offs += 1; + if (unittester.write_offs >= unittester.write_len) { + unittester.status &= ~UT_STATUS_AWAITING_WRITE; + /* Determine what we're doing here based on the command. */ + switch (unittester.cmd_id) { + case UT_CMD_EXIT: + unittester_log("[UT] Exit received - code = %02X\n", unittester.exit_code); + + /* CHECK: Do we actually exit? */ + if (unittester_exit_enabled) { + /* Yes - call exit! */ + /* Clamp exit code */ + if (unittester.exit_code > 0x7F) + unittester.exit_code = 0x7F; + + /* Exit somewhat quickly! */ + unittester_log("[UT] Exit enabled, exiting with code %02X\n", unittester.exit_code); + exit(unittester.exit_code); + + } else { + /* No - report successful command completion and continue program execution */ + unittester_log("[UT] Exit disabled, continuing execution\n"); + } + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + /* Recompute screen */ + unittester.snap_img_width = 0; + unittester.snap_img_height = 0; + unittester.snap_img_xoffs = 0; + unittester.snap_img_yoffs = 0; + unittester.snap_overscan_width = 0; + unittester.snap_overscan_height = 0; + if (unittester.snap_monitor < 0x01 || (unittester.snap_monitor - 1) > MONITORS_NUM) { + /* No monitor here - clear snapshot */ + unittester.snap_monitor = 0x00; + } else if (video_get_type_monitor(unittester.snap_monitor - 1) == VIDEO_FLAG_TYPE_NONE) { + /* Monitor disabled - clear snapshot */ + unittester.snap_monitor = 0x00; + } else { + /* Compute bounds for snapshot */ + const monitor_t *m = &monitors[unittester.snap_monitor - 1]; + unittester.snap_img_width = m->mon_xsize; + unittester.snap_img_height = m->mon_ysize; + unittester.snap_overscan_width = m->mon_xsize + m->mon_overscan_x; + unittester.snap_overscan_height = m->mon_ysize + m->mon_overscan_y; + unittester.snap_img_xoffs = (m->mon_overscan_x >> 1); + unittester.snap_img_yoffs = (m->mon_overscan_y >> 1); + /* Take snapshot */ + for (size_t y = 0; y < unittester.snap_overscan_height; y++) { + for (size_t x = 0; x < unittester.snap_overscan_width; x++) { + unittester_screen_buffer->line[y][x] = m->target_buffer->line[y][x]; + } + } + } + + /* We have 12 bytes to read. */ + unittester_log("[UT] Screen snapshot - image %d x %d @ (%d, %d) in overscan %d x %d\n", + unittester.snap_img_width, + unittester.snap_img_height, + unittester.snap_img_xoffs, + unittester.snap_img_yoffs, + unittester.snap_overscan_width, + unittester.snap_overscan_height); + unittester.status = UT_STATUS_AWAITING_READ; + unittester.read_len = 12; + break; + + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + /* Offset the X,Y offsets by the overscan offsets. */ + unittester.read_snap_xoffs += (int16_t) unittester.snap_img_xoffs; + unittester.read_snap_yoffs += (int16_t) unittester.snap_img_yoffs; + /* NOTE: Width * Height * 4 can potentially exceed a 32-bit number. + So, we use 64-bit numbers instead. + In practice, this will only happen if someone decides to request e.g. a 65535 x 65535 image, + of which most of the pixels will be out of range anyway. + */ + unittester.read_len = ((uint64_t) unittester.read_snap_width) * ((uint64_t) unittester.read_snap_height) * 4; + unittester.read_snap_crc = 0xFFFFFFFF; + + unittester_log("[UT] Screen rectangle analysis - %d x %d @ (%d, %d)\n", + unittester.read_snap_width, + unittester.read_snap_height, + unittester.read_snap_xoffs - (int16_t) unittester.snap_img_xoffs, + unittester.read_snap_yoffs - (int16_t) unittester.snap_img_yoffs); + + if (unittester.cmd_id == UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE) { + /* Read everything and compute CRC */ + uint32_t crc = 0xFFFFFFFF; + for (uint64_t i = 0; i < unittester.read_len; i++) { + crc ^= 0xFF & (uint32_t) unittester_read_snap_rect_idx(i); + /* Use some bit twiddling until we have a table-based fast CRC-32 implementation */ + for (uint32_t j = 0; j < 8; j++) { + crc = (crc >> 1) ^ ((-(crc & 0x1)) & 0xEDB88320); + } + } + unittester.read_snap_crc = crc ^ 0xFFFFFFFF; + + unittester_log("[UT] Screen rectangle analysis CRC = %08X\n", + unittester.read_snap_crc); + + /* Set actual read length for CRC result */ + unittester.read_len = 4; + unittester.status = UT_STATUS_AWAITING_READ; + + } else { + /* Do we have anything to read? */ + if (unittester.read_len >= 1) { + /* Yes - start reads! */ + unittester.status = UT_STATUS_AWAITING_READ; + } else { + /* No - stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } + } + break; + + default: + /* Nothing to write? Stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + break; + } + } + + } else { + /* Not handled here - possibly open bus! */ + } +} + +static uint8_t +unittester_read(uint16_t port, UNUSED(void *priv)) +{ + uint8_t outval = 0xFF; + + if (port == unittester.iobase_port + 0x00) { + /* Status port */ + /* unittester_log("[UT] R -- Status = %02X\n", unittester.status); */ + return unittester.status; + } else if (port == unittester.iobase_port + 0x01) { + /* Data port */ + /* unittester_log("[UT] R -- Data\n"); */ + + /* Skip if not awaiting */ + if ((unittester.status & UT_STATUS_AWAITING_READ) == 0) + return 0xFF; + + switch (unittester.cmd_id) { + case UT_CMD_CAPTURE_SCREEN_SNAPSHOT: + switch (unittester.read_offs) { + case 0: + outval = (uint8_t) (unittester.snap_img_width); + break; + case 1: + outval = (uint8_t) (unittester.snap_img_width >> 8); + break; + case 2: + outval = (uint8_t) (unittester.snap_img_height); + break; + case 3: + outval = (uint8_t) (unittester.snap_img_height >> 8); + break; + case 4: + outval = (uint8_t) (unittester.snap_overscan_width); + break; + case 5: + outval = (uint8_t) (unittester.snap_overscan_width >> 8); + break; + case 6: + outval = (uint8_t) (unittester.snap_overscan_height); + break; + case 7: + outval = (uint8_t) (unittester.snap_overscan_height >> 8); + break; + case 8: + outval = (uint8_t) (unittester.snap_img_xoffs); + break; + case 9: + outval = (uint8_t) (unittester.snap_img_xoffs >> 8); + break; + case 10: + outval = (uint8_t) (unittester.snap_img_yoffs); + break; + case 11: + outval = (uint8_t) (unittester.snap_img_yoffs >> 8); + break; + default: + break; + } + break; + + case UT_CMD_READ_SCREEN_SNAPSHOT_RECTANGLE: + outval = unittester_read_snap_rect_idx(unittester.read_offs); + break; + + case UT_CMD_VERIFY_SCREEN_SNAPSHOT_RECTANGLE: + outval = (uint8_t) (unittester.read_snap_crc >> (8 * unittester.read_offs)); + break; + + /* This should not be reachable, but just in case... */ + default: + break; + } + + /* Advance read buffer */ + unittester.read_offs += 1; + if (unittester.read_offs >= unittester.read_len) { + /* Once fully read, we stop here. */ + unittester.cmd_id = UT_CMD_NOOP; + unittester.status = UT_STATUS_IDLE; + } + + return outval; + } else { + /* Not handled here - possibly open bus! */ + return 0xFF; + } +} + +static void +unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) +{ + /* This one gets quite spammy. */ + /* unittester_log("[UT] Trigger value %02X -> FSM1 = %02X, FSM2 = %02X, IOBASE = %04X\n", val, unittester.fsm1, unittester.fsm2, unittester.iobase_port); */ + + /* Update FSM2 */ + switch (unittester.fsm2) { + /* IDLE: Do nothing - FSM1 will put us in the right state. */ + case UT_FSM2_IDLE: + unittester.fsm2 = UT_FSM2_IDLE; + break; + + /* WAIT IOBASE 0: Set low byte of temporary IOBASE. */ + case UT_FSM2_WAIT_IOBASE_0: + unittester.fsm2_new_iobase = ((uint16_t) val); + unittester.fsm2 = UT_FSM2_WAIT_IOBASE_1; + break; + + /* WAIT IOBASE 0: Set high byte of temporary IOBASE and commit to the real IOBASE. */ + case UT_FSM2_WAIT_IOBASE_1: + unittester.fsm2_new_iobase |= ((uint16_t) val) << 8; + + unittester_log("[UT] Remapping IOBASE: %04X -> %04X\n", unittester.iobase_port, unittester.fsm2_new_iobase); + + /* Unmap old IOBASE */ + if (unittester.iobase_port != 0xFFFF) + io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester.iobase_port = 0xFFFF; + + /* Map new IOBASE */ + unittester.iobase_port = unittester.fsm2_new_iobase; + if (unittester.iobase_port != 0xFFFF) + io_sethandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + + /* Reset FSM2 to IDLE */ + unittester.fsm2 = UT_FSM2_IDLE; + break; + } + + /* Update FSM1 */ + switch (val) { + case '8': + unittester.fsm1 = UT_FSM1_WAIT_6; + break; + case '6': + if (unittester.fsm1 == UT_FSM1_WAIT_6) + unittester.fsm1 = UT_FSM1_WAIT_B; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'B': + if (unittester.fsm1 == UT_FSM1_WAIT_B) + unittester.fsm1 = UT_FSM1_WAIT_o; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'o': + if (unittester.fsm1 == UT_FSM1_WAIT_o) + unittester.fsm1 = UT_FSM1_WAIT_x; + else + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + case 'x': + if (unittester.fsm1 == UT_FSM1_WAIT_x) { + unittester_log("[UT] Config activated, awaiting new IOBASE\n"); + unittester.fsm2 = UT_FSM2_WAIT_IOBASE_0; + } + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + + default: + unittester.fsm1 = UT_FSM1_WAIT_8; + break; + } +} + +static void * +unittester_init(UNUSED(const device_t *info)) +{ + unittester = (struct unittester_state) unittester_defaults; + + unittester_exit_enabled = !!device_get_config_int("exit_enabled"); + + if (unittester_screen_buffer == NULL) + unittester_screen_buffer = create_bitmap(2048, 2048); + + io_sethandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); + + unittester_log("[UT] 86Box Unit Tester initialised\n"); + + return &unittester; /* Dummy non-NULL value */ +} + +static void +unittester_close(UNUSED(void *priv)) +{ + io_removehandler(unittester.trigger_port, 1, NULL, NULL, NULL, unittester_trigger_write, NULL, NULL, NULL); + + if (unittester.iobase_port != 0xFFFF) + io_removehandler(unittester.iobase_port, 2, unittester_read, NULL, NULL, unittester_write, NULL, NULL, NULL); + unittester.iobase_port = 0xFFFF; + + if (unittester_screen_buffer != NULL) { + destroy_bitmap(unittester_screen_buffer); + unittester_screen_buffer = NULL; + } + + unittester_log("[UT] 86Box Unit Tester closed\n"); +} + +const device_t unittester_device = { + .name = "86Box Unit Tester", + .internal_name = "unittester", + .flags = DEVICE_ISA, + .local = 0, + .init = unittester_init, + .close = unittester_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = unittester_config, +}; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 7771a0b72f..310354ccf2 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -15,7 +15,8 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) + hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c + hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index f1ef1ecf6a..7bfb7e05a0 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -24,6 +24,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/machine.h> +#include <86box/timer.h> #include <86box/device.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -99,12 +100,10 @@ static const struct { { &ide_isa_device }, { &ide_isa_2ch_device }, { &xtide_at_device }, - { &xtide_at_386_device }, { &xtide_at_ps2_device }, { &xta_wdxt150_device }, { &xtide_acculogic_device }, { &xtide_device }, - { &xtide_plus_device }, { &esdi_ps2_device }, { &ide_pci_device }, { &ide_pci_2ch_device }, @@ -142,7 +141,7 @@ hdc_reset(void) device_add(&ide_qua_device); } -char * +const char * hdc_get_internal_name(int hdc) { return device_get_internal_name(controllers[hdc].device); @@ -154,7 +153,7 @@ hdc_get_from_internal_name(char *s) int c = 0; while (controllers[c].device != NULL) { - if (!strcmp((char *) controllers[c].device->internal_name, s)) + if (!strcmp(controllers[c].device->internal_name, s)) return c; c++; } diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 7c0d08fcaf..65184094ad 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -70,7 +70,7 @@ #define CMD_SET_PARAMETERS 0x91 #define CMD_READ_PARAMETERS 0xec -typedef struct { +typedef struct drive_t { int cfg_spt; int cfg_hpc; int current_cylinder; @@ -81,10 +81,14 @@ typedef struct { int hdd_num; } drive_t; -typedef struct { +typedef struct esdi_t { uint8_t status; uint8_t error; - int secount, sector, cylinder, head, cylprecomp; + int secount; + int sector; + int cylinder; + int head; + int cylprecomp; uint8_t command; uint8_t fdisk; int pos; @@ -132,13 +136,13 @@ irq_raise(esdi_t *esdi) } static __inline void -irq_lower(esdi_t *esdi) +irq_lower(UNUSED(esdi_t *esdi)) { picintc(1 << 14); } static __inline void -irq_update(esdi_t *esdi) +irq_update(UNUSED(esdi_t *esdi)) { if (esdi->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(esdi->fdisk & 2)) picint(1 << 14); @@ -159,7 +163,7 @@ esdi_set_callback(esdi_t *esdi, double callback) } double -esdi_get_xfer_time(esdi_t *esdi, int size) +esdi_get_xfer_time(UNUSED(esdi_t *esdi), int size) { /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ return (3125.0 / 8.0) * (double) size; @@ -169,13 +173,13 @@ esdi_get_xfer_time(esdi_t *esdi, int size) static int get_sector(esdi_t *esdi, off64_t *addr) { - drive_t *drive = &esdi->drives[esdi->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; - int c; - int h; - int s; - int sector; + const drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + int c; + int h; + int s; + int sector; if (esdi->head > heads) { esdi_at_log("esdi_get_sector: past end of configured heads\n"); @@ -334,7 +338,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi->command &= ~0x03; if (val & 0x02) fatal("Read with ECC\n"); - /*FALLTHROUGH*/ + fallthrough; case 0xa0: esdi->status = STAT_BUSY; @@ -393,7 +397,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) default: esdi_at_log("WD1007: bad command %02X\n", val); - /*FALLTHROUGH*/ + fallthrough; case 0xe8: /*???*/ esdi->status = STAT_BUSY; esdi_set_callback(esdi, 200 * HDC_TIME); @@ -417,6 +421,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi->fdisk = val; irq_update(esdi); break; + + default: + break; } } @@ -498,6 +505,9 @@ esdi_read(uint16_t port, void *priv) irq_lower(esdi); temp = esdi->status; break; + + default: + break; } esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp); @@ -779,7 +789,7 @@ esdi_callback(void *priv) default: esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command); - /*FALLTHROUGH*/ + fallthrough; case 0xe8: esdi->status = STAT_READY | STAT_ERR | STAT_DSC; @@ -791,7 +801,7 @@ esdi_callback(void *priv) } static void -loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn) +loadhd(esdi_t *esdi, int hdd_num, int d, UNUSED(const char *fn)) { drive_t *drive = &esdi->drives[hdd_num]; @@ -811,9 +821,9 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const char *fn) } static void -esdi_rom_write(uint32_t addr, uint8_t val, void *p) +esdi_rom_write(uint32_t addr, uint8_t val, void *priv) { - rom_t *rom = (rom_t *) p; + rom_t *rom = (rom_t *) priv; addr &= rom->mask; @@ -822,7 +832,7 @@ esdi_rom_write(uint32_t addr, uint8_t val, void *p) } static void * -wd1007vse1_init(const device_t *info) +wd1007vse1_init(UNUSED(const device_t *info)) { int c; @@ -868,8 +878,8 @@ wd1007vse1_init(const device_t *info) static void wd1007vse1_close(void *priv) { - esdi_t *esdi = (esdi_t *) priv; - drive_t *drive; + esdi_t *esdi = (esdi_t *) priv; + const drive_t *drive; for (uint8_t d = 0; d < 2; d++) { drive = &esdi->drives[d]; diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index f8686ba4ea..02f054ca26 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -82,6 +82,7 @@ #include <86box/ui.h> #include <86box/hdc.h> #include <86box/hdd.h> +#include <86box/plat_unused.h> /* These are hardwired. */ #define ESDI_IOADDR_PRI 0x3510 @@ -95,7 +96,8 @@ #define CMD_ADAPTER 0 typedef struct esdi_drive_t { - int spt, hpc; + int spt; + int hpc; int tracks; int sectors; int present; @@ -117,8 +119,8 @@ typedef struct esdi_t { uint16_t cmd_data[4]; int cmd_dev; - int status_pos, - status_len; + int status_pos; + int status_len; uint16_t status_data[256]; @@ -138,7 +140,7 @@ typedef struct esdi_t { uint32_t rba; - struct { + struct cmds { int req_in_progress; } cmds[3]; @@ -221,7 +223,7 @@ set_irq(esdi_t *dev) } static __inline void -clear_irq(esdi_t *dev) +clear_irq(UNUSED(esdi_t *dev)) { picintc(1 << 14); } @@ -241,7 +243,7 @@ esdi_mca_set_callback(esdi_t *dev, double callback) } static double -esdi_mca_get_xfer_time(esdi_t *esdi, int size) +esdi_mca_get_xfer_time(UNUSED(esdi_t *esdi), int size) { /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ return (3125.0 / 8.0) * (double) size; @@ -350,10 +352,10 @@ complete_command_status(esdi_t *dev) static void esdi_callback(void *priv) { - esdi_t *dev = (esdi_t *) priv; - drive_t *drive; - int val; - double cmd_time = 0.0; + esdi_t *dev = (esdi_t *) priv; + const drive_t *drive; + int val; + double cmd_time = 0.0; esdi_mca_set_callback(dev, 0); @@ -440,6 +442,9 @@ esdi_callback(void *priv) dev->irq_in_progress = 1; set_irq(dev); break; + + default: + break; } break; @@ -513,6 +518,9 @@ esdi_callback(void *priv) dev->irq_in_progress = 1; set_irq(dev); break; + + default: + break; } break; @@ -546,6 +554,9 @@ esdi_callback(void *priv) dev->irq_in_progress = 1; set_irq(dev); break; + + default: + break; } break; @@ -577,6 +588,9 @@ esdi_callback(void *priv) dev->irq_in_progress = 1; set_irq(dev); break; + + default: + break; } break; @@ -695,7 +709,6 @@ esdi_callback(void *priv) } dev->data[dev->data_pos++] = val & 0xffff; - ; } memcpy(dev->sector_buffer[dev->sector_pos++], dev->data, 512); @@ -714,6 +727,9 @@ esdi_callback(void *priv) set_irq(dev); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); break; + + default: + break; } break; @@ -771,6 +787,9 @@ esdi_callback(void *priv) set_irq(dev); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); break; + + default: + break; } break; @@ -839,6 +858,9 @@ esdi_callback(void *priv) dev->irq_in_progress = 1; set_irq(dev); break; + + default: + break; } break; @@ -1037,7 +1059,7 @@ esdi_writew(uint16_t port, uint16_t val, void *priv) static uint8_t esdi_mca_read(int port, void *priv) { - esdi_t *dev = (esdi_t *) priv; + const esdi_t *dev = (esdi_t *) priv; esdi_mca_log("ESDI: mcard(%04x)\n", port); @@ -1085,6 +1107,9 @@ esdi_mca_write(int port, uint8_t val, void *priv) case 0x10: dev->dma = 4; break; + + default: + break; } if (dev->pos_regs[2] & 1) { @@ -1107,13 +1132,13 @@ esdi_mca_write(int port, uint8_t val, void *priv) static uint8_t esdi_mca_feedb(void *priv) { - esdi_t *dev = (esdi_t *) priv; + const esdi_t *dev = (esdi_t *) priv; return (dev->pos_regs[2] & 1); } static void * -esdi_init(const device_t *info) +esdi_init(UNUSED(const device_t *info)) { drive_t *drive; esdi_t *dev; @@ -1185,8 +1210,8 @@ esdi_init(const device_t *info) static void esdi_close(void *priv) { - esdi_t *dev = (esdi_t *) priv; - drive_t *drive; + esdi_t *dev = (esdi_t *) priv; + const drive_t *drive; dev->drives[0].present = dev->drives[1].present = 0; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 2bd1b8b8a6..39031138f7 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -82,23 +82,23 @@ #define WIN_SEEK 0x70 #define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ #define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 +#define WIN_PACKETCMD 0xa0 /* Send a packet command. */ +#define WIN_PIDENTIFY 0xa1 /* Identify ATAPI device */ +#define WIN_READ_MULTIPLE 0xc4 +#define WIN_WRITE_MULTIPLE 0xc5 +#define WIN_SET_MULTIPLE_MODE 0xc6 +#define WIN_READ_DMA 0xc8 +#define WIN_READ_DMA_ALT 0xc9 +#define WIN_WRITE_DMA 0xcA +#define WIN_WRITE_DMA_ALT 0xcB +#define WIN_STANDBYNOW1 0xe0 +#define WIN_IDLENOW1 0xe1 +#define WIN_SETIDLE1 0xe3 +#define WIN_CHECKPOWERMODE1 0xe5 +#define WIN_SLEEP1 0xe6 +#define WIN_IDENTIFY 0xeC /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xeF +#define WIN_READ_NATIVE_MAX 0xf8 #define FEATURE_SET_TRANSFER_MODE 0x03 #define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d @@ -110,69 +110,118 @@ #define IDE_TIME 10.0 -typedef struct { - int bit32, cur_dev, - irq, inited, - diag, force_ata3; - uint16_t base_main, side_main; - pc_timer_t timer; - ide_t *ide[2]; -} ide_board_t; +#define IDE_ATAPI_IS_EARLY ide->sc->pad0 -typedef struct { - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); - void (*set_irq)(int channel, void *priv); +typedef struct ide_bm_t { + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv); + void (*set_irq)(uint8_t status, void *priv); void *priv; } ide_bm_t; -static ide_board_t *ide_boards[4] = { NULL, NULL, NULL, NULL }; -static ide_bm_t *ide_bm[4] = { NULL, NULL, NULL, NULL }; +typedef struct ide_board_t { + uint8_t devctl; + uint8_t pad; + uint16_t base[2]; + int bit32; + int cur_dev; + int irq; + int inited; + int diag; + int force_ata3; + + pc_timer_t timer; + + ide_t *ide[2]; + ide_bm_t *bm; +} ide_board_t; + +ide_board_t *ide_boards[IDE_BUS_MAX]; static uint8_t ide_ter_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ - - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ + 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + /* PnP version 1.0, vendor version 1.0 */ + 0x0a, 0x10, 0x10, + /* ANSI identifier */ + 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', + 'l', 'l', 'e', 'r', + + /* Logical device BOX0001 */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, + /* Compatible device PNP0600 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, + /* Start dependent functions, preferred */ + 0x31, 0x00, + /* IRQ 11 */ + 0x22, 0x00, 0x08, + /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, + /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, + /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, + /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, + /* End dependent functions */ + 0x38, + + /* End tag, dummy checksum (filled in by isapnp_add_card) */ + 0x79, 0x00 }; static uint8_t ide_qua_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ - - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ - - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ + 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + /* PnP version 1.0, vendor version 1.0 */ + 0x0a, 0x10, 0x10, + /* ANSI identifier */ + 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', + 'l', 'l', 'e', 'r', + + /* Logical device BOX0001 */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, + /* Compatible device PNP0600 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, + /* Start dependent functions, preferred */ + 0x31, 0x00, + /* IRQ 10 */ + 0x22, 0x00, 0x04, + /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, + /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, + /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, + /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, + /* End dependent functions */ + 0x38, + + /* End tag, dummy checksum (filled in by isapnp_add_card) */ + 0x79, 0x00 }; ide_t *ide_drives[IDE_NUM]; @@ -203,7 +252,7 @@ ide_log(const char *fmt, ...) uint8_t getstat(ide_t *ide) { - return ide->atastat; + return ide->tf->atastat; } ide_t * @@ -240,6 +289,9 @@ ide_get_xfer_time(ide_t *ide, int size) case 0x10: period = (50.0 / 3.0); break; + + default: + break; } break; case 0x100: /* Single Word DMA */ @@ -253,6 +305,9 @@ ide_get_xfer_time(ide_t *ide, int size) case 0x04: period = (25.0 / 3.0); break; + + default: + break; } break; case 0x200: /* Multiword DMA */ @@ -266,6 +321,9 @@ ide_get_xfer_time(ide_t *ide, int size) case 0x04: period = (50.0 / 3.0); break; + + default: + break; } break; case 0x300: /* Ultra DMA */ @@ -288,8 +346,14 @@ ide_get_xfer_time(ide_t *ide, int size) case 0x20: period = 100.0; break; + + default: + break; } break; + + default: + break; } period = (1.0 / period); /* get us for 1 byte */ @@ -311,71 +375,46 @@ ide_atapi_get_period(uint8_t channel) return ide_get_xfer_time(ide, 1); } -void -ide_irq_raise(ide_t *ide) +static void +ide_irq_update(ide_board_t *dev, int log) { - if (!ide_boards[ide->board]) - return; + ide_t *ide; + uint8_t set; - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + if (dev == NULL) + return; - ide_log("IDE %i: IRQ raise\n", ide->board); +#ifdef ENABLE_IDE_LOG + if (log) + ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq); +#endif - if (!(ide->fdisk & 2) && ide->selected) { - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picint(1 << ide_boards[ide->board]->irq); - } + ide = ide_drives[dev->cur_dev]; + set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat; - ide->irqstat = 1; - ide->service = 1; + if (!dev->force_ata3 && dev->bm && dev->bm->set_irq) + dev->bm->set_irq(set << 2, dev->bm->priv); + else if (ide_boards[ide->board]->irq != -1) + picint_common(1 << dev->irq, PIC_IRQ_EDGE, set, NULL); } void -ide_irq_lower(ide_t *ide) +ide_irq(ide_t *ide, int set, int log) { if (!ide_boards[ide->board]) return; - /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - // ide_log("IDE %i: IRQ lower\n", ide->board); - - if (ide->irqstat && ide->selected) { - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picintc(1 << ide_boards[ide->board]->irq); - } - - ide->irqstat = 0; -} +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("IDE %i: IRQ %s\n", ide->channel, set ? "raise" : "lower"); +#endif -static void -ide_irq_update(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; + ide->irqstat = set; - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + if (set) + ide->service = 1; - if (!(ide->fdisk & 2) && ide->irqstat) { - ide_log("IDE %i: IRQ update raise\n", ide->board); - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - } else if (ide_boards[ide->board]->irq != -1) { - picintc(1 << ide_boards[ide->board]->irq); - picint(1 << ide_boards[ide->board]->irq); - } - } else if ((ide->fdisk & 2) || !ide->irqstat) { - ide_log("IDE %i: IRQ update lower\n", ide->board); - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else if (ide_boards[ide->board]->irq != -1) - picintc(1 << ide_boards[ide->board]->irq); - } + if (ide->selected) + ide_irq_update(ide_boards[ide->board], log); } /** @@ -424,59 +463,37 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src) static int ide_get_max(ide_t *ide, int type) { - if (ide->type == IDE_ATAPI) - return ide->get_max(!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type); - - switch (type) { - case TYPE_PIO: /* PIO */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 4; - - return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ - case TYPE_SDMA: /* SDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 2; + int ret = -1; + ide_bm_t *bm = ide_boards[ide->board]->bm; + int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); + int max[2][4] = { { 0, -1, -1, -1 }, { 4, 2, 2, 5 } }; - return -1; - case TYPE_MDMA: /* MDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 2; - - return -1; - case TYPE_UDMA: /* UDMA */ - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 5; + if (ide->type == IDE_ATAPI) + ret = ide->get_max(!IDE_ATAPI_IS_EARLY && ata_4, type); + else if (type <= TYPE_UDMA) + ret = max[ata_4][type]; + else + fatal("Unknown transfer type: %i\n", type); - return -1; - default: - fatal("Unknown transfer type: %i\n", type); - return -1; - } + return ret; } static int ide_get_timings(ide_t *ide, int type) { - if (ide->type == IDE_ATAPI) - return ide->get_timings(!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type); - - switch (type) { - case TIMINGS_DMA: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; + int ret = 0; + ide_bm_t *bm = ide_boards[ide->board]->bm; + int ata_4 = (!ide_boards[ide->board]->force_ata3 && (bm != NULL)); + int timings[2][3] = { { 0, 0, 0 }, { 120, 120, 0 } }; - return 0; - case TIMINGS_PIO: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; + if (ide->type == IDE_ATAPI) + ret = ide->get_timings(!IDE_ATAPI_IS_EARLY && ata_4, type); + else if (type <= TIMINGS_PIO_FC) + ret = timings[ata_4][type]; + else + fatal("Unknown transfer type: %i\n", type); - return 0; - case TIMINGS_PIO_FC: - return 0; - default: - fatal("Unknown transfer type: %i\n", type); - return 0; - } + return ret; } /** @@ -486,11 +503,13 @@ static void ide_hd_identify(ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + ide_bm_t *bm = ide_boards[ide->board]->bm; uint32_t d_hpc; uint32_t d_spt; uint32_t d_tracks; - uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * + hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; @@ -519,13 +538,20 @@ ide_hd_identify(ide_t *ide) } ide_log("Default CHS translation: %i, %i, %i\n", ide->buffer[1], ide->buffer[3], ide->buffer[6]); - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[0] = (1 << 6); /*Fixed drive*/ - ide->buffer[20] = 3; /*Buffer type*/ - ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; /*Buffer size*/ - ide->buffer[50] = 0x4000; /* Capabilities */ + /* Serial Number */ + ide_padstr((char *) (ide->buffer + 10), "", 20); + /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); + /* Model */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); + /* Fixed drive */ + ide->buffer[0] = (1 << 6); + /* Buffer type */ + ide->buffer[20] = 3; + /* Buffer size */ + ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; + /* Capabilities */ + ide->buffer[50] = 0x4000; ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if ((ide->tracks >= 1024) || (ide->hpc > 16) || (ide->spt > 63)) { @@ -537,9 +563,10 @@ ide_hd_identify(ide_t *ide) ide_log("Full size: %" PRIu64 "\n", full_size); /* - Bit 0 = The fields reported in words 54-58 are valid; - Bit 1 = The fields reported in words 64-70 are valid; - Bit 2 = The fields reported in word 88 are valid. */ + Bit 0 = The fields reported in words 54-58 are valid; + Bit 1 = The fields reported in words 64-70 are valid; + Bit 2 = The fields reported in word 88 are valid. + */ ide->buffer[53] = 1; if (ide->cfg_spt != 0) { @@ -558,16 +585,19 @@ ide_hd_identify(ide_t *ide) } } - full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * ((uint64_t) ide->buffer[56]); + full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * + ((uint64_t) ide->buffer[56]); - ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ + /* Total addressable sectors (LBA) */ + ide->buffer[57] = full_size & 0xFFFF; ide->buffer[58] = (full_size >> 16) & 0x0FFF; ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); } - ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/ - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) { + /* Max sectors on multiple transfer command */ + ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; + if (!ide_boards[ide->board]->force_ata3 && (bm != NULL)) { ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ } else { @@ -578,21 +608,22 @@ ide_hd_identify(ide_t *ide) static void ide_identify(ide_t *ide) { - int d; - int i; - int max_pio; - int max_sdma; - int max_mdma; - int max_udma; - ide_t *ide_other = ide_drives[ide->channel ^ 1]; + int d; + int i; + int max_pio; + int max_sdma; + int max_mdma; + int max_udma; + const ide_t *ide_other = ide_drives[ide->channel ^ 1]; + ide_bm_t *bm = ide_boards[ide->board]->bm; ide_log("IDE IDENTIFY or IDENTIFY PACKET DEVICE on board %i (channel %i)\n", ide->board, ide->channel); memset(ide->buffer, 0, 512); if (ide->type == IDE_ATAPI) - ide->identify(ide, !ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)); - else if (ide->type != IDE_NONE) + ide->identify(ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL)); + else if (ide->type == IDE_HDD) ide_hd_identify(ide); else { fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); @@ -649,7 +680,8 @@ ide_identify(ide_t *ide) } if ((max_sdma != -1) || (max_mdma != -1) || (max_udma != -1)) { - ide->buffer[49] |= 0x100; /* DMA supported */ + /* DMA supported */ + ide->buffer[49] |= 0x100; ide->buffer[52] = ide_get_timings(ide, TIMINGS_DMA); } @@ -683,15 +715,16 @@ ide_get_sector(ide_t *ide) uint32_t heads; uint32_t sectors; - if (ide->lba) + if (ide->tf->lba) return (off64_t) ide->lba_addr; else { heads = ide->cfg_hpc; sectors = ide->cfg_spt; - uint8_t sector = ide->sector ? ide->sector : 1; + uint8_t sector = ide->tf->sector ? (ide->tf->sector - 1) : 0; - return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (sector - 1); + return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->tf->head) * sectors) + + (off64_t) sector; } } @@ -701,23 +734,29 @@ ide_get_sector(ide_t *ide) static void ide_next_sector(ide_t *ide) { - if (ide->lba) + uint32_t sector = ide->tf->sector; + uint32_t head = ide->tf->head; + + if (ide->tf->lba) ide->lba_addr++; else { - ide->sector++; - if (ide->sector == (ide->cfg_spt + 1)) { - ide->sector = 1; - ide->head++; - if (ide->head == ide->cfg_hpc) { - ide->head = 0; - ide->cylinder++; + sector++; + if ((sector == 0) || (sector == (ide->cfg_spt + 1))) { + sector = 1; + head++; + if (head == ide->cfg_hpc) { + head = 0; + ide->tf->cylinder++; } } } + + ide->tf->sector = sector & 0xff; + ide->tf->head = head & 0x0f; } static void -loadhd(ide_t *ide, int d, const char *fn) +loadhd(ide_t *ide, int d, UNUSED(const char *fn)) { if (!hdd_image_load(d)) { ide->type = IDE_NONE; @@ -736,21 +775,15 @@ loadhd(ide_t *ide, int d, const char *fn) void ide_set_signature(ide_t *ide) { - ide->sector = 1; - ide->head = 0; + uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f }; - if (ide->type == IDE_ATAPI) { - ide->sc->phase = 1; - ide->sc->request_length = 0xEB14; - ide->secount = ide->sc->phase; - ide->cylinder = ide->sc->request_length; - } else { - ide->secount = 1; - // ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF); - ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0x7F7F); - if (ide->type == IDE_HDD) - ide->drive = 0; - } + ide->tf->sector = 1; + ide->tf->head = 0; + ide->tf->secount = 1; + ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; + + if (ide->type == IDE_HDD) + ide->drive = 0; } static int @@ -762,10 +795,8 @@ ide_set_features(ide_t *ide) int submode; int max; - features = ide->cylprecomp; - features_data = ide->secount; - - ide_log("Features code %02X\n", features); + features = ide->tf->cylprecomp; + features_data = ide->tf->secount; ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data); @@ -782,7 +813,8 @@ ide_set_features(ide_t *ide) return 0; max = ide_get_max(ide, TYPE_PIO); ide->mdma_mode = (1 << max); - ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, + submode, ide->mdma_mode); break; case 0x01: /* PIO mode */ @@ -790,7 +822,8 @@ ide_set_features(ide_t *ide) if (submode > max) return 0; ide->mdma_mode = (1 << submode); - ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, + submode, ide->mdma_mode); break; case 0x02: /* Singleword DMA mode */ @@ -798,7 +831,8 @@ ide_set_features(ide_t *ide) if (submode > max) return 0; ide->mdma_mode = (1 << submode) | 0x100; - ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, + submode, ide->mdma_mode); break; case 0x04: /* Multiword DMA mode */ @@ -806,7 +840,8 @@ ide_set_features(ide_t *ide) if (submode > max) return 0; ide->mdma_mode = (1 << submode) | 0x200; - ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, + submode, ide->mdma_mode); break; case 0x08: /* Ultra DMA mode */ @@ -814,7 +849,8 @@ ide_set_features(ide_t *ide) if (submode > max) return 0; ide->mdma_mode = (1 << submode) | 0x300; - ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); + ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, + submode, ide->mdma_mode); break; default: @@ -848,16 +884,16 @@ ide_set_sector(ide_t *ide, int64_t sector_num) { unsigned int cyl; unsigned int r; - if (ide->lba) { - ide->head = (sector_num >> 24); - ide->cylinder = (sector_num >> 8); - ide->sector = (sector_num); + if (ide->tf->lba) { + ide->tf->head = (sector_num >> 24) & 0xff; + ide->tf->cylinder = (sector_num >> 8) & 0xffff; + ide->tf->sector = sector_num & 0xff; } else { - cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - ide->cylinder = cyl; - ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); - ide->sector = (r % hdd[ide->hdd_num].spt) + 1; + cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + ide->tf->cylinder = cyl & 0xffff; + ide->tf->head = ((r / hdd[ide->hdd_num].spt) & 0x0f) & 0xff; + ide->tf->sector = ((r % hdd[ide->hdd_num].spt) + 1) & 0xff; } } @@ -865,14 +901,16 @@ static void ide_zero(int d) { ide_t *dev; + if (ide_drives[d] == NULL) - ide_drives[d] = (ide_t *) malloc(sizeof(ide_t)); - memset(ide_drives[d], 0, sizeof(ide_t)); + ide_drives[d] = (ide_t *) calloc(1, sizeof(ide_t)); + dev = ide_drives[d]; + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); dev->channel = d; dev->type = IDE_NONE; dev->hdd_num = -1; - dev->atastat = DRDY_STAT | DSC_STAT; + dev->tf->atastat = DRDY_STAT | DSC_STAT; dev->service = 0; dev->board = d >> 1; dev->selected = !(d & 1); @@ -884,31 +922,31 @@ void ide_allocate_buffer(ide_t *dev) { if (dev->buffer == NULL) - dev->buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); - memset(dev->buffer, 0, 65536 * sizeof(uint16_t)); + dev->buffer = (uint16_t *) calloc(1, 65536 * sizeof(uint16_t)); } void ide_atapi_attach(ide_t *ide) { + ide_bm_t *bm = ide_boards[ide->board]->bm; + if (ide->type != IDE_NONE) return; ide->type = IDE_ATAPI; ide_allocate_buffer(ide); ide_set_signature(ide); - ide->mdma_mode = (1 << ide->get_max(!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), TYPE_PIO)); - ide->error = 1; + ide->mdma_mode = (1 << ide->get_max(!IDE_ATAPI_IS_EARLY && + !ide_boards[ide->board]->force_ata3 && (bm != NULL), TYPE_PIO)); + ide->tf->error = 1; ide->cfg_spt = ide->cfg_hpc = 0; -#ifndef EARLY_ATAPI - ide->sc->status = 0; -#endif + if (!IDE_ATAPI_IS_EARLY) + ide->tf->atastat = 0; } void ide_set_callback(ide_t *ide, double callback) { - if (!ide) { ide_log("ide_set_callback(NULL): Set callback failed\n"); return; @@ -943,9 +981,9 @@ ide_set_board_callback(uint8_t board, double callback) static void ide_atapi_command_bus(ide_t *ide) { - ide->sc->status = BUSY_STAT; - ide->sc->phase = 1; - ide->sc->pos = 0; + ide->tf->atastat = BUSY_STAT; + ide->tf->phase = 1; + ide->tf->pos = 0; ide->sc->callback = 1.0 * IDE_TIME; ide_set_callback(ide, ide->sc->callback); } @@ -955,90 +993,91 @@ ide_atapi_callback(ide_t *ide) { int out; int ret = 0; + ide_bm_t *bm = ide_boards[ide->board]->bm; +#ifdef ENABLE_IDE_LOG + char *phases[7] = { "Idle", "Command", "Data in", "Data out", "Data in DMA", "Data out DMA", + "Complete" }; + char *phase; switch (ide->sc->packet_status) { - case PHASE_IDLE: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_IDLE\n"); + default: + phase = "Unknown"; + break; + case PHASE_IDLE ... PHASE_COMPLETE: + phase = phases[ide->sc->packet_status]; + break; + case PHASE_ERROR: + phase = "Error"; + break; + case PHASE_NONE: + phase = "None"; + break; + } + + ide_log("Phase: %02X (%s)\n", ide->sc->packet_status, phase); #endif - ide->sc->pos = 0; - ide->sc->phase = 1; - ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); - return; + + switch (ide->sc->packet_status) { + default: + break; + + case PHASE_IDLE: + ide->tf->pos = 0; + ide->tf->phase = 1; + ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT); + break; case PHASE_COMMAND: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_COMMAND\n"); -#endif - ide->sc->status = BUSY_STAT | (ide->sc->status & ERR_STAT); + ide->tf->atastat = BUSY_STAT | (ide->tf->atastat & ERR_STAT); if (ide->packet_command) { ide->packet_command(ide->sc, ide->sc->atapi_cdb); if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) ide_atapi_callback(ide); } - return; + break; case PHASE_COMPLETE: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_COMPLETE\n"); -#endif - ide->sc->status = READY_STAT; - ide->sc->phase = 3; + case PHASE_ERROR: + ide->tf->atastat = READY_STAT; + if (ide->sc->packet_status == PHASE_ERROR) + ide->tf->atastat |= ERR_STAT; + ide->tf->phase = 3; ide->sc->packet_status = PHASE_NONE; ide_irq_raise(ide); - return; + break; case PHASE_DATA_IN: case PHASE_DATA_OUT: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_DATA_IN or PHASE_DATA_OUT\n"); -#endif - ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); - ide->sc->phase = !(ide->sc->packet_status & 0x01) << 1; + ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT); + ide->tf->phase = !(ide->sc->packet_status & 0x01) << 1; ide_irq_raise(ide); - return; + break; case PHASE_DATA_IN_DMA: case PHASE_DATA_OUT_DMA: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_DATA_IN_DMA or PHASE_DATA_OUT_DMA\n"); -#endif out = (ide->sc->packet_status & 0x01); - if (!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - ret = ide_bm[ide->board]->dma(ide->board, - ide->sc->temp_buffer, ide->sc->packet_len, - out, ide_bm[ide->board]->priv); - } else { - /* DMA command without a bus master. */ - if (ide->bus_master_error) - ide->bus_master_error(ide->sc); - return; + if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && + (bm != NULL) && bm->dma) { + ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, out, bm->priv); } + /* Else, DMA command without a bus master, ret = 0 (default). */ - if (ret == 0) { - if (ide->bus_master_error) - ide->bus_master_error(ide->sc); - } else if (ret == 1) { - if (out && ide->phase_data_out) - ret = ide->phase_data_out(ide->sc); - else if (!out && ide->command_stop) - ide->command_stop(ide->sc); - - if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) - ide_atapi_callback(ide); - } else if (ret == 2) - ide_atapi_command_bus(ide); - - return; - case PHASE_ERROR: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_ERROR\n"); -#endif - ide->sc->status = READY_STAT | ERR_STAT; - ide->sc->phase = 3; - ide->sc->packet_status = PHASE_NONE; - ide_irq_raise(ide); - return; - default: - ide_log("PHASE_UNKNOWN %02X\n", ide->sc->packet_status); - return; + switch (ret) { + case 0: + if (ide->bus_master_error) + ide->bus_master_error(ide->sc); + break; + case 1: + if (out && ide->phase_data_out) + ret = ide->phase_data_out(ide->sc); + else if (!out && ide->command_stop) + ide->command_stop(ide->sc); + + if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); + break; + case 2: + ide_atapi_command_bus(ide); + break; + } + break; } } @@ -1048,14 +1087,14 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) { scsi_common_t *dev = ide->sc; - ide_irq_lower(ide_drives[ide->board]); + ide_irq_lower(ide); - dev->status = BSY_STAT; + ide->tf->atastat = BSY_STAT; - if (dev->pos >= dev->packet_len) { - ide_log("%i bytes %s, command done\n", dev->pos, out ? "written" : "read"); + if (ide->tf->pos >= dev->packet_len) { + ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read"); - dev->pos = dev->request_pos = 0; + ide->tf->pos = dev->request_pos = 0; if (out && ide->phase_data_out) ide->phase_data_out(dev); else if (!out && ide->command_stop) @@ -1064,23 +1103,23 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) ide_atapi_callback(ide); } else { - ide_log("%i bytes %s, %i bytes are still left\n", dev->pos, - out ? "written" : "read", dev->packet_len - dev->pos); + ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos, + out ? "written" : "read", dev->packet_len - ide->tf->pos); /* If less than (packet length) bytes are remaining, update packet length accordingly. */ - if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) { - dev->max_transfer_len = dev->packet_len - dev->pos; + if ((dev->packet_len - ide->tf->pos) < (dev->max_transfer_len)) { + dev->max_transfer_len = dev->packet_len - ide->tf->pos; /* Also update the request length so the host knows how many bytes to transfer. */ - dev->request_length = dev->max_transfer_len; + ide->tf->request_length = dev->max_transfer_len; } ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, dev->max_transfer_len); dev->packet_status = PHASE_DATA_IN | out; - dev->status = BSY_STAT; - dev->phase = 1; + ide->tf->atastat = BSY_STAT; + ide->tf->phase = 1; ide_atapi_callback(ide); ide_set_callback(ide, 0.0); @@ -1088,168 +1127,123 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) } } -static uint32_t +static uint16_t ide_atapi_packet_read(ide_t *ide, int length) { scsi_common_t *dev = ide->sc; - - uint16_t *bufferw; - uint32_t *bufferl; - - uint32_t temp = 0; - - if (!dev || !dev->temp_buffer || (dev->packet_status != PHASE_DATA_IN)) - return 0; - - if (dev->packet_status == PHASE_DATA_IN) - ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", dev->request_pos, dev->max_transfer_len, dev->pos, dev->packet_len); - - bufferw = (uint16_t *) dev->temp_buffer; - bufferl = (uint32_t *) dev->temp_buffer; - - /* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it, - which can happen when issuing media access commands with an allocated length below minimum request length - (which is 1 sector = 2048 bytes). */ - switch (length) { - case 1: - temp = (dev->pos < dev->packet_len) ? dev->temp_buffer[dev->pos] : 0; - dev->pos++; - dev->request_pos++; - break; - case 2: - temp = (dev->pos < dev->packet_len) ? bufferw[dev->pos >> 1] : 0; - dev->pos += 2; + const uint16_t *bufferw; + uint16_t ret = 0; + + if (dev && dev->temp_buffer && (dev->packet_status == PHASE_DATA_IN)) { + ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", + dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); + + bufferw = (uint16_t *) dev->temp_buffer; + + /* Make sure we return a 0 and don't attempt to read from the buffer if + we're transferring bytes beyond it, which can happen when issuing media + access commands with an allocated length below minimum request length + (which is 1 sector = 2048 bytes). */ + if (length == 2) { + ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; + ide->tf->pos += 2; dev->request_pos += 2; - break; - case 4: - temp = (dev->pos < dev->packet_len) ? bufferl[dev->pos >> 2] : 0; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return 0; - } + } else { + ret = (ide->tf->pos < dev->packet_len) ? dev->temp_buffer[ide->tf->pos] : 0; + ide->tf->pos++; + dev->request_pos++; + } - if (dev->packet_status == PHASE_DATA_IN) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { + if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { /* Time for a DRQ. */ ide_atapi_pio_request(ide, 0); } - return temp; - } else - return 0; + } + + return ret; } static void -ide_atapi_packet_write(ide_t *ide, uint32_t val, int length) +ide_atapi_packet_write(ide_t *ide, uint16_t val, int length) { scsi_common_t *dev = ide->sc; - uint8_t *bufferb; - uint16_t *bufferw; - uint32_t *bufferl; - - if (!dev) - return; + uint8_t *bufferb = NULL; + uint16_t *bufferw = NULL; - if (dev->packet_status == PHASE_IDLE) - bufferb = dev->atapi_cdb; - else { - if (dev->temp_buffer) + if (dev) { + if (dev->packet_status == PHASE_IDLE) + bufferb = dev->atapi_cdb; + else if (dev->temp_buffer) bufferb = dev->temp_buffer; - else - return; - } - - bufferw = (uint16_t *) bufferb; - bufferl = (uint32_t *) bufferb; - - if (dev->packet_status == PHASE_DATA_IN) - return; - switch (length) { - case 1: - bufferb[dev->pos] = val & 0xff; - dev->pos++; - dev->request_pos++; - break; - case 2: - bufferw[dev->pos >> 1] = val & 0xffff; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - bufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; + bufferw = (uint16_t *) bufferb; } - if (dev->packet_status == PHASE_DATA_OUT) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - ide_atapi_pio_request(ide, 1); + if ((bufferb != NULL) && (dev->packet_status != PHASE_DATA_IN)) { + if (length == 2) { + bufferw[ide->tf->pos >> 1] = val & 0xffff; + ide->tf->pos += 2; + dev->request_pos += 2; + } else { + bufferb[ide->tf->pos] = val & 0xff; + ide->tf->pos++; + dev->request_pos++; } - return; - } else if (dev->packet_status == PHASE_IDLE) { - if (dev->pos >= 12) { - dev->pos = 0; - dev->status = BSY_STAT; - dev->packet_status = PHASE_COMMAND; - ide_atapi_callback(ide); + + if (dev->packet_status == PHASE_DATA_OUT) { + if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { + /* Time for a DRQ. */ + ide_atapi_pio_request(ide, 1); + } + } else if (dev->packet_status == PHASE_IDLE) { + if (ide->tf->pos >= 12) { + ide->tf->pos = 0; + ide->tf->atastat = BSY_STAT; + dev->packet_status = PHASE_COMMAND; + ide_atapi_callback(ide); + } } - return; } } -void -ide_write_data(ide_t *ide, uint32_t val, int length) +static void +ide_write_data(ide_t *ide, uint16_t val, int length) { uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; - - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - - if (ide->type == IDE_ATAPI) - ide_atapi_packet_write(ide, val, length); - } else { - switch (length) { - case 1: - idebufferb[ide->pos] = val & 0xff; - ide->pos++; - break; - case 2: - idebufferw[ide->pos >> 1] = val & 0xffff; - ide->pos += 2; - break; - case 4: - idebufferl[ide->pos >> 2] = val; - ide->pos += 4; - break; - default: - return; - } - if (ide->pos >= 512) { - ide->pos = 0; - ide->atastat = BSY_STAT; - double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - double wait_time = seek_time + xfer_time; - if (ide->command == WIN_WRITE_MULTIPLE) { - if ((ide->blockcount + 1) >= ide->blocksize || ide->secount == 1) { - ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); - ide->pending_delay = 0; - } else { - ide->pending_delay += wait_time; - ide_callback(ide); - } + if ((ide->type != IDE_NONE) && !(ide->type & IDE_SHADOW) && ide->buffer) { + if (ide->command == WIN_PACKETCMD) { + if (ide->type == IDE_ATAPI) + ide_atapi_packet_write(ide, val, length); + else + ide->tf->pos = 0; + } else { + if (length == 2) { + idebufferw[ide->tf->pos >> 1] = val & 0xffff; + ide->tf->pos += 2; } else { - ide_set_callback(ide, wait_time); + idebufferb[ide->tf->pos] = val & 0xff; + ide->tf->pos++; + } + + if (ide->tf->pos >= 512) { + ide->tf->pos = 0; + ide->tf->atastat = BSY_STAT; + double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + double xfer_time = ide_get_xfer_time(ide, 512); + double wait_time = seek_time + xfer_time; + if (ide->command == WIN_WRITE_MULTIPLE) { + if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { + ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); + ide->pending_delay = 0; + } else { + ide->pending_delay += wait_time; + ide_callback(ide); + } + } else + ide_set_callback(ide, wait_time); } } } @@ -1258,7 +1252,7 @@ ide_write_data(ide_t *ide, uint32_t val, int length) void ide_writew(uint16_t addr, uint16_t val, void *priv) { - ide_board_t *dev = (ide_board_t *) priv; + const ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; int ch; @@ -1266,7 +1260,9 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; - ide_log("ide_writew %04X %04X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv); +#endif addr &= 0x7; @@ -1290,7 +1286,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) static void ide_writel(uint16_t addr, uint32_t val, void *priv) { - ide_board_t *dev = (ide_board_t *) priv; + const ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; int ch; @@ -1298,7 +1294,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; - ide_log("ide_writel %04X %08X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv); +#endif addr &= 0x7; @@ -1334,7 +1332,7 @@ dev_reset(ide_t *ide) } void -ide_write_devctl(uint16_t addr, uint8_t val, void *priv) +ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; @@ -1347,14 +1345,14 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; - ide_log("ide_write_devctl %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); + ide_log("ide_write_devctl(%04X, %02X, %08X)\n", addr, val, priv); if ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)) return; dev->diag = 0; - if ((val & 4) && !(ide->fdisk & 4)) { + if ((val & 4) && !(dev->devctl & 4)) { /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; @@ -1365,44 +1363,28 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) some 286 and 386 machines error out. */ if (!(ch & 1)) { if (ide->type != IDE_NONE) { - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } + ide->tf->atastat = BSY_STAT; + ide->tf->error = 1; } if (ide_other->type != IDE_NONE) { - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } + ide_other->tf->atastat = BSY_STAT; + ide_other->tf->error = 1; } } - } else if (!(val & 4) && (ide->fdisk & 4)) { + } else if (!(val & 4) && (dev->devctl & 4)) { /* Reset toggled from 1 to 0. */ if (!(ch & 1)) { /* Currently active device is 0, use the device 0 reset protocol. */ /* Device 0. */ dev_reset(ide); - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } + ide->tf->atastat = BSY_STAT; + ide->tf->error = 1; /* Device 1. */ dev_reset(ide_other); - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } + ide_other->tf->atastat = BSY_STAT; + ide_other->tf->error = 1; /* Fire the timer. */ dev->diag = 0; @@ -1413,12 +1395,15 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) } else { /* Currently active device is 1, simply reset the status and the active device. */ dev_reset(ide); - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - } + /* Non-early ATAPI devices have DRDY clear after SRST. */ + ide->tf->atastat = 0; + if (IDE_ATAPI_IS_EARLY) + ide->tf->atastat |= DRDY_STAT; + } else + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide->tf->error = 1; + ide_other->tf->error = 1; /* Assert PDIAG-. */ dev->cur_dev &= ~1; ch = dev->cur_dev; @@ -1430,111 +1415,123 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) } } - old = ide->fdisk; - ide->fdisk = ide_other->fdisk = val; - if (!(val & 0x02) && (old & 0x02) && ide->irqstat) - ide_irq_update(ide); + old = dev->devctl; + dev->devctl = val; + if (!(val & 0x02) && (old & 0x02)) + ide_irq_update(ide_boards[ide->board], 1); +} + +static void +ide_reset_registers(ide_t *ide) +{ + uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f }; + + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide->tf->error = 1; + ide->tf->secount = 1; + ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; + ide->tf->sector = 1; + ide->tf->head = 0; + + ide->reset = 0; + + if (ide->type == IDE_ATAPI) + ide->sc->callback = 0.0; + + ide_set_callback(ide, 0.0); } void ide_writeb(uint16_t addr, uint8_t val, void *priv) { ide_board_t *dev = (ide_board_t *) priv; - ide_t *ide; ide_t *ide_other; int ch; + int bad = 0; + int reset = 0; ch = dev->cur_dev; ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; - ide_log("ide_write %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); + ide_log("ide_writeb(%04X, %02X, %08X)\n", addr, val, priv); addr &= 0x7; - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { + if ((ide->type != IDE_NONE) || ((addr != 0x0) && (addr != 0x7))) switch (addr) { case 0x0: /* Data */ ide_write_data(ide, val | (val << 8), 2); - return; + break; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ case 0x1: /* Features */ - if (ide->type == IDE_ATAPI) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - ide->sc->features = val; + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->cylprecomp = val; + if (ide->type == IDE_ATAPI) + ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); } - ide->cylprecomp = val; - -/* The ATA-3 specification says this register is the parameter for the - command and is unclear as to whether or not it's written to both - devices at once. Writing it to both devices at once breaks CD boot - on the AMI Apollo. */ -#ifdef WRITE_PARAM_TO_BOTH_DEVICES - if (ide_other->type == IDE_ATAPI) - ide_other->sc->features = val; - ide_other->cylprecomp = val; -#endif - return; + + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide_other->tf->cylprecomp = val; + break; case 0x2: /* Sector count */ - if (ide->type == IDE_ATAPI) { - ide_log("Sector count write: %i\n", val); - ide->sc->phase = val; - } - ide->secount = val; + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide->tf->secount = val; + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide_other->tf->secount = val; + break; - if (ide_other->type == IDE_ATAPI) { - ide_log("Other sector count write: %i\n", val); - ide_other->sc->phase = val; + case 0x3: /* Sector */ + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->sector = val; + ide->lba_addr = (ide->lba_addr & 0xfffff00) | val; } - ide_other->secount = val; - return; - case 0x3: /* Sector */ - ide->sector = val; - ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; - ide_other->sector = val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; - return; + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->sector = val; + ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val; + } + break; case 0x4: /* Cylinder low */ - if (ide->type == IDE_ATAPI) { - ide->sc->request_length &= 0xFF00; - ide->sc->request_length |= val; + if (ide->type & IDE_SHADOW) + break; + + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val; + ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8); } - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF00; - ide_other->sc->request_length |= val; + if (!(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); } - ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); - return; + break; case 0x5: /* Cylinder high */ - if (ide->type == IDE_ATAPI) { - ide->sc->request_length &= 0xFF; - ide->sc->request_length |= (val << 8); + if (ide->type & IDE_SHADOW) + break; + + if (!(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); } - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF; - ide_other->sc->request_length |= (val << 8); + if (!(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); } - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; + break; case 0x6: /* Drive/Head */ if (ch != ((val >> 4) & 1) + (ide->board << 1)) { + if (!ide->reset && !ide_other->reset && ide->irqstat) { + ide_irq_lower(ide); + ide->irqstat = 1; + } + ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); ch = ide_boards[ide->board]->cur_dev; @@ -1545,87 +1542,69 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_other->selected = 0; if (ide->reset || ide_other->reset) { - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - ide->reset = ide_other->reset = 0; - - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - ide->sc->phase = 1; - ide->sc->request_length = 0xEB14; - ide->sc->callback = 0.0; - ide->cylinder = 0xEB14; - } - - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = DRDY_STAT | DSC_STAT; - ide_other->sc->error = 1; - ide_other->sc->phase = 1; - ide_other->sc->request_length = 0xEB14; - ide_other->sc->callback = 0.0; - ide_other->cylinder = 0xEB14; - } + ide_reset_registers(ide); + ide_reset_registers(ide_other); - ide_set_callback(ide, 0.0); - ide_set_callback(ide_other, 0.0); ide_set_board_callback(ide->board, 0.0); - return; - } + reset = 1; + } else + ide_irq_update(ide_boards[ide->board], 1); } - ide->head = val & 0xF; - ide->lba = val & 0x40; - ide_other->head = val & 0xF; - ide_other->lba = val & 0x40; - - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); + if (!reset) { + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->drvsel = val & 0xef; + ide->lba_addr = (ide->lba_addr & 0x0ffffff) | + (ide->tf->head << 24); + } - ide_irq_update(ide); - return; + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->drvsel = val & 0xef; + ide_other->lba_addr = (ide_other->lba_addr & 0x0ffffff) | + (ide->tf->head << 24); + } + } + break; case 0x7: /* Command register */ - if (ide->type == IDE_NONE) - return; + if (ide->tf->atastat & (BSY_STAT | DRQ_STAT)) + break; + + if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) + break; ide_irq_lower(ide); ide->command = val; - ide->error = 0; - if (ide->type == IDE_ATAPI) - ide->sc->error = 0; + ide->tf->error = 0; - if (((val >= WIN_RECAL) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT; - else - ide->atastat = READY_STAT | BSY_STAT; + switch (val) { + case WIN_RECAL ... 0x1F: + case WIN_SEEK ... 0x7F: + if (ide->type == IDE_ATAPI) + ide->tf->atastat = DRDY_STAT; + else + ide->tf->atastat = READY_STAT | BSY_STAT; - if (ide->type == IDE_ATAPI) { - ide->sc->callback = 100.0 * IDE_TIME; - ide_set_callback(ide, 100.0 * IDE_TIME); - } else { - double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0); - ide_set_callback(ide, seek_time); - } - return; - } + if (ide->type == IDE_ATAPI) { + ide->sc->callback = 100.0 * IDE_TIME; + ide_set_callback(ide, 100.0 * IDE_TIME); + } else { + double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ? + ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } + break; - switch (val) { case WIN_SRST: /* ATAPI Device Reset */ if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; + ide->tf->atastat = BSY_STAT; ide->sc->callback = 100.0 * IDE_TIME; } else - ide->atastat = DRDY_STAT; + ide->tf->atastat = DRDY_STAT; ide_set_callback(ide, 100.0 * IDE_TIME); - return; + break; case WIN_READ_MULTIPLE: /* Fatal removed in accordance with the official ATAPI reference: @@ -1634,40 +1613,42 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) disabled, the Read Multiple operation is rejected with an Aborted Com- mand error. */ ide->blockcount = 0; - /*FALLTHROUGH*/ + fallthrough; case WIN_READ: case WIN_READ_NORETRY: case WIN_READ_DMA: case WIN_READ_DMA_ALT: - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; + ide->tf->atastat = BSY_STAT; + + if (ide->type == IDE_ATAPI) ide->sc->callback = 200.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; if (ide->type == IDE_HDD) { ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); uint32_t sec_count; double wait_time; if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - // TODO make DMA timing more accurate - sec_count = ide->secount ? ide->secount : 256; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + /* 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], + ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time > xfer_time ? seek_time : xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) { - sec_count = ide->secount ? ide->secount : 256; + sec_count = ide->tf->secount ? ide->tf->secount : 256; if (sec_count > ide->blocksize) sec_count = ide->blocksize; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time + xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize == 0)) wait_time = 200.0; else { sec_count = 1; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time + xfer_time; } @@ -1675,7 +1656,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } else ide_set_callback(ide, 200.0 * IDE_TIME); ide->do_initial_read = 1; - return; + break; case WIN_WRITE_MULTIPLE: /* Fatal removed for the same reason as for WIN_READ_MULTIPLE. */ @@ -1683,18 +1664,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) /* Turn on the activity indicator *here* so that it gets turned on less times. */ ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - /*FALLTHROUGH*/ + fallthrough; case WIN_WRITE: case WIN_WRITE_NORETRY: - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->sc->pos = 0; - } else { - ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->pos = 0; - } - return; + ide->tf->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; + ide->tf->pos = 0; + break; case WIN_WRITE_DMA: case WIN_WRITE_DMA_ALT: @@ -1703,46 +1679,47 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) case WIN_IDENTIFY: /* Identify Device */ case WIN_SET_FEATURES: /* Set Features */ case WIN_READ_NATIVE_MAX: - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; + ide->tf->atastat = BSY_STAT; + + if (ide->type == IDE_ATAPI) ide->sc->callback = 200.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; if ((ide->type == IDE_HDD) && ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { - uint32_t sec_count = ide->secount ? ide->secount : 256; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + uint32_t sec_count = ide->tf->secount ? ide->tf->secount : 256; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); double wait_time = seek_time > xfer_time ? seek_time : xfer_time; ide_set_callback(ide, wait_time); - } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { - uint32_t sec_count = ide->secount ? ide->secount : 256; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || + (val == WIN_VERIFY_ONCE))) { + uint32_t sec_count = ide->tf->secount ? ide->tf->secount : 256; + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), sec_count); ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2)); } else if ((val == WIN_IDENTIFY) || (val == WIN_SET_FEATURES)) ide_callback(ide); else ide_set_callback(ide, 200.0 * IDE_TIME); - return; + break; case WIN_FORMAT: if (ide->type == IDE_ATAPI) - goto ide_bad_command; + bad = 1; else { - ide->atastat = DRQ_STAT; - ide->pos = 0; + ide->tf->atastat = DRQ_STAT; + ide->tf->pos = 0; } - return; + break; case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; + ide->tf->atastat = BSY_STAT; + + if (ide->type == IDE_ATAPI) ide->sc->callback = 30.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; ide_set_callback(ide, 30.0 * IDE_TIME); - return; + break; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ dev->cur_dev &= ~1; @@ -1753,21 +1730,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) /* Device 0. */ dev_reset(ide); - ide->atastat = BSY_STAT; - ide->error = 1; - if (ide->type == IDE_ATAPI) { - ide->sc->status = BSY_STAT; - ide->sc->error = 1; - } + ide->tf->atastat = BSY_STAT; + ide->tf->error = 1; /* Device 1. */ dev_reset(ide_other); - ide_other->atastat = BSY_STAT; - ide_other->error = 1; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = BSY_STAT; - ide_other->sc->error = 1; - } + ide_other->tf->atastat = BSY_STAT; + ide_other->tf->error = 1; /* Fire the timer. */ dev->diag = 1; @@ -1775,200 +1744,178 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_set_callback(ide, 0.0); ide_set_callback(ide_other, 0.0); ide_set_board_callback(ide->board, 200.0 * IDE_TIME); - return; + break; case WIN_PIDENTIFY: /* Identify Packet Device */ case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ case WIN_NOP: case WIN_STANDBYNOW1: case WIN_IDLENOW1: - case WIN_SETIDLE1: /* Idle */ + case WIN_SETIDLE1: /* Idle */ case WIN_CHECKPOWERMODE1: case WIN_SLEEP1: - if (ide->type == IDE_ATAPI) - ide->sc->status = BSY_STAT; - else - ide->atastat = BSY_STAT; + ide->tf->atastat = BSY_STAT; ide_callback(ide); - return; + break; case WIN_PACKETCMD: /* ATAPI Packet */ /* Skip the command callback wait, and process immediately. */ + ide->tf->pos = 0; if (ide->type == IDE_ATAPI) { ide->sc->packet_status = PHASE_IDLE; - ide->sc->pos = 0; - ide->sc->phase = 1; - ide->sc->status = DRDY_STAT | DRQ_STAT; + ide->tf->secount = 1; + ide->tf->atastat = DRDY_STAT | DRQ_STAT; if (ide->interrupt_drq) ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ } else { - ide->atastat = BSY_STAT; + ide->tf->atastat = BSY_STAT; ide_set_callback(ide, 200.0 * IDE_TIME); - ide->pos = 0; } - return; + break; - case 0xF0: + case 0xf0: default: -ide_bad_command: - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - } - ide_irq_raise(ide); - return; + bad = 1; + break; + } + + if (bad) { + ide->tf->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->tf->error = ABRT_ERR; + ide_irq_raise(ide); } - return; + break; + + default: + break; } } -static uint32_t +static uint16_t ide_read_data(ide_t *ide, int length) { - uint32_t temp = 0; - - if (!ide->buffer) { - switch (length) { - case 1: - return 0xff; - case 2: - return 0xffff; - case 4: - return 0xffffffff; - default: - return 0; - } - } + const uint8_t *idebufferb = (uint8_t *) ide->buffer; + const uint16_t *idebufferw = ide->buffer; + uint16_t ret = 0; + double seek_us; + double xfer_us; - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel, + ide->board, ide->type); +#endif - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; + if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || !ide->buffer) { + if (length == 2) + ret = 0xff7f; + else + ret = 0x7f; + } else if (ide->command == WIN_PACKETCMD) { if (ide->type == IDE_ATAPI) - temp = ide_atapi_packet_read(ide, length); + ret = ide_atapi_packet_read(ide, length); else { - ide_log("Drive not ATAPI (position: %i)\n", ide->pos); - return 0; + ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos); + ide->tf->pos = 0; } } else { - switch (length) { - case 1: - temp = idebufferb[ide->pos]; - ide->pos++; - break; - case 2: - temp = idebufferw[ide->pos >> 1]; - ide->pos += 2; - break; - case 4: - temp = idebufferl[ide->pos >> 2]; - ide->pos += 4; - break; - default: - return 0; - } - } - if ((ide->pos >= 512) && (ide->command != WIN_PACKETCMD)) { - ide->pos = 0; - ide->atastat = DRDY_STAT | DSC_STAT; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->packet_status = PHASE_IDLE; + if (length == 2) { + ret = idebufferw[ide->tf->pos >> 1]; + ide->tf->pos += 2; + } else { + ret = idebufferb[ide->tf->pos]; + ide->tf->pos++; } - if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || (ide->command == WIN_READ_MULTIPLE)) { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; - if (ide->command == WIN_READ_MULTIPLE) { - if (!ide->blockcount) { - uint32_t sec_count = ide->secount ? ide->secount : 256; - if (sec_count > ide->blocksize) - sec_count = ide->blocksize; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); - double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); - ide_set_callback(ide, seek_time + xfer_time); + + if (ide->tf->pos >= 512) { + ide->tf->pos = 0; + ide->tf->atastat = DRDY_STAT | DSC_STAT; + if (ide->type == IDE_ATAPI) + ide->sc->packet_status = PHASE_IDLE; + + if ((ide->command == WIN_READ) || + (ide->command == WIN_READ_NORETRY) || + (ide->command == WIN_READ_MULTIPLE)) { + ide->tf->secount--; + + if (ide->tf->secount) { + ide_next_sector(ide); + ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT; + if (ide->command == WIN_READ_MULTIPLE) { + if (!ide->blockcount) { + uint32_t cnt = ide->tf->secount ? + ide->tf->secount : 256; + if (cnt > ide->blocksize) + cnt = ide->blocksize; + seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), cnt); + xfer_us = ide_get_xfer_time(ide, 512 * cnt); + ide_set_callback(ide, seek_us + xfer_us); + } else + ide_callback(ide); } else { - ide_callback(ide); + seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), 1); + xfer_us = ide_get_xfer_time(ide, 512); + ide_set_callback(ide, seek_us + xfer_us); } - } else { - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - ide_set_callback(ide, seek_time + xfer_time); - } - } else - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } else + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } } } - return temp; + return ret; } static uint8_t ide_status(ide_t *ide, ide_t *ide_other, int ch) { - if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1))) - return 0x7f; /* Bit 7 pulled down, all other bits pulled up, per the spec. */ - else if ((ide->type == IDE_NONE) && (ch & 1)) - return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */ - else if (ide->type == IDE_ATAPI) - return (ide->sc->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - else - return ide->atastat; + uint8_t ret; + + /* Absent and is master or both are absent. */ + if (ide->type == IDE_NONE) { + /* Bit 7 pulled down, all other bits pulled up, per the spec. */ + ret = 0x7f; + /* Absent and is slave and master is present. */ + } else if (ide->type & IDE_SHADOW) { + /* On real hardware, a slave with a present master always + returns a status of 0x00. + Confirmed by the ATA-3 and ATA-4 specifications. */ + // ret = 0x00; + ret = 0x01; + } else { + ret = ide->tf->atastat; + if (ide->type == IDE_ATAPI) + ret = (ret & ~DSC_STAT) | (ide->service << 4); + } + + return ret; } uint8_t ide_readb(uint16_t addr, void *priv) { - ide_board_t *dev = (ide_board_t *) priv; - + const ide_board_t *dev = (ide_board_t *) priv; int ch; - int absent = 0; ide_t *ide; + uint8_t ret = 0xff; ch = dev->cur_dev; ide = ide_drives[ch]; - uint8_t temp = 0xff; - uint16_t tempw; - - addr |= 0x90; - addr &= 0xFFF7; - - if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) - absent = 1; /* Absent and is master or both are absent. */ - else if ((ide->type == IDE_NONE) && (ch & 1)) - absent = 2; /* Absent and is slave and master is present. */ - switch (addr & 0x7) { case 0x0: /* Data */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x00; - else { - tempw = ide_read_data(ide, 2); - temp = tempw & 0xff; - } + ret = ide_read_data(ide, 2) & 0xff; break; /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), and Bit 0 = ILI (illegal length indication). */ case 0x1: /* Error */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x01; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->error; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = ide->error; + ret = ide->tf->error; break; /* For ATAPI: @@ -1985,74 +1932,69 @@ ide_readb(uint16_t addr, void *priv) 0 1 0 Data from host 1 0 1 Status. */ case 0x2: /* Sector count */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x01; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->phase; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = ide->secount; + ret = ide->tf->secount; break; case 0x3: /* Sector */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x01; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = (uint8_t) ide->sector; + ret = (uint8_t) ide->tf->sector; break; case 0x4: /* Cylinder low */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x00; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->request_length & 0xff; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = ide->cylinder & 0xff; + ret = ide->tf->cylinder & 0xff; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("Cylinder low @ board %i, channel %i: ide->type = %i, " + "ret = %02X\n", ide->board, ide->channel, ide->type, ret); +#endif break; case 0x5: /* Cylinder high */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0x00; - else if (ide->type == IDE_ATAPI) - temp = ide->sc->request_length >> 8; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = ide->cylinder >> 8; + ret = ide->tf->cylinder >> 8; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("Cylinder high @ board %i, channel %i: ide->type = %i, " + "ret = %02X\n", ide->board, ide->channel, ide->type, ret); +#endif break; case 0x6: /* Drive/Head */ - if (absent == 1) - temp = 0x7f; - else if (absent == 2) - temp = 0xb0; + if (ide->type == IDE_NONE) + ret = 0x7f; else - temp = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); + ret = ide->tf->drvsel | ((ch & 1) ? 0xb0 : 0xa0); break; /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is DF (drive fault). */ case 0x7: /* Status */ - ide_irq_lower(ide); - temp = ide_status(ide, ide_drives[ch ^ 1], ch); + ide_irq(ide, 0, 0); + ret = ide_status(ide, ide_drives[ch ^ 1], ch); + break; + + default: break; } - ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; + ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint8_t -ide_read_alt_status(uint16_t addr, void *priv) +ide_read_alt_status(UNUSED(uint16_t addr), void *priv) { - uint8_t temp = 0xff; + uint8_t ret = 0xff; - ide_board_t *dev = (ide_board_t *) priv; + const ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; int ch; @@ -2062,18 +2004,18 @@ ide_read_alt_status(uint16_t addr, void *priv) /* Per the Seagate ATA-3 specification: Reading the alternate status does *NOT* clear the IRQ. */ - temp = ide_status(ide, ide_drives[ch ^ 1], ch); + ret = ide_status(ide, ide_drives[ch ^ 1], ch); - ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; + ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, ret); + return ret; } uint16_t ide_readw(uint16_t addr, void *priv) { - uint16_t temp = 0xffff; + uint16_t ret = 0xffff; - ide_board_t *dev = (ide_board_t *) priv; + const ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; int ch; @@ -2083,86 +2025,86 @@ ide_readw(uint16_t addr, void *priv) switch (addr & 0x7) { case 0x0: /* Data */ - temp = ide_read_data(ide, 2); + ret = ide_read_data(ide, 2); break; case 0x7: - temp = ide_readb(addr, priv) | 0xff00; + ret = ide_readb(addr, priv) | 0xff00; break; default: - temp = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); + ret = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); break; } - ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); - return temp; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret); +#endif + return ret; } static uint32_t ide_readl(uint16_t addr, void *priv) { - uint16_t temp2; - uint32_t temp = 0xffffffff; - - ide_board_t *dev = (ide_board_t *) priv; - ide_t *ide; int ch; + uint32_t ret = 0xffffffff; + + const ide_board_t *dev = (ide_board_t *) priv; ch = dev->cur_dev; ide = ide_drives[ch]; switch (addr & 0x7) { case 0x0: /* Data */ - temp2 = ide_read_data(ide, 2); + ret = ide_read_data(ide, 2); if (dev->bit32) - temp = temp2 | (ide_read_data(ide, 2) << 16); + ret |= (ide_read_data(ide, 2) << 16); else - temp = temp2 | (ide_readw(addr + 2, priv) << 16); + ret |= (ide_readw(addr + 2, priv) << 16); break; case 0x6: case 0x7: - temp = ide_readw(addr, priv) | 0xffff0000; + ret = ide_readw(addr, priv) | 0xffff0000; break; default: - temp = ide_readw(addr, priv) | (ide_readw(addr + 2, priv) << 16); + ret = ide_readw(addr, priv) | (ide_readw(addr + 2, priv) << 16); break; } - ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, temp); - return temp; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret); +#endif + return ret; } static void ide_board_callback(void *priv) { ide_board_t *dev = (ide_board_t *) priv; + ide_t *ide; -#ifdef ENABLE_IDE_LOG - ide_log("CALLBACK RESET\n"); -#endif + ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1); - dev->ide[0]->atastat = DRDY_STAT | DSC_STAT; - if (dev->ide[0]->type == IDE_ATAPI) { - if (dev->ide[0]->sc->pad0) - dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; - else - dev->ide[0]->sc->status = 0; - } + dev->cur_dev &= ~1; - dev->ide[1]->atastat = DRDY_STAT | DSC_STAT; - if (dev->ide[1]->type == IDE_ATAPI) { - if (dev->ide[1]->sc->pad0) - dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; - else - dev->ide[1]->sc->status = 0; - } + /* Reset the devices in reverse so if there's a slave without a master, + its copy of the master's task file gets reset first. */ + for (int8_t i = 1; i >= 0; i--) { + ide = dev->ide[i]; + if (ide->type == IDE_ATAPI) { + ide->tf->atastat = 0; + if (IDE_ATAPI_IS_EARLY) + ide->tf->atastat |= DRDY_STAT | DSC_STAT; + } else + ide->tf->atastat = DRDY_STAT | DSC_STAT; - dev->cur_dev &= ~1; + ide->reset = 0; + } + ide = dev->ide[0]; if (dev->diag) { dev->diag = 0; - if ((dev->ide[0]->type != IDE_ATAPI) || dev->ide[0]->sc->pad0) - ide_irq_raise(dev->ide[0]); + if ((ide->type != IDE_ATAPI) || IDE_ATAPI_IS_EARLY) + ide_irq_raise(ide); } } @@ -2170,15 +2112,10 @@ static void atapi_error_no_ready(ide_t *ide) { ide->command = 0; - if (ide->type == IDE_ATAPI) { - ide->sc->status = ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - ide->sc->pos = 0; - } else { - ide->atastat = ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; - } + ide->tf->atastat = ERR_STAT | DSC_STAT; + ide->tf->error = ABRT_ERR; + ide->tf->pos = 0; + ide_irq_raise(ide); } @@ -2187,151 +2124,151 @@ ide_callback(void *priv) { int snum; int ret = 0; - + uint8_t err = 0x00; + int chk_chs = 0; ide_t *ide = (ide_t *) priv; + ide_bm_t *bm = ide_boards[ide->board]->bm; - ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset, ide->channel); - - if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { - if (ide->type != IDE_HDD) { - atapi_error_no_ready(ide); - return; - } - if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F) && !ide->lba) { - if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || !ide->sector || (ide->sector > ide->spt)) - goto id_not_found; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } + ide_log("ide_callback(%i): %02X\n", ide->channel, ide->command); switch (ide->command) { - /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, - Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ + case WIN_SEEK ... 0x7f: + chk_chs = !ide->tf->lba; + if (ide->type == IDE_ATAPI) + atapi_error_no_ready(ide); + else { + if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc) || + !ide->tf->sector || (ide->tf->sector > ide->spt))) + err = IDNF_ERR; + else { + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + } + } + break; + + case WIN_RECAL ... 0x1f: + if (ide->type == IDE_ATAPI) + atapi_error_no_ready(ide); + else { + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + } + break; + + /* Initialize the Task File Registers as follows: + Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, + Cylinder Low = 14h, Cylinder High = EBh and Drive/Head = 00h. */ case WIN_SRST: /*ATAPI Device Reset */ + ide->tf->error = 1; /*Device passed*/ - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = 1; - ide->sector = 1; + ide->tf->secount = 1; + ide->tf->sector = 1; ide_set_signature(ide); + ide->tf->atastat = DRDY_STAT | DSC_STAT; if (ide->type == IDE_ATAPI) { - ide->sc->error = 1; if (ide->device_reset) ide->device_reset(ide->sc); - if (ide->sc->pad0) /* pad0 = early */ - ide->sc->status = DRDY_STAT | DSC_STAT; - else - ide->sc->status = 0; + if (!IDE_ATAPI_IS_EARLY) + ide->tf->atastat = 0; } + ide_irq_raise(ide); - if ((ide->type == IDE_ATAPI) && !ide->sc->pad0) + + if ((ide->type == IDE_ATAPI) && !IDE_ATAPI_IS_EARLY) ide->service = 0; - return; + break; case WIN_NOP: case WIN_STANDBYNOW1: case WIN_IDLENOW1: case WIN_SETIDLE1: - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; - else - ide->atastat = DRDY_STAT | DSC_STAT; + ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); - return; + break; case WIN_CHECKPOWERMODE1: case WIN_SLEEP1: - if (ide->type == IDE_ATAPI) { - ide->sc->phase = 0xFF; - ide->sc->status = DRDY_STAT | DSC_STAT; - } - ide->secount = 0xFF; - ide->atastat = DRDY_STAT | DSC_STAT; + ide->tf->secount = 0xff; + ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); - return; + break; case WIN_READ: case WIN_READ_NORETRY: if (ide->type == IDE_ATAPI) { ide_set_signature(ide); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } + err = ABRT_ERR; + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + hdd_image_read(ide->hdd_num, ide_get_sector(ide), + ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); + } - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); - ide->sector_pos++; - ide->pos = 0; + ide->sector_pos++; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->tf->pos = 0; + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); + ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + } + break; case WIN_READ_DMA: case WIN_READ_DMA_ALT: - if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { + if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) { ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) { + err = ABRT_ERR; + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - ide->sector_pos = 0; - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->pos = 0; - - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - /* We should not abort - we should simply wait for the host to start DMA. */ - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - 0, ide_bm[ide->board]->priv); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide, 6.0 * IDE_TIME); - return; - } else if (ret == 1) { - /*DMA successful*/ - ide_log("IDE %i: DMA read successful\n", ide->channel); - - ide->atastat = DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + err = IDNF_ERR; + } else { + ide->sector_pos = 0; + if (ide->tf->secount) + ide->sector_pos = ide->tf->secount; + else + ide->sector_pos = 256; + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); + + ide->tf->pos = 0; + + if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + /* We should not abort - we should simply wait for the host to start DMA. */ + ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv); + if (ret == 2) { + /* Bus master DMA disabled, simply wait for the host to enable DMA. */ + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_set_callback(ide, 6.0 * IDE_TIME); + return; + } else if (ret == 1) { + /* DMA successful */ + ide_log("IDE %i: DMA read successful\n", ide->channel); + + ide->tf->atastat = DRDY_STAT | DSC_STAT; + + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } else { + /* Bus master DMAS error, abort the command. */ + ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); + err = ABRT_ERR; + } } else { - /* Bus master DMAS error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; + ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); + err = ABRT_ERR; } - } else { - ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); - goto abort_cmd; } - return; + break; case WIN_READ_MULTIPLE: /* According to the official ATA reference: @@ -2341,99 +2278,101 @@ ide_callback(void *priv) disabled, the Read Multiple operation is rejected with an Aborted Com- mand error. */ if ((ide->type == IDE_ATAPI) || !ide->blocksize) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } + err = ABRT_ERR; + else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + hdd_image_read(ide->hdd_num, ide_get_sector(ide), + ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); + } - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); - ide->sector_pos++; - ide->pos = 0; + ide->sector_pos++; + ide->tf->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - if (!ide->blockcount) - ide_irq_raise(ide); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize) - ide->blockcount = 0; - return; + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + if (!ide->blockcount) + ide_irq_raise(ide); + ide->blockcount++; + if (ide->blockcount >= ide->blocksize) + ide->blockcount = 0; + } + break; case WIN_WRITE: case WIN_WRITE_NORETRY: +#ifdef ENABLE_IDE_LOG + off64_t sector = ide_get_sector(ide); +#endif if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide_irq_raise(ide); - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos = 0; - ide_next_sector(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + err = ABRT_ERR; + else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ide_irq_raise(ide); + ide->tf->secount--; + if (ide->tf->secount) { + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->tf->pos = 0; + ide_next_sector(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + } else { + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } } - return; + ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, sector); + break; case WIN_WRITE_DMA: case WIN_WRITE_DMA_ALT: - if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board]) { + if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) { ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); - goto abort_cmd; - } - if (!ide->lba && (ide->cfg_spt == 0)) { + err = ABRT_ERR; + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; + err = IDNF_ERR; + } else { + if (!ide_boards[ide->board]->force_ata3 && (bm != NULL) && bm->dma) { + if (ide->tf->secount) + ide->sector_pos = ide->tf->secount; + else + ide->sector_pos = 256; - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - 1, ide_bm[ide->board]->priv); + ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 1, bm->priv); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide, 6.0 * IDE_TIME); - return; - } else if (ret == 1) { - /*DMA successful*/ - ide_log("IDE %i: DMA write successful\n", ide->channel); + if (ret == 2) { + /* Bus master DMA disabled, simply wait for the host to enable DMA. */ + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide_set_callback(ide, 6.0 * IDE_TIME); + return; + } else if (ret == 1) { + /* DMA successful */ + ide_log("IDE %i: DMA write successful\n", ide->channel); - hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); + hdd_image_write(ide->hdd_num, ide_get_sector(ide), + ide->sector_pos, ide->sector_buffer); - ide->atastat = DRDY_STAT | DSC_STAT; + ide->tf->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } else { + /* Bus master DMA error, abort the command. */ + ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); + err = ABRT_ERR; + } } else { - /* Bus master DMA error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; + ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); + err = ABRT_ERR; } - } else { - ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); - goto abort_cmd; } - - return; + break; case WIN_WRITE_MULTIPLE: /* According to the official ATA reference: @@ -2443,164 +2382,165 @@ ide_callback(void *priv) disabled, the Read Multiple operation is rejected with an Aborted Com- mand error. */ if ((ide->type == IDE_ATAPI) || !ide->blocksize) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize || ide->secount == 1) { - ide->blockcount = 0; - ide_irq_raise(ide); - } - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos = 0; - ide_next_sector(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + err = ABRT_ERR; + else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ide->blockcount++; + if (ide->blockcount >= ide->blocksize || ide->tf->secount == 1) { + ide->blockcount = 0; + ide_irq_raise(ide); + } + ide->tf->secount--; + if (ide->tf->secount) { + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->tf->pos = 0; + ide_next_sector(ide); + } else { + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + } } - return; + break; case WIN_VERIFY: case WIN_VERIFY_ONCE: if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - ide->pos = 0; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + err = ABRT_ERR; + else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + ide->tf->pos = 0; + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + } + break; case WIN_FORMAT: if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (!ide->lba && (ide->cfg_spt == 0)) - goto id_not_found; - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); + err = ABRT_ERR; + else if (!ide->tf->lba && (ide->cfg_spt == 0)) + err = IDNF_ERR; + else { + hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->tf->secount); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + } + break; case WIN_SPECIFY: /* Initialize Drive Parameters */ if (ide->type == IDE_ATAPI) - goto abort_cmd; - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - ide->cfg_spt = ide->secount; - ide->cfg_hpc = ide->head + 1; + err = ABRT_ERR; + else { + if (ide->cfg_spt == 0) { + /* Only accept after RESET or DIAG. */ + ide->cfg_spt = ide->tf->secount; + ide->cfg_hpc = ide->tf->head + 1; + } + ide->command = 0x00; + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide->tf->error = 1; + ide_irq_raise(ide); } - ide->command = 0x00; - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - return; + break; case WIN_PIDENTIFY: /* Identify Packet Device */ if (ide->type == IDE_ATAPI) { ide_identify(ide); - ide->pos = 0; - ide->sc->phase = 2; - ide->sc->pos = 0; - ide->sc->error = 0; - ide->sc->status = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->tf->pos = 0; + ide->tf->phase = 2; + ide->tf->error = 0; + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide_irq_raise(ide); - return; - } - goto abort_cmd; + } else + err = ABRT_ERR; + break; case WIN_SET_MULTIPLE_MODE: - if (ide->type == IDE_ATAPI) - goto abort_cmd; - if ((ide->secount < 2) || (ide->secount > hdd[ide->hdd_num].max_multiple_block)) - goto abort_cmd; - ide->blocksize = ide->secount; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + if ((ide->type == IDE_ATAPI) || (ide->tf->secount < 2) || + (ide->tf->secount > hdd[ide->hdd_num].max_multiple_block)) + err = ABRT_ERR; + else { + ide->blocksize = ide->tf->secount; + ide->tf->atastat = DRDY_STAT | DSC_STAT; + + ide_irq_raise(ide); + } + break; case WIN_SET_FEATURES: if ((ide->type == IDE_NONE) || !ide_set_features(ide)) - goto abort_cmd; + err = ABRT_ERR; + else { + ide->tf->atastat = DRDY_STAT | DSC_STAT; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->pos = 0; - } + if (ide->type == IDE_ATAPI) + ide->tf->pos = 0; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + ide_irq_raise(ide); + } + break; case WIN_READ_NATIVE_MAX: - if (ide->type != IDE_HDD) - goto abort_cmd; - snum = hdd[ide->hdd_num].spt; - snum *= hdd[ide->hdd_num].hpc; - snum *= hdd[ide->hdd_num].tracks; - ide_set_sector(ide, snum - 1); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + if (ide->type == IDE_HDD) { + snum = hdd[ide->hdd_num].spt; + snum *= hdd[ide->hdd_num].hpc; + snum *= hdd[ide->hdd_num].tracks; + ide_set_sector(ide, snum - 1); + ide->tf->atastat = DRDY_STAT | DSC_STAT; + ide_irq_raise(ide); + } else + err = ABRT_ERR; + break; case WIN_IDENTIFY: /* Identify Device */ - if (ide->type != IDE_HDD) { - ide_set_signature(ide); - goto abort_cmd; - } else { + if (ide->type == IDE_HDD) { ide_identify(ide); - ide->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + ide->tf->pos = 0; + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide_irq_raise(ide); + } else { + ide_set_signature(ide); + err = ABRT_ERR; } - return; + break; case WIN_PACKETCMD: /* ATAPI Packet */ - if (ide->type != IDE_ATAPI) - goto abort_cmd; - - ide_atapi_callback(ide); - return; + if (ide->type == IDE_ATAPI) + ide_atapi_callback(ide); + else + err = ABRT_ERR; + break; - case 0xFF: - goto abort_cmd; + default: + case 0xff: + err = ABRT_ERR; + break; } -abort_cmd: - ide->command = 0; - if (ide->type == IDE_ATAPI) { - ide->sc->status = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->sc->error = ABRT_ERR; - ide->sc->pos = 0; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; - } - ide_irq_raise(ide); - return; + if (err != 0x00) { + ide->tf->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; + ide->tf->error = err; -id_not_found: - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = IDNF_ERR; - ide->pos = 0; - ide_irq_raise(ide); + ide->tf->pos = 0; + + ide_irq_raise(ide); + } } uint8_t ide_read_ali_75(void) { - ide_t *ide0; - ide_t *ide1; - int ch0; - int ch1; - uint8_t ret = 0x00; + const ide_t *ide0; + const ide_t *ide1; + int ch0; + int ch1; + uint8_t ret = 0x00; ch0 = ide_boards[0]->cur_dev; ch1 = ide_boards[1]->cur_dev; @@ -2622,141 +2562,85 @@ ide_read_ali_75(void) uint8_t ide_read_ali_76(void) { - ide_t *ide0; - ide_t *ide1; - int ch0; - int ch1; - uint8_t ret = 0x00; + const ide_t *ide0; + const ide_t *ide1; + int ch0; + int ch1; + uint8_t ret = 0x00; ch0 = ide_boards[0]->cur_dev; ch1 = ide_boards[1]->cur_dev; ide0 = ide_drives[ch0]; ide1 = ide_drives[ch1]; - if (ide1->atastat & BSY_STAT) + if (ide1->tf->atastat & BSY_STAT) ret |= 0x40; - if (ide1->atastat & DRQ_STAT) + if (ide1->tf->atastat & DRQ_STAT) ret |= 0x20; - if (ide1->atastat & ERR_STAT) + if (ide1->tf->atastat & ERR_STAT) ret |= 0x10; - if (ide0->atastat & BSY_STAT) + if (ide0->tf->atastat & BSY_STAT) ret |= 0x04; - if (ide0->atastat & DRQ_STAT) + if (ide0->tf->atastat & DRQ_STAT) ret |= 0x02; - if (ide0->atastat & ERR_STAT) + if (ide0->tf->atastat & ERR_STAT) ret |= 0x01; return ret; } void -ide_set_handlers(uint8_t board) -{ - if (ide_boards[board] == NULL) - return; - - if (ide_boards[board]->base_main) { - io_sethandler(ide_boards[board]->base_main, 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } - - if (ide_boards[board]->side_main) { - io_sethandler(ide_boards[board]->side_main, 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); - } -} - -void -ide_remove_handlers(uint8_t board) -{ - if (ide_boards[board] == NULL) - return; - - if (ide_boards[board]->base_main) { - io_removehandler(ide_boards[board]->base_main, 8, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } +ide_handlers(uint8_t board, int set) +{ + if (ide_boards[board] != NULL) { + if (ide_boards[board]->base[0]) { + io_handler(set, ide_boards[board]->base[0], 8, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); + } - if (ide_boards[board]->side_main) { - io_removehandler(ide_boards[board]->side_main, 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); + if (ide_boards[board]->base[1]) { + io_handler(set, ide_boards[board]->base[1], 1, + ide_read_alt_status, NULL, NULL, + ide_write_devctl, NULL, NULL, + ide_boards[board]); + } } } void -ide_pri_enable(void) -{ - ide_set_handlers(0); -} - -void -ide_pri_disable(void) -{ - ide_remove_handlers(0); -} - -void -ide_sec_enable(void) -{ - ide_set_handlers(1); -} - -void -ide_sec_disable(void) -{ - ide_remove_handlers(1); -} - -void -ide_set_base(int board, uint16_t port) -{ - ide_log("ide_set_base(%i, %04X)\n", board, port); - - if (ide_boards[board] == NULL) - return; - - ide_boards[board]->base_main = port; -} - -void -ide_set_side(int board, uint16_t port) +ide_set_base_addr(int board, int base, uint16_t port) { - ide_log("ide_set_side(%i, %04X)\n", board, port); - - if (ide_boards[board] == NULL) - return; + ide_log("ide_set_base_addr(%i, %i, %04X)\n", board, base, port); - ide_boards[board]->side_main = port; + if (ide_boards[board] != NULL) + ide_boards[board]->base[base] = port; } static void ide_clear_bus_master(int board) { - if (ide_bm[board]) { - free(ide_bm[board]); - ide_bm[board] = NULL; + ide_bm_t *bm = ide_boards[board]->bm; + + if (bm != NULL) { + free(bm); + ide_boards[board]->bm = NULL; } } -/* This so drives can be forced to ATA-3 (no DMA) for machines that hide the on-board PCI IDE controller - (eg. Packard Bell PB640 and ASUS P/I-P54TP4XE), breaking DMA drivers unless this is done. */ +/* + This so drives can be forced to ATA-3 (no DMA) for machines that hide the + on-board PCI IDE controller (eg. Packard Bell PB640 and ASUS P/I-P54TP4XE), + breaking DMA drivers unless this is done. + */ extern void ide_board_set_force_ata3(int board, int force_ata3) { ide_log("ide_board_set_force_ata3(%i, %i)\n", board, force_ata3); - if ((ide_boards[board] == NULL) || !ide_boards[board]->inited) - return; - - ide_boards[board]->force_ata3 = force_ata3; + if ((ide_boards[board] != NULL) && ide_boards[board]->inited) + ide_boards[board]->force_ata3 = force_ata3; } static void @@ -2784,28 +2668,31 @@ ide_board_close(int board) dev = ide_drives[c]; - if (dev == NULL) - continue; - - if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) - hdd_image_close(dev->hdd_num); + if (dev != NULL) { + if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) + hdd_image_close(dev->hdd_num); - if (dev->type == IDE_ATAPI) - dev->sc->status = DRDY_STAT | DSC_STAT; + if (dev->type == IDE_ATAPI) + dev->tf->atastat = DRDY_STAT | DSC_STAT; + else if (!(dev->type & IDE_SHADOW) && (dev->tf != NULL)) { + free(dev->tf); + dev->tf = NULL; + } - if (dev->buffer) { - free(dev->buffer); - dev->buffer = NULL; - } + if (dev->buffer) { + free(dev->buffer); + dev->buffer = NULL; + } - if (dev->sector_buffer) { - free(dev->sector_buffer); - dev->buffer = NULL; - } + if (dev->sector_buffer) { + free(dev->sector_buffer); + dev->buffer = NULL; + } - if (dev) { - free(dev); - ide_drives[c] = NULL; + if (dev) { + free(dev); + ide_drives[c] = NULL; + } } } @@ -2849,8 +2736,7 @@ ide_board_setup(int board) ide_log("Found IDE hard disk on channel %i\n", ch); loadhd(ide_drives[ch], d, hdd[d].fn); if (ide_drives[ch]->sector_buffer == NULL) - ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256 * 512); - memset(ide_drives[ch]->sector_buffer, 0, 256 * 512); + ide_drives[ch]->sector_buffer = (uint8_t *) calloc(1, 256 * 512); if (++c >= 2) break; } @@ -2869,7 +2755,7 @@ ide_board_setup(int board) ide_set_signature(dev); dev->mdma_mode = (1 << ide_get_max(dev, TYPE_PIO)); - dev->error = 1; + dev->tf->error = 1; if (dev->type != IDE_HDD) dev->cfg_spt = dev->cfg_hpc = 0; if (dev->type == IDE_HDD) @@ -2887,14 +2773,15 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_log("IDE: Initializing board %i...\n", board); - ide_boards[board] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[board], 0, sizeof(ide_board_t)); + if (ide_boards[board] == NULL) + ide_boards[board] = (ide_board_t *) calloc(1, sizeof(ide_board_t)); + ide_boards[board]->irq = irq; ide_boards[board]->cur_dev = board << 1; if (type & 6) ide_boards[board]->bit32 = 1; - ide_boards[board]->base_main = base_main; - ide_boards[board]->side_main = side_main; + ide_boards[board]->base[0] = base_main; + ide_boards[board]->base[1] = side_main; ide_set_handlers(board); timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); @@ -2912,18 +2799,20 @@ ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) if (ld) return; - if (ide_boards[board]->base_main || ide_boards[board]->side_main) { + if (ide_boards[board]->base[0] || ide_boards[board]->base[1]) { ide_remove_handlers(board); - ide_boards[board]->base_main = ide_boards[board]->side_main = 0; + ide_boards[board]->base[0] = ide_boards[board]->base[1] = 0; } ide_boards[board]->irq = -1; if (config->activate) { - ide_boards[board]->base_main = (config->io[0].base != ISAPNP_IO_DISABLED) ? config->io[0].base : 0x0000; - ide_boards[board]->side_main = (config->io[1].base != ISAPNP_IO_DISABLED) ? config->io[1].base : 0x0000; + ide_boards[board]->base[0] = (config->io[0].base != ISAPNP_IO_DISABLED) ? + config->io[0].base : 0x0000; + ide_boards[board]->base[1] = (config->io[1].base != ISAPNP_IO_DISABLED) ? + config->io[1].base : 0x0000; - if (ide_boards[board]->base_main && ide_boards[board]->side_main) + if (ide_boards[board]->base[0] && ide_boards[board]->base[1]) ide_set_handlers(board); if (config->irq[0].irq != ISAPNP_IRQ_DISABLED) @@ -2947,9 +2836,10 @@ ide_ter_init(const device_t *info) if (irq < 0) { ide_board_init(2, -1, 0, 0, 0); if (irq == -1) - isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); + isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), + ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); } else { - ide_board_init(2, irq, 0x168, 0x36e, 0); + ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0); } return (ide_boards[2]); @@ -2957,7 +2847,7 @@ ide_ter_init(const device_t *info) /* Close a standalone IDE unit. */ static void -ide_ter_close(void *priv) +ide_ter_close(UNUSED(void *priv)) { ide_board_close(2); } @@ -2978,17 +2868,17 @@ ide_qua_init(const device_t *info) if (irq < 0) { ide_board_init(3, -1, 0, 0, 0); if (irq == -1) - isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); - } else { - ide_board_init(3, irq, 0x1e8, 0x3ee, 0); - } + isapnp_add_card(ide_qua_pnp_rom, sizeof(ide_qua_pnp_rom), + ide_pnp_config_changed, NULL, NULL, NULL, (void *) 3); + } else + ide_board_init(3, irq, HDC_QUATERNARY_BASE, HDC_QUATERNARY_SIDE, 0); return (ide_boards[3]); } /* Close a standalone IDE unit. */ static void -ide_qua_close(void *priv) +ide_qua_close(UNUSED(void *priv)) { ide_board_close(3); } @@ -3009,15 +2899,20 @@ ide_xtide_close(void) void ide_set_bus_master(int board, - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), - void (*set_irq)(int channel, void *priv), void *priv) + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv), + void (*set_irq)(uint8_t status, void *priv), void *priv) { - if (ide_bm[board] == NULL) - ide_bm[board] = (ide_bm_t *) malloc(sizeof(ide_bm_t)); + ide_bm_t *bm; - ide_bm[board]->dma = dma; - ide_bm[board]->set_irq = set_irq; - ide_bm[board]->priv = priv; + if (ide_boards[board]->bm == NULL) { + bm = (ide_bm_t *) calloc(1, sizeof(ide_bm_t)); + ide_boards[board]->bm = bm; + } else + bm = ide_boards[board]->bm; + + bm->dma = dma; + bm->set_irq = set_irq; + bm->priv = priv; } static void * @@ -3026,20 +2921,18 @@ ide_init(const device_t *info) ide_log("Initializing IDE...\n"); switch (info->local) { - case 0: /* ISA, single-channel */ - case 1: /* ISA, dual-channel */ - case 2: /* VLB, single-channel */ - case 3: /* VLB, dual-channel */ - case 4: /* PCI, single-channel */ - case 5: /* PCI, dual-channel */ + case 0 ... 5: ide_board_init(0, 14, 0x1f0, 0x3f6, info->local); if (info->local & 1) ide_board_init(1, 15, 0x170, 0x376, info->local); break; + + default: + break; } - return ide_drives; + return (void *) (intptr_t) -1; } static void @@ -3047,11 +2940,17 @@ ide_drive_reset(int d) { ide_log("Resetting IDE drive %i...\n", d); - ide_drives[d]->channel = d; - ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; - ide_drives[d]->service = 0; - ide_drives[d]->board = d >> 1; - ide_drives[d]->selected = !(d & 1); + if ((d & 1) && (ide_drives[d]->type == IDE_NONE) && (ide_drives[d ^ 1]->type != IDE_NONE)) { + ide_drives[d]->type = ide_drives[d ^ 1]->type | IDE_SHADOW; + free(ide_drives[d]->tf); + ide_drives[d]->tf = ide_drives[d ^ 1]->tf; + } else + ide_drives[d]->tf->atastat = DRDY_STAT | DSC_STAT; + + ide_drives[d]->channel = d; + ide_drives[d]->service = 0; + ide_drives[d]->board = d >> 1; + ide_drives[d]->selected = !(d & 1); timer_stop(&ide_drives[d]->timer); if (ide_boards[d >> 1]) { @@ -3085,33 +2984,45 @@ ide_board_reset(int board) ide_drive_reset(d); } +void +ide_drives_set_shadow(void) +{ + for (uint8_t d = 0; d < IDE_NUM; d++) { + if (ide_drives[d] == NULL) + continue; + + if ((d & 1) && (ide_drives[d]->type == IDE_NONE) && (ide_drives[d ^ 1]->type != IDE_NONE)) { + ide_drives[d]->type = ide_drives[d ^ 1]->type | IDE_SHADOW; + if (ide_drives[d]->tf != NULL) + free(ide_drives[d]->tf); + ide_drives[d]->tf = ide_drives[d ^ 1]->tf; + } + } +} + /* Reset a standalone IDE unit. */ static void -ide_reset(void *p) +ide_reset(UNUSED(void *priv)) { ide_log("Resetting IDE...\n"); - if (ide_boards[0] != NULL) - ide_board_reset(0); - - if (ide_boards[1] != NULL) - ide_board_reset(1); + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) + ide_board_reset(i); + } } /* Close a standalone IDE unit. */ static void -ide_close(void *priv) +ide_close(UNUSED(void *priv)) { ide_log("Closing IDE...\n"); - if (ide_boards[0] != NULL) { - ide_board_close(0); - ide_boards[0] = NULL; - } - - if (ide_boards[1] != NULL) { - ide_board_close(1); - ide_boards[1] = NULL; + for (uint8_t i = 0; i < 2; i++) { + if (ide_boards[i] != NULL) { + ide_board_close(i); + ide_boards[i] = NULL; + } } } @@ -3206,7 +3117,7 @@ static const device_config_t ide_ter_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 10, + .default_int = HDC_TERTIARY_IRQ, .file_filter = "", .spinner = { 0 }, .selection = { @@ -3232,7 +3143,7 @@ static const device_config_t ide_qua_config[] = { .description = "IRQ", .type = CONFIG_SELECTION, .default_string = "", - .default_int = 11, + .default_int = HDC_QUATERNARY_IRQ, .file_filter = "", .spinner = { 0 }, .selection = { diff --git a/src/disk/hdc_ide_ali5213.c b/src/disk/hdc_ide_ali5213.c new file mode 100644 index 0000000000..eee3844c4c --- /dev/null +++ b/src/disk/hdc_ide_ali5213.c @@ -0,0 +1,267 @@ +/* + * 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. + * + * Implementation of the ALi M1489 chipset. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2020-2021 Tiseno100. + * Copyright 2020-2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_ALI5213_LOG +int ali5213_do_log = ENABLE_ALI5213_LOG; + +static void +ali5213_log(const char *fmt, ...) +{ + va_list ap; + + if (ali5213_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ali5213_log(fmt, ...) +#endif + +typedef struct ali5213_t { + uint8_t index; + uint8_t chip_id; + + uint8_t regs[256]; +} ali5213_t; + +static void +ali5213_ide_handler(ali5213_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0x01] & 0x01) { + ide_pri_enable(); + if (!(dev->regs[0x35] & 0x40)) + ide_sec_enable(); + } +} + +static void +ali5213_write(uint16_t addr, uint8_t val, void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + ali5213_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0xf4: /* Usually it writes 30h here */ + dev->chip_id = val; + break; + + case 0xf8: + dev->index = val; + break; + + case 0xfc: + if (dev->chip_id != 0x30) + break; + + switch (dev->index) { + case 0x01: /* IDE Configuration Register */ + dev->regs[dev->index] = val & 0x8f; + ali5213_ide_handler(dev); + break; + case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ + case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ + case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ + case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ + case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ + case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ + case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ + case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ + case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ + case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ + case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ + case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ + case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ + case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ + case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ + case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ + case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ + case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ + case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ + case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x07: /* Buffer Mode Register 1 */ + dev->regs[dev->index] = val; + break; + case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ + dev->regs[dev->index] = val & 0xc3; + break; + case 0x0a: /* Buffer Mode Register 2 */ + dev->regs[dev->index] = val & 0x4f; + break; + case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ + case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ + case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ + case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ + dev->regs[dev->index] = val & 0x03; + break; + case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ + case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ + case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ + dev->regs[dev->index] = val; + ali5213_ide_handler(dev); + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +ali5213_read(uint16_t addr, void *priv) +{ + const ali5213_t *dev = (ali5213_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0xf4: + ret = dev->chip_id; + break; + case 0xfc: + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + ali5213_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +ali5213_reset(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0x00] = 0x57; + dev->regs[0x01] = 0x02; + dev->regs[0x08] = 0xff; + dev->regs[0x09] = 0x41; + dev->regs[0x0c] = 0x02; + dev->regs[0x0e] = 0x02; + dev->regs[0x10] = 0x02; + dev->regs[0x12] = 0x02; + dev->regs[0x34] = 0xff; + dev->regs[0x35] = 0x01; + + ali5213_ide_handler(dev); +} + +static void +ali5213_close(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + free(dev); +} + +static void * +ali5213_init(UNUSED(const device_t *info)) +{ + ali5213_t *dev = (ali5213_t *) calloc(1, sizeof(ali5213_t)); + + /* M5213/M1489 IDE controller + F4h Chip ID we write always 30h onto it + F8h Index Port + FCh Data Port + */ + io_sethandler(0x0f4, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0f8, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0fc, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + ali5213_reset(dev); + + return dev; +} + +const device_t ide_ali1489_device = { + .name = "ALi M1489 IDE", + .internal_name = "ali1489_ide", + .flags = 0, + .local = 1, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_ali5213_device = { + .name = "ALi M5213", + .internal_name = "ali5213", + .flags = 0, + .local = 0, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 6f8580cba2..3e77730a2b 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -37,14 +37,20 @@ #include <86box/zip.h> #include <86box/mo.h> -typedef struct -{ - uint8_t vlb_idx, id, - in_cfg, single_channel, - pci, regs[256]; +typedef struct cmd640_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t irq_state; + uint8_t pci_slot; + uint8_t pad0; + uint8_t regs[256]; uint32_t local; - int slot, irq_mode[2], - irq_pin, irq_line; + int irq_mode[2]; + int irq_pin; + int irq_line; } cmd640_t; static int next_id = 0; @@ -68,34 +74,52 @@ cmd640_log(const char *fmt, ...) #endif void -cmd640_set_irq(int channel, void *priv) +cmd640_set_irq_0(uint8_t status, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - int irq = !!(channel & 0x40); + int irq = !!(status & 0x04); - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 1)) + return; + + if (irq) { + if (dev->irq_mode[0] == 1) + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picint(1 << 14); } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } + if (dev->irq_mode[0] == 1) + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picintc(1 << 14); } +} + +void +cmd640_set_irq_1(uint8_t status, void *priv) +{ + cmd640_t *dev = (cmd640_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + if (!(dev->channels & 2)) + return; - channel &= 0x01; if (irq) { - if (dev->irq_mode[channel] == 1) - pci_set_irq(dev->slot, dev->irq_pin); + if (dev->irq_mode[1] == 1) + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picint(1 << (14 + channel)); + picint(1 << 15); } else { - if (dev->irq_mode[channel] == 1) - pci_clear_irq(dev->slot, dev->irq_pin); + if (dev->irq_mode[1] == 1) + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picintc(1 << (14 + channel)); + picintc(1 << 15); } } @@ -105,40 +129,41 @@ cmd640_ide_handlers(cmd640_t *dev) uint16_t main; uint16_t side; - ide_pri_disable(); + if (dev->channels & 0x01) { + ide_pri_disable(); - if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); - side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; - } else { - main = 0x1f0; - side = 0x3f6; - } - - ide_set_base(0, main); - ide_set_side(0, side); + if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); + side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; + } else { + main = 0x1f0; + side = 0x3f6; + } - if (dev->regs[0x04] & 0x01) - ide_pri_enable(); + ide_set_base(0, main); + ide_set_side(0, side); - if (dev->single_channel) - return; + if (dev->regs[0x04] & 0x01) + ide_pri_enable(); + } - ide_sec_disable(); + if (dev->channels & 0x02) { + ide_sec_disable(); - if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { - main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); - side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; - } else { - main = 0x170; - side = 0x376; - } + if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); + side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; + } else { + main = 0x170; + side = 0x376; + } - ide_set_base(1, main); - ide_set_side(1, side); + ide_set_base(1, main); + ide_set_side(1, side); - if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) - ide_sec_enable(); + if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) + ide_sec_enable(); + } } static void @@ -166,6 +191,9 @@ cmd640_common_write(int addr, uint8_t val, cmd640_t *dev) case 0x5b: /* Undocumented register that Linux attempts to use! */ dev->regs[addr] = val; break; + + default: + break; } } @@ -188,6 +216,9 @@ cmd640_vlb_write(uint16_t addr, uint8_t val, void *priv) if (dev->regs[0x50] & 0x80) dev->in_cfg = 0; break; + + default: + break; } } @@ -227,6 +258,9 @@ cmd640_vlb_read(uint16_t addr, void *priv) if (dev->regs[0x50] & 0x80) dev->in_cfg = 0; break; + + default: + break; } return ret; @@ -356,22 +390,49 @@ cmd640_reset(void *priv) { cmd640_t *dev = (cmd640_t *) priv; int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && + (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) zip_reset((scsi_common_t *) zip_drives[i].priv); } for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } - cmd640_set_irq(0x00, priv); - cmd640_set_irq(0x01, priv); + if (dev->channels & 0x01) + cmd640_set_irq_0(0x00, priv); + + if (dev->channels & 0x02) + cmd640_set_irq_1(0x00, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); @@ -417,6 +478,8 @@ cmd640_reset(void *priv) dev->irq_pin = PCI_INTA; dev->irq_line = 14; } else { + dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */ + if ((dev->local & 0xffff) == 0x0078) dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ @@ -449,20 +512,33 @@ cmd640_init(const device_t *info) dev->pci = !!(info->flags & DEVICE_PCI); dev->local = info->local; + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + if (info->flags & DEVICE_PCI) { device_add(&ide_pci_2ch_device); - dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot); - ide_set_bus_master(0, NULL, cmd640_set_irq, dev); - ide_set_bus_master(1, NULL, cmd640_set_irq, dev); + if (dev->channels & 0x01) + ide_set_bus_master(0, NULL, cmd640_set_irq_0, dev); + + if (dev->channels & 0x02) + ide_set_bus_master(1, NULL, cmd640_set_irq_1, dev); /* The CMD PCI-0640B IDE controller has no DMA capability, so set our devices IDE devices to force ATA-3 (no DMA). */ - ide_board_set_force_ata3(0, 1); - ide_board_set_force_ata3(1, 1); + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); - // ide_pri_disable(); +#if 0 + ide_pri_disable(); +#endif } else if (info->flags & DEVICE_VLB) { device_add(&ide_vlb_2ch_device); @@ -472,8 +548,6 @@ cmd640_init(const device_t *info) dev); } - dev->single_channel = !!(info->local & 0x20000); - next_id++; cmd640_reset(dev); @@ -485,7 +559,7 @@ const device_t ide_cmd640_vlb_device = { .name = "CMD PCI-0640B VLB", .internal_name = "ide_cmd640_vlb", .flags = DEVICE_VLB, - .local = 0x0078, + .local = 0x60078, .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, @@ -499,7 +573,63 @@ const device_t ide_cmd640_vlb_178_device = { .name = "CMD PCI-0640B VLB (Port 178h)", .internal_name = "ide_cmd640_vlb_178", .flags = DEVICE_VLB, - .local = 0x0178, + .local = 0x60178, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd640_vlb_pri_device = { + .name = "CMD PCI-0640B VLB", + .internal_name = "ide_cmd640_vlb", + .flags = DEVICE_VLB, + .local = 0x20078, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd640_vlb_pri_178_device = { + .name = "CMD PCI-0640B VLB (Port 178h)", + .internal_name = "ide_cmd640_vlb_178", + .flags = DEVICE_VLB, + .local = 0x20178, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd640_vlb_sec_device = { + .name = "CMD PCI-0640B VLB", + .internal_name = "ide_cmd640_vlb", + .flags = DEVICE_VLB, + .local = 0x40078, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd640_vlb_sec_178_device = { + .name = "CMD PCI-0640B VLB (Port 178h)", + .internal_name = "ide_cmd640_vlb_178", + .flags = DEVICE_VLB, + .local = 0x40178, .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, @@ -513,7 +643,7 @@ const device_t ide_cmd640_pci_device = { .name = "CMD PCI-0640B PCI", .internal_name = "ide_cmd640_pci", .flags = DEVICE_PCI, - .local = 0x0a, + .local = 0x6000a, .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, @@ -527,7 +657,7 @@ const device_t ide_cmd640_pci_legacy_only_device = { .name = "CMD PCI-0640B PCI (Legacy Mode Only)", .internal_name = "ide_cmd640_pci_legacy_only", .flags = DEVICE_PCI, - .local = 0x00, + .local = 0x60000, .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, @@ -550,3 +680,17 @@ const device_t ide_cmd640_pci_single_channel_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ide_cmd640_pci_single_channel_sec_device = { + .name = "CMD PCI-0640B PCI", + .internal_name = "ide_cmd640_pci_single_channel_sec", + .flags = DEVICE_PCI, + .local = 0x4000a, + .init = cmd640_init, + .close = cmd640_close, + .reset = cmd640_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index a9f5eb8835..8367b9a41a 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -37,13 +37,20 @@ #include <86box/zip.h> #include <86box/mo.h> -typedef struct -{ - uint8_t vlb_idx, single_channel, - in_cfg, regs[256]; - uint32_t local; - int slot, irq_mode[2], - irq_pin; +typedef struct cmd646_t { + uint8_t vlb_idx; + uint8_t single_channel; + uint8_t in_cfg; + uint8_t pci_slot; + + uint8_t regs[256]; + + uint32_t local; + + int irq_pin; + + int irq_mode[2]; + sff8038i_t *bm[2]; } cmd646_t; @@ -66,31 +73,41 @@ cmd646_log(const char *fmt, ...) #endif static void -cmd646_set_irq(int channel, void *priv) +cmd646_set_irq_0(uint8_t status, void *priv) { cmd646_t *dev = (cmd646_t *) priv; - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } - } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); + sff_bus_master_set_irq(status, dev->bm[0]); } -static int -cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +static void +cmd646_set_irq_1(uint8_t status, void *priv) { cmd646_t *dev = (cmd646_t *) priv; - return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + sff_bus_master_set_irq(status, dev->bm[1]); +} + +static int +cmd646_bus_master_dma_0(uint8_t *data, int transfer_length, int out, void *priv) +{ + const cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(data, transfer_length, out, dev->bm[0]); +} + +static int +cmd646_bus_master_dma_1(uint8_t *data, int transfer_length, int out, void *priv) +{ + const cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(data, transfer_length, out, dev->bm[1]); } static void @@ -98,7 +115,10 @@ cmd646_ide_handlers(cmd646_t *dev) { uint16_t main; uint16_t side; - int irq_mode[2] = { 0, 0 }; + int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; + + sff_set_slot(dev->bm[0], dev->pci_slot); + sff_set_slot(dev->bm[1], dev->pci_slot); ide_pri_disable(); @@ -114,10 +134,9 @@ cmd646_ide_handlers(cmd646_t *dev) ide_set_side(0, side); if (dev->regs[0x09] & 0x01) - irq_mode[0] = 1; + irq_mode[0] = IRQ_MODE_PCI_IRQ_PIN; - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); if (dev->regs[0x04] & 0x01) ide_pri_enable(); @@ -141,8 +160,7 @@ cmd646_ide_handlers(cmd646_t *dev) if (dev->regs[0x09] & 0x04) irq_mode[1] = 1; - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) ide_sec_enable(); @@ -262,6 +280,9 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) case 0x78 ... 0x7f: sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); break; + + default: + break; } } @@ -308,8 +329,8 @@ cmd646_reset(void *priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } - cmd646_set_irq(0x00, priv); - cmd646_set_irq(0x01, priv); + cmd646_set_irq_0(0x00, priv); + cmd646_set_irq_1(0x00, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); @@ -377,7 +398,10 @@ cmd646_init(const device_t *info) device_add(&ide_pci_2ch_device); - dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev); + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot); dev->single_channel = !!(info->local & 0x20000); @@ -385,17 +409,14 @@ cmd646_init(const device_t *info) if (!dev->single_channel) dev->bm[1] = device_add_inst(&sff8038i_device, 2); - ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(0, cmd646_bus_master_dma_0, cmd646_set_irq_0, dev); if (!dev->single_channel) - ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(1, cmd646_bus_master_dma_1, cmd646_set_irq_1, dev); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (!dev->single_channel) { - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } + if (!dev->single_channel) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); cmd646_reset(dev); diff --git a/src/disk/hdc_ide_opti611.c b/src/disk/hdc_ide_opti611.c index 06eecb68f3..4803312014 100644 --- a/src/disk/hdc_ide_opti611.c +++ b/src/disk/hdc_ide_opti611.c @@ -28,12 +28,14 @@ #include <86box/mem.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> - -typedef struct -{ - uint8_t tries, - in_cfg, cfg_locked, - regs[19]; +#include <86box/plat_unused.h> + +typedef struct opti611_t { + uint8_t is_sec; + uint8_t tries; + uint8_t in_cfg; + uint8_t cfg_locked; + uint8_t regs[19]; } opti611_t; static void opti611_ide_handler(opti611_t *dev); @@ -68,6 +70,9 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv) case 0x0006: dev->regs[0x06] = val; break; + + default: + break; } } @@ -88,8 +93,8 @@ opti611_cfg_writel(uint16_t addr, uint32_t val, void *priv) static uint8_t opti611_cfg_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - opti611_t *dev = (opti611_t *) priv; + uint8_t ret = 0xff; + const opti611_t *dev = (opti611_t *) priv; addr &= 0x0007; @@ -109,6 +114,9 @@ opti611_cfg_read(uint16_t addr, void *priv) case 0x0006: ret = dev->regs[addr]; break; + + default: + break; } return ret; @@ -153,7 +161,7 @@ opti611_ide_write(uint16_t addr, uint8_t val, void *priv) } static void -opti611_ide_writew(uint16_t addr, uint16_t val, void *priv) +opti611_ide_writew(uint16_t addr, UNUSED(uint16_t val), void *priv) { opti611_t *dev = (opti611_t *) priv; @@ -169,7 +177,7 @@ opti611_ide_writew(uint16_t addr, uint16_t val, void *priv) } static void -opti611_ide_writel(uint16_t addr, uint32_t val, void *priv) +opti611_ide_writel(uint16_t addr, UNUSED(uint32_t val), void *priv) { opti611_t *dev = (opti611_t *) priv; @@ -247,28 +255,54 @@ opti611_ide_readl(uint16_t addr, void *priv) static void opti611_ide_handler(opti611_t *dev) { - ide_pri_disable(); - io_removehandler(0x01f0, 0x0007, - opti611_ide_read, opti611_ide_readw, opti611_ide_readl, - opti611_ide_write, opti611_ide_writew, opti611_ide_writel, - dev); - io_removehandler(0x01f0, 0x0007, - opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, - opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, - dev); - - if (dev->in_cfg && !dev->cfg_locked) { - io_sethandler(0x01f0, 0x0007, - opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, - opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, - dev); + if (dev->is_sec) { + ide_sec_disable(); + io_removehandler(0x0170, 0x0007, + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); + io_removehandler(0x0170, 0x0007, + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); + + if (dev->in_cfg && !dev->cfg_locked) { + io_sethandler(0x0170, 0x0007, + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); + } else { + if (dev->regs[0x03] & 0x01) + ide_sec_enable(); + io_sethandler(0x0170, 0x0007, + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); + } } else { - if (dev->regs[0x03] & 0x01) - ide_pri_enable(); - io_sethandler(0x01f0, 0x0007, - opti611_ide_read, opti611_ide_readw, opti611_ide_readl, - opti611_ide_write, opti611_ide_writew, opti611_ide_writel, - dev); + ide_pri_disable(); + io_removehandler(0x01f0, 0x0007, + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); + io_removehandler(0x01f0, 0x0007, + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); + + if (dev->in_cfg && !dev->cfg_locked) { + io_sethandler(0x01f0, 0x0007, + opti611_cfg_read, opti611_cfg_readw, opti611_cfg_readl, + opti611_cfg_write, opti611_cfg_writew, opti611_cfg_writel, + dev); + } else { + if (dev->regs[0x03] & 0x01) + ide_pri_enable(); + io_sethandler(0x01f0, 0x0007, + opti611_ide_read, opti611_ide_readw, opti611_ide_readl, + opti611_ide_write, opti611_ide_writew, opti611_ide_writel, + dev); + } } } @@ -281,11 +315,13 @@ opti611_close(void *priv) } static void * -opti611_init(const device_t *info) +opti611_init(UNUSED(const device_t *info)) { opti611_t *dev = (opti611_t *) malloc(sizeof(opti611_t)); memset(dev, 0, sizeof(opti611_t)); + dev->is_sec = info->local; + dev->regs[0x12] = 0x80; dev->regs[0x03] = 0x01; dev->regs[0x05] = 0x20; @@ -310,3 +346,17 @@ const device_t ide_opti611_vlb_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ide_opti611_vlb_sec_device = { + .name = "OPTi 82C611/82C611A VLB (Secondary)", + .internal_name = "ide_opti611_vlb", + .flags = DEVICE_VLB, + .local = 1, + .init = opti611_init, + .close = opti611_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index a2c80ac7ff..631afa9312 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -27,7 +27,9 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/cdrom.h> +#include <86box/hdd.h> #include <86box/scsi_device.h> +#include <86box/scsi_disk.h> #include <86box/scsi_cdrom.h> #include <86box/dma.h> #include <86box/io.h> @@ -42,6 +44,7 @@ #include <86box/hdc_ide_sff8038i.h> #include <86box/zip.h> #include <86box/mo.h> +#include <86box/plat_unused.h> static int next_id = 0; @@ -73,7 +76,7 @@ sff_log(const char *fmt, ...) void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base) { - if (dev->base != 0x0000) { + if (dev->enabled && (dev->base != 0x0000)) { io_removehandler(dev->base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, @@ -160,6 +163,9 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv) dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); dev->ptr %= (mem_size * 1024); break; + + default: + break; } } @@ -185,6 +191,9 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv) dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); dev->ptr %= (mem_size * 1024); break; + + default: + break; } } @@ -206,13 +215,16 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) dev->ptr %= (mem_size * 1024); dev->ptr0 = val & 0xff; break; + + default: + break; } } uint8_t sff_bus_master_read(uint16_t port, void *priv) { - sff8038i_t *dev = (sff8038i_t *) priv; + const sff8038i_t *dev = (sff8038i_t *) priv; uint8_t ret = 0xff; @@ -238,6 +250,9 @@ sff_bus_master_read(uint16_t port, void *priv) case 7: ret = dev->ptr >> 24; break; + + default: + break; } sff_log("SFF-8038i Bus master BYTE read : %04X %02X\n", port, ret); @@ -248,7 +263,7 @@ sff_bus_master_read(uint16_t port, void *priv) static uint16_t sff_bus_master_readw(uint16_t port, void *priv) { - sff8038i_t *dev = (sff8038i_t *) priv; + const sff8038i_t *dev = (sff8038i_t *) priv; uint16_t ret = 0xffff; @@ -264,6 +279,9 @@ sff_bus_master_readw(uint16_t port, void *priv) case 6: ret = dev->ptr >> 16; break; + + default: + break; } sff_log("SFF-8038i Bus master WORD read : %04X %04X\n", port, ret); @@ -274,7 +292,7 @@ sff_bus_master_readw(uint16_t port, void *priv) static uint32_t sff_bus_master_readl(uint16_t port, void *priv) { - sff8038i_t *dev = (sff8038i_t *) priv; + const sff8038i_t *dev = (sff8038i_t *) priv; uint32_t ret = 0xffffffff; @@ -287,6 +305,9 @@ sff_bus_master_readl(uint16_t port, void *priv) case 4: ret = dev->ptr0 | (dev->ptr & 0xffffff00); break; + + default: + break; } sff_log("sff Bus master DWORD read : %04X %08X\n", port, ret); @@ -295,7 +316,7 @@ sff_bus_master_readl(uint16_t port, void *priv) } int -sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; #ifdef ENABLE_SFF_LOG @@ -366,64 +387,67 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi } void -sff_bus_master_set_irq(int channel, void *priv) +sff_bus_master_set_irq(uint8_t status, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; - uint8_t irq = !!(channel & 0x40); + uint8_t irq = !!(status & 0x04); - if (!(dev->status & 0x04) || (channel & 0x40)) { - dev->status &= ~0x04; - dev->status |= (channel >> 4); - } - - channel &= 0x01; + if (!(dev->status & 0x04) || (status & 0x04)) + dev->status = (dev->status & ~0x04) | status; - switch (dev->irq_mode[channel]) { - case 0: + switch (dev->irq_mode) { default: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ if (irq) - picint(1 << (14 + channel)); + picint(1 << dev->irq_line); else - picintc(1 << (14 + channel)); + picintc(1 << dev->irq_line); break; - case 1: + case IRQ_MODE_PCI_IRQ_PIN: /* Native PCI IRQ mode with interrupt pin. */ if (irq) - pci_set_irq(dev->slot, dev->irq_pin); + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); else - pci_clear_irq(dev->slot, dev->irq_pin); + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); break; - case 2: - case 5: - /* MIRQ 0 or 1. */ + case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3: + /* MIRQ 0, 1, 2, or 3. */ if (irq) - pci_set_mirq(dev->irq_mode[channel] & 1, 0); + pci_set_mirq(dev->irq_mode & 3, 0, &dev->irq_state); else - pci_clear_mirq(dev->irq_mode[channel] & 1, 0); + pci_clear_mirq(dev->irq_mode & 3, 0, &dev->irq_state); break; - case 3: + /* TODO: Redo this as a MIRQ. */ + case IRQ_MODE_PCI_IRQ_LINE: /* Native PCI IRQ mode with specified interrupt line. */ if (irq) - picintlevel(1 << dev->irq_line); + pci_set_dirq(dev->pci_irq_line, &dev->irq_state); else - picintc(1 << dev->irq_line); + pci_clear_dirq(dev->pci_irq_line, &dev->irq_state); break; - case 4: + case IRQ_MODE_ALI_ALADDIN: /* ALi Aladdin Native PCI INTAJ mode. */ if (irq) - pci_set_mirq(channel + 2, dev->irq_level[channel]); + pci_set_mirq((dev->channel + 2), pci_get_mirq_level(dev->channel + 2), &dev->irq_state); else - pci_clear_mirq(channel + 2, dev->irq_level[channel]); + pci_clear_mirq((dev->channel + 2), pci_get_mirq_level(dev->channel + 2), &dev->irq_state); + break; + case IRQ_MODE_SIS_551X: + /* SiS 551x mode. */ + if (irq) + pci_set_mirq(dev->mirq, 1, &dev->irq_state); + else + pci_clear_mirq(dev->mirq, 1, &dev->irq_state); break; } } void -sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base) +sff_bus_master_reset(sff8038i_t *dev) { - if (dev->enabled) { - io_removehandler(old_base, 0x08, + if (dev->enabled && (dev->base != 0x0000)) { + io_removehandler(dev->base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, dev); @@ -437,35 +461,38 @@ sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base) dev->addr = 0x00000000; dev->ptr0 = 0x00; dev->count = dev->eot = 0x00000000; + dev->irq_state = 0; ide_pri_disable(); ide_sec_disable(); } static void -sff_reset(void *p) +sff_reset(void *priv) { - int i = 0; - #ifdef ENABLE_SFF_LOG sff_log("SFF8038i: Reset\n"); #endif - for (i = 0; i < CDROM_NUM; i++) { + for (uint8_t i = 0; i < HDD_NUM; i++) { + if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv) + scsi_disk_reset((scsi_common_t *) hdd[i].priv); + } + for (uint8_t i = 0; i < CDROM_NUM; i++) { if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } - for (i = 0; i < ZIP_NUM; i++) { + for (uint8_t i = 0; i < ZIP_NUM; i++) { if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) zip_reset((scsi_common_t *) zip_drives[i].priv); } - for (i = 0; i < MO_NUM; i++) { + for (uint8_t i = 0; i < MO_NUM; i++) { if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } - sff_bus_master_set_irq(0x00, p); - sff_bus_master_set_irq(0x01, p); + sff_bus_master_set_irq(0x00, priv); + sff_bus_master_set_irq(0x01, priv); } void @@ -475,44 +502,48 @@ sff_set_slot(sff8038i_t *dev, int slot) } void -sff_set_irq_line(sff8038i_t *dev, int irq_line) +sff_set_irq_line(sff8038i_t *dev, int pci_irq_line) { - dev->irq_line = irq_line; + dev->pci_irq_line = pci_irq_line; } +/* TODO: Why does this always set the level to 0, regardless of the parameter?! */ void -sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level) +sff_set_irq_level(sff8038i_t *dev, UNUSED(int irq_level)) { - dev->irq_level[channel] = 0; + dev->irq_level = 0; } void -sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode) +sff_set_irq_mode(sff8038i_t *dev, int irq_mode) { - dev->irq_mode[channel] = irq_mode; + dev->irq_mode = irq_mode; - switch (dev->irq_mode[channel]) { - case 0: + switch (dev->irq_mode) { default: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ - sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); + sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, dev->irq_line); break; - case 1: + case IRQ_MODE_PCI_IRQ_PIN: /* Native PCI IRQ mode with interrupt pin. */ - sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin); + sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin); break; - case 2: - case 5: - /* MIRQ 0 or 1. */ - sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1); + case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3: + /* MIRQ 0, 1, 2, or 3. */ + sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, dev->irq_mode & 3); break; - case 3: + case IRQ_MODE_PCI_IRQ_LINE: /* Native PCI IRQ mode with specified interrupt line. */ - sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line); + sff_log("[%08X] Setting IRQ mode to native PCI IRQ %i\n", dev, dev->pci_irq_line); break; - case 4: + case IRQ_MODE_ALI_ALADDIN: /* ALi Aladdin Native PCI INTAJ mode. */ - sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel); + sff_log("[%08X] Setting IRQ mode to INT%cJ\n", dev, 'A' + dev->channel); + break; + case IRQ_MODE_SIS_551X: + /* SiS 551x mode. */ + sff_log("[%08X] Setting IRQ mode to PCI MIRQ2\n", dev); break; } } @@ -523,10 +554,16 @@ sff_set_irq_pin(sff8038i_t *dev, int irq_pin) dev->irq_pin = irq_pin; } +void +sff_set_mirq(sff8038i_t *dev, uint8_t mirq) +{ + dev->mirq = mirq; +} + static void -sff_close(void *p) +sff_close(void *priv) { - sff8038i_t *dev = (sff8038i_t *) p; + sff8038i_t *dev = (sff8038i_t *) priv; free(dev); @@ -535,9 +572,8 @@ sff_close(void *p) next_id = 0; } -static void - * - sff_init(const device_t *info) +static void * +sff_init(UNUSED(const device_t *info)) { sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t)); memset(dev, 0, sizeof(sff8038i_t)); @@ -549,12 +585,16 @@ static void ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev); dev->slot = 7; - dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ - dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ + /* Channel 0 goes to IRQ 14, channel 1 goes to MIRQ0. */ + dev->irq_mode = next_id ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY; dev->irq_pin = PCI_INTA; - dev->irq_line = 14; - dev->irq_level[0] = dev->irq_level[1] = 0; + dev->irq_line = 14 + next_id; + dev->pci_irq_line = 14; + dev->irq_level = 0; + dev->irq_state = 0; + dev->mirq = 2; + dev->channel = next_id; next_id++; return dev; diff --git a/src/disk/hdc_ide_um8673f.c b/src/disk/hdc_ide_um8673f.c new file mode 100644 index 0000000000..9ee149c7f3 --- /dev/null +++ b/src/disk/hdc_ide_um8673f.c @@ -0,0 +1,212 @@ +/* + * 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. + * + * Implementation of the UMC UMF8673F IDE controller. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_UM8673F_LOG +int um8673f_do_log = ENABLE_UM8673F_LOG; + +static void +um8673f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8673f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8673f_log(fmt, ...) +#endif + +typedef struct um8673f_t { + uint8_t index; + uint8_t tries; + uint8_t unlocked; + + uint8_t regs[256]; +} um8673f_t; + +static void +um8673f_ide_handler(um8673f_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0xb0] & 0x80) + ide_pri_enable(); + if (dev->regs[0xb0] & 0x40) + ide_sec_enable(); +} + +static void +um8673f_write(uint16_t addr, uint8_t val, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + um8673f_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0x108: + if (dev->unlocked) { + if (dev->index == 0x34) { + dev->unlocked = 0; + dev->tries = 0; + } else + dev->index = val; + } else if (((dev->tries == 0) && (val == 0x4a)) || + ((dev->tries == 1) && (val == 0x6c))) { + dev->tries++; + if (dev->tries == 2) + dev->unlocked = 1; + } else + dev->tries = 0; + break; + + case 0x109: + switch (dev->index) { + case 0xb0: + dev->regs[dev->index] = val; + um8673f_ide_handler(dev); + break; + case 0xb1 ... 0xb8: + dev->regs[dev->index] = val; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +um8673f_read(uint16_t addr, void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x108: + if (dev->unlocked) + ret = dev->index; + else + dev->tries = 0; + break; + case 0x109: + if ((dev->index >= 0xb0) && (dev->index <= 0xb8)) + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + um8673f_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +um8673f_reset(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0xb0] = 0xc0; + + um8673f_ide_handler(dev); +} + +static void +um8673f_close(void *priv) +{ + um8673f_t *dev = (um8673f_t *) priv; + + free(dev); +} + +static void * +um8673f_init(UNUSED(const device_t *info)) +{ + um8673f_t *dev = (um8673f_t *) calloc(1, sizeof(um8673f_t)); + + io_sethandler(0x0108, 0x0002, um8673f_read, NULL, NULL, um8673f_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + um8673f_reset(dev); + + return dev; +} + +const device_t ide_um8886af_device = { + .name = "UMC UM8886F IDE", + .internal_name = "um8886af_ide", + .flags = 0, + .local = 1, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_um8673f_device = { + .name = "UMC UM8673F", + .internal_name = "um8673f", + .flags = 0, + .local = 0, + .init = um8673f_init, + .close = um8673f_close, + .reset = um8673f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c new file mode 100644 index 0000000000..ed34bc9fc2 --- /dev/null +++ b/src/disk/hdc_ide_w83769f.c @@ -0,0 +1,460 @@ +/* + * 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. + * + * Implementation of the Winbond W83769F controller. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/zip.h> +#include <86box/mo.h> + +typedef struct w83769f_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t regs[256]; +} w83769f_t; + +static int next_id = 0; + +#ifdef ENABLE_W83769F_LOG +int w83769f_do_log = ENABLE_W83769F_LOG; + +static void +w83769f_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd640_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define w83769f_log(fmt, ...) +#endif + +void +w83769f_set_irq_0(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 1)) + return; + + if (irq) + picint(1 << 14); + else + picintc(1 << 14); +} + +void +w83769f_set_irq_1(uint8_t status, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; + + if (!(dev->channels & 2)) + return; + + if (irq) + picint(1 << 15); + else + picintc(1 << 15); +} + +static void +w83769f_ide_handlers(w83769f_t *dev) +{ + if (dev->channels & 0x01) { + ide_pri_disable(); + + if (!dev->pci || (dev->regs[0x04] & 0x01)) + ide_pri_enable(); + } + + if (dev->channels & 0x02) { + ide_sec_disable(); + + if ((!dev->pci || (dev->regs[0x04] & 0x01)) && (dev->regs[0x57] & 0x01)) + ide_sec_enable(); + } +} + +static void +w83769f_common_write(int addr, uint8_t val, w83769f_t *dev) +{ + switch (addr) { + case 0x50: + case 0x57: + dev->regs[0x57] = val & 0x01; + w83769f_ide_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0x7f; + break; + case 0x52: + case 0x54: + case 0x56: + case 0x58 ... 0x59: + dev->regs[addr] = val; + break; + case 0x53: + case 0x55: + dev->regs[addr] = val & 0xcf; + break; + + default: + break; + } +} + +static void +w83769f_vlb_write(uint16_t addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + dev->vlb_idx = val; + break; + case 0x0038: + case 0x00b8: + w83769f_common_write(dev->vlb_idx, val, dev); + break; + + default: + break; + } +} + +static void +w83769f_vlb_writew(uint16_t addr, uint16_t val, void *priv) +{ + w83769f_vlb_write(addr, val & 0xff, priv); + w83769f_vlb_write(addr + 1, val >> 8, priv); +} + +static void +w83769f_vlb_writel(uint16_t addr, uint32_t val, void *priv) +{ + w83769f_vlb_writew(addr, val & 0xffff, priv); + w83769f_vlb_writew(addr + 2, val >> 16, priv); +} + +static uint8_t +w83769f_vlb_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + w83769f_t *dev = (w83769f_t *) priv; + + switch (addr) { + case 0x0034: + case 0x00b4: + ret = dev->vlb_idx; + break; + case 0x0038: + case 0x00b8: + ret = dev->regs[dev->vlb_idx]; + if (dev->vlb_idx == 0x50) + dev->regs[0x50] &= ~0x04; + break; + + default: + break; + } + + return ret; +} + +static uint16_t +w83769f_vlb_readw(uint16_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + ret = w83769f_vlb_read(addr, priv); + ret |= (w83769f_vlb_read(addr + 1, priv) << 8); + + return ret; +} + +static uint32_t +w83769f_vlb_readl(uint16_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + ret = w83769f_vlb_readw(addr, priv); + ret |= (w83769f_vlb_readw(addr + 2, priv) << 16); + + return ret; +} + +static void +w83769f_pci_write(int func, int addr, uint8_t val, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + w83769f_log("w83769f_pci_write(%i, %02X, %02X)\n", func, addr, val); + + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (dev->regs[addr] & 0xbf) | (val & 0x40); + w83769f_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + break; + } +} + +static uint8_t +w83769f_pci_read(int func, int addr, void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = dev->regs[addr]; + + w83769f_log("w83769f_pci_read(%i, %02X, %02X)\n", func, addr, ret); + + return ret; +} + +static void +w83769f_reset(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < ZIP_NUM; i++) { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && + (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + if (dev->channels & 0x01) + w83769f_set_irq_0(0x00, priv); + + if (dev->channels & 0x02) + w83769f_set_irq_1(0x00, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x50] = (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + dev->regs[0x51] = 0x40; + dev->regs[0x57] = 0x01; /* Required by the MSI MS-5109 */ + dev->regs[0x59] = 0x40; + + if (dev->pci) { + dev->regs[0x00] = 0xad; /* Winbond */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x01; /* W83769 */ + dev->regs[0x03] = 0x00; + dev->regs[0x04] = 0x01; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* 00h for Rev BB, 02h for Rev A3C */ + dev->regs[0x09] = 0x00; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + } else + dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */ + + w83769f_ide_handlers(dev); +} + +static void +w83769f_close(void *priv) +{ + w83769f_t *dev = (w83769f_t *) priv; + + free(dev); + + next_id = 0; +} + +static void * +w83769f_init(const device_t *info) +{ + w83769f_t *dev = (w83769f_t *) malloc(sizeof(w83769f_t)); + memset(dev, 0x00, sizeof(w83769f_t)); + + dev->id = next_id | 0x60; + + dev->pci = !!(info->flags & DEVICE_PCI); + + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + + if (info->flags & DEVICE_PCI) { + device_add(&ide_pci_2ch_device); + + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, w83769f_pci_read, w83769f_pci_write, dev, &dev->pci_slot); + } else if (info->flags & DEVICE_VLB) + device_add(&ide_vlb_2ch_device); + + if (dev->channels & 0x01) + ide_set_bus_master(0, NULL, w83769f_set_irq_0, dev); + + if (dev->channels & 0x02) + ide_set_bus_master(1, NULL, w83769f_set_irq_1, dev); + + /* The CMD PCI-0640B IDE controller has no DMA capability, + so set our devices IDE devices to force ATA-3 (no DMA). */ + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); + + io_sethandler(info->local & 0xffff, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + io_sethandler((info->local & 0xffff) + 0x0004, 0x0001, + w83769f_vlb_read, w83769f_vlb_readw, w83769f_vlb_readl, + w83769f_vlb_write, w83769f_vlb_writew, w83769f_vlb_writel, + dev); + + next_id++; + + w83769f_reset(dev); + + return dev; +} + +const device_t ide_w83769f_vlb_device = { + .name = "Winbond W83769F VLB", + .internal_name = "ide_w83769f_vlb", + .flags = DEVICE_VLB, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_vlb_34_device = { + .name = "Winbond W83769F VLB (Port 34h)", + .internal_name = "ide_w83769f_vlb_34", + .flags = DEVICE_VLB, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_device = { + .name = "Winbond W83769F PCI", + .internal_name = "ide_w83769f_pci", + .flags = DEVICE_PCI, + .local = 0x600b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_w83769f_pci_34_device = { + .name = "Winbond W83769F PCI (Port 34h)", + .internal_name = "ide_w83769f_pci_34", + .flags = DEVICE_PCI, + .local = 0x60034, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 88fd7192bc..41499591d5 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -74,36 +74,36 @@ #define CMD_DIAGNOSE 0x90 #define CMD_SET_PARAMETERS 0x91 -typedef struct { - int8_t present, /* drive is present */ - hdd_num, /* drive number in system */ - steprate, /* current servo step rate */ - spt, /* physical #sectors per track */ - hpc, /* physical #heads per cylinder */ - pad; - int16_t tracks; /* physical #tracks per cylinder */ - - int8_t cfg_spt, /* configured #sectors per track */ - cfg_hpc; /* configured #heads per track */ - - int16_t curcyl; /* current track number */ +typedef struct drive_t { + int8_t present; /* drive is present */ + int8_t hdd_num; /* drive number in system */ + int8_t steprate; /* current servo step rate */ + int8_t spt; /* physical #sectors per track */ + int8_t hpc; /* physical #heads per cylinder */ + int8_t pad; + int16_t tracks; /* physical #tracks per cylinder */ + + int8_t cfg_spt; /* configured #sectors per track */ + int8_t cfg_hpc; /* configured #heads per track */ + + int16_t curcyl; /* current track number */ } drive_t; -typedef struct { - uint8_t precomp, /* 1: precomp/error register */ - error, - secount, /* 2: sector count register */ - sector, /* 3: sector number */ - head, /* 6: head number + drive select */ - command, /* 7: command/status */ - status, - fdisk; /* 8: control register */ +typedef struct mfm_t { + uint8_t precomp; /* 1: precomp/error register */ + uint8_t error; + uint8_t secount; /* 2: sector count register */ + uint8_t sector; /* 3: sector number */ + uint8_t head; /* 6: head number + drive select */ + uint8_t command; /* 7: command/status */ + uint8_t status; + uint8_t fdisk; /* 8: control register */ uint16_t cylinder; /* 4/5: cylinder LOW and HIGH */ - int8_t reset, /* controller in reset */ - irqstat, /* current IRQ status */ - drvsel, /* current selected drive */ - pad; + int8_t reset; /* controller in reset */ + int8_t irqstat; /* current IRQ status */ + int8_t drvsel; /* current selected drive */ + int8_t pad; int pos; /* offset within data buffer */ pc_timer_t callback_timer; /* callback delay timer */ @@ -144,7 +144,7 @@ irq_raise(mfm_t *mfm) } static inline void -irq_lower(mfm_t *mfm) +irq_lower(UNUSED(mfm_t *mfm)) { picintc(1 << 14); } @@ -171,7 +171,7 @@ irq_update(mfm_t *mfm) static int get_sector(mfm_t *mfm, off64_t *addr) { - drive_t *drive = &mfm->drives[mfm->drvsel]; + const drive_t *drive = &mfm->drives[mfm->drvsel]; /* FIXME: See if this is even needed - if the code is present, IBM AT diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ @@ -435,6 +435,9 @@ mfm_write(uint16_t port, uint8_t val, void *priv) mfm->fdisk = val; irq_update(mfm); break; + + default: + break; } } @@ -668,7 +671,7 @@ do_callback(void *priv) } static void -loadhd(mfm_t *mfm, int c, int d, const char *fn) +loadhd(mfm_t *mfm, int c, int d, UNUSED(const char *fn)) { drive_t *drive = &mfm->drives[c]; @@ -686,7 +689,7 @@ loadhd(mfm_t *mfm, int c, int d, const char *fn) } static void * -mfm_init(const device_t *info) +mfm_init(UNUSED(const device_t *info)) { mfm_t *mfm; int c; @@ -731,7 +734,7 @@ mfm_close(void *priv) mfm_t *mfm = (mfm_t *) priv; for (uint8_t d = 0; d < 2; d++) { - drive_t *drive = &mfm->drives[d]; + const drive_t *drive = &mfm->drives[d]; hdd_image_close(drive->hdd_num); } diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 6f9358e0a5..fc20350b04 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -107,7 +107,7 @@ #define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" #define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" #define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ @@ -229,7 +229,7 @@ enum { STATE_DONE }; -typedef struct { +typedef struct drive_t { int8_t present; uint8_t hdd_num; @@ -238,30 +238,33 @@ typedef struct { uint16_t cylinder; /* current cylinder */ - uint8_t spt, /* physical parameters */ - hpc; + uint8_t spt; /* physical parameters */ + uint8_t hpc; uint16_t tracks; - uint8_t cfg_spt, /* configured parameters */ - cfg_hpc; + uint8_t cfg_spt; /* configured parameters */ + uint8_t cfg_hpc; uint16_t cfg_cyl; } drive_t; -typedef struct { +typedef struct hdc_t { uint8_t type; /* controller type */ uint8_t spt; /* sectors-per-track for controller */ uint16_t base; /* controller configuration */ - int8_t irq, - dma; + int8_t irq; + int8_t dma; uint8_t switches; uint8_t misc; - uint8_t nr_err, err_bv, cur_sec, pad; - uint32_t bios_addr, - bios_size, - bios_ram; - rom_t bios_rom; + uint8_t nr_err; + uint8_t err_bv; + uint8_t cur_sec; + uint8_t pad; + uint32_t bios_addr; + uint32_t bios_size; + uint32_t bios_ram; + rom_t bios_rom; int state; /* operational data */ uint8_t irq_dma; @@ -272,14 +275,14 @@ typedef struct { uint8_t command[6]; /* current command request */ int drive_sel; - int sector, - head, - cylinder, - count; + int sector; + int head; + int cylinder; + int count; uint8_t compl ; /* current request completion code */ - int buff_pos, /* pointers to the RAM buffer */ - buff_cnt; + int buff_pos; /* pointers to the RAM buffer */ + int buff_cnt; drive_t drives[MFM_NUM]; /* the attached drives */ uint8_t scratch[64]; /* ST-11 scratchpad RAM */ @@ -287,7 +290,7 @@ typedef struct { } hdc_t; /* Supported drives table for the Xebec controller. */ -typedef struct { +typedef struct hd_type_t { uint16_t tracks; uint8_t hpc; uint8_t spt; @@ -505,6 +508,9 @@ st506_callback(void *priv) case STATE_DONE: st506_complete(dev); break; + + default: + break; } break; @@ -531,6 +537,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -567,6 +576,9 @@ st506_callback(void *priv) ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); st506_complete(dev); break; + + default: + break; } break; @@ -599,6 +611,9 @@ st506_callback(void *priv) timer_advance_u64(&dev->timer, ST506_TIME); break; + + default: + break; } break; @@ -608,6 +623,7 @@ st506_callback(void *priv) st506_complete(dev); break; } + fallthrough; case CMD_FORMAT_TRACK: case CMD_FORMAT_BAD_TRACK: switch (dev->state) { @@ -642,6 +658,9 @@ st506_callback(void *priv) ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); st506_complete(dev); break; + + default: + break; } break; @@ -651,6 +670,7 @@ st506_callback(void *priv) st506_complete(dev); break; } + fallthrough; case CMD_READ: #if 0 case CMD_READ_LONG: @@ -734,6 +754,9 @@ st506_callback(void *priv) } dev->state = STATE_SEND_DATA; break; + + default: + break; } break; @@ -747,6 +770,7 @@ st506_callback(void *priv) st506_complete(dev); break; } + fallthrough; case CMD_WRITE: #if 0 case CMD_WRITE_LONG: @@ -829,6 +853,9 @@ st506_callback(void *priv) } dev->state = STATE_RECEIVE_DATA; break; + + default: + break; } break; @@ -884,6 +911,9 @@ st506_callback(void *priv) } st506_complete(dev); break; + + default: + break; } break; @@ -903,6 +933,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -943,6 +976,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -984,6 +1020,9 @@ st506_callback(void *priv) case STATE_RECEIVED_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -1005,6 +1044,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } else { st506_error(dev, ERR_BAD_COMMAND); @@ -1117,6 +1159,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -1136,6 +1181,9 @@ st506_callback(void *priv) /* FIXME: ignore the results. */ st506_complete(dev); break; + + default: + break; } break; @@ -1158,6 +1206,9 @@ st506_callback(void *priv) case STATE_SENT_DATA: st506_complete(dev); break; + + default: + break; } break; @@ -1202,6 +1253,9 @@ st506_read(uint16_t port, void *priv) timer_set_delay_u64(&dev->timer, ST506_TIME); } break; + + default: + break; } break; @@ -1214,6 +1268,9 @@ st506_read(uint16_t port, void *priv) case 2: /* read option jumpers */ ret = dev->switches; break; + + default: + break; } st506_xt_log("ST506: read(%04x) = %02x\n", port, ret); @@ -1254,6 +1311,9 @@ st506_write(uint16_t port, uint8_t val, void *priv) timer_set_delay_u64(&dev->timer, ST506_TIME); } break; + + default: + break; } break; @@ -1279,6 +1339,9 @@ st506_write(uint16_t port, uint8_t val, void *priv) picintc(1 << dev->irq); } break; + + default: + break; } } @@ -1317,10 +1380,10 @@ mem_write(uint32_t addr, uint8_t val, void *priv) static uint8_t mem_read(uint32_t addr, void *priv) { - hdc_t *dev = (hdc_t *) priv; - uint32_t ptr; - uint32_t mask = 0; - uint8_t ret = 0xff; + const hdc_t *dev = (hdc_t *) priv; + uint32_t ptr; + uint32_t mask = 0; + uint8_t ret = 0xff; /* Ignore accesses to anything below the configured address, needed because of the emulator's 4k mapping granularity. */ @@ -1362,9 +1425,10 @@ mem_read(uint32_t addr, void *priv) case ST506_XT_TYPE_ST11R: /* ST-11R */ mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; - - /* default: - break; */ +#if 0 + default: + break; +#endif } addr = addr & dev->bios_rom.mask; @@ -1429,7 +1493,7 @@ loadrom(hdc_t *dev, const char *fn) } static void -loadhd(hdc_t *dev, int c, int d, const char *fn) +loadhd(hdc_t *dev, int c, int d, UNUSED(const char *fn)) { drive_t *drive = &dev->drives[c]; @@ -1468,8 +1532,9 @@ loadhd(hdc_t *dev, int c, int d, const char *fn) static void set_switches(hdc_t *dev, hd_type_t *hdt, int num) { - drive_t *drive; - int e; + const drive_t *drive; + int c; + int e; dev->switches = 0x00; @@ -1482,7 +1547,7 @@ set_switches(hdc_t *dev, hd_type_t *hdt, int num) continue; } - for (int c = 0; c < num; c++) { + for (c = 0; c < num; c++) { /* Does the Xebec also support more than 4 types? */ if ((drive->spt == hdt[c].spt) && (drive->hpc == hdt[c].hpc) && (drive->tracks == hdt[c].tracks)) { /* Olivetti M24/M240: Move the upper 2 bites up by 2 bits, as the @@ -1510,10 +1575,10 @@ set_switches(hdc_t *dev, hd_type_t *hdt, int num) static void * st506_init(const device_t *info) { - char *fn = NULL; - hdc_t *dev; - int i; - int c; + const char *fn = NULL; + hdc_t *dev; + int i; + int c; dev = (hdc_t *) malloc(sizeof(hdc_t)); memset(dev, 0x00, sizeof(hdc_t)); @@ -1543,7 +1608,7 @@ st506_init(const device_t *info) case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */ dev->spt = RLL_SECTORS; - /*FALLTHROUGH*/ + fallthrough; case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; @@ -1557,6 +1622,9 @@ st506_init(const device_t *info) case 19: /* v2.0 */ fn = ST11_BIOS_FILE_NEW; break; + + default: + break; } dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); @@ -1599,7 +1667,7 @@ st506_init(const device_t *info) fn = WD1004A_WX1_BIOS_FILE; /* The switches are read in reverse: 0 = closed, 1 = open. Both open means MFM, 17 sectors per track. */ - dev->switches = 0x10; /* autobios */ + dev->switches = 0x30; /* autobios */ dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) @@ -1661,6 +1729,9 @@ st506_init(const device_t *info) dev->base = 0x01f0; dev->switches = 0x0c; break; + + default: + break; } /* Load the ROM BIOS. */ @@ -1711,8 +1782,8 @@ st506_init(const device_t *info) static void st506_close(void *priv) { - hdc_t *dev = (hdc_t *) priv; - drive_t *drive; + hdc_t *dev = (hdc_t *) priv; + const drive_t *drive; for (uint8_t d = 0; d < MFM_NUM; d++) { drive = &dev->drives[d]; diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index e698df7ffe..ede21caf2b 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -102,7 +102,7 @@ #include <86box/hdc.h> #include <86box/hdd.h> -#define HDC_TIME (50 * TIMER_USEC) +#define HDC_TIME (250 * TIMER_USEC) #define WD_REV_1_BIOS_FILE "roms/hdd/xta/idexywd2.bin" #define WD_REV_2_BIOS_FILE "roms/hdd/xta/infowdbios.rom" @@ -182,15 +182,15 @@ enum { /* The device control block (6 bytes) */ #pragma pack(push, 1) -typedef struct { +typedef struct dcb_t { uint8_t cmd; /* [7:5] class, [4:0] opcode */ - uint8_t head : 5, /* [4:0] head number */ - drvsel : 1, /* [5] drive select */ - mbz : 2; /* [7:6] 00 */ + uint8_t head : 5; /* [4:0] head number */ + uint8_t drvsel : 1; /* [5] drive select */ + uint8_t mbz : 2; /* [7:6] 00 */ - uint8_t sector : 6, /* [5:0] sector number 0-63 */ - cyl_high : 2; /* [7:6] cylinder [9:8] bits */ + uint8_t sector : 6; /* [5:0] sector number 0-63 */ + uint8_t cyl_high : 2; /* [7:6] cylinder [9:8] bits */ uint8_t cyl_low; /* [7:0] cylinder [7:0] bits */ @@ -202,7 +202,7 @@ typedef struct { /* The (configured) Drive Parameters. */ #pragma pack(push, 1) -typedef struct { +typedef struct dprm_t { uint8_t cyl_high; /* (MSB) number of cylinders */ uint8_t cyl_low; /* (LSB) number of cylinders */ uint8_t heads; /* number of heads per cylinder */ @@ -215,24 +215,24 @@ typedef struct { #pragma pack(pop) /* Define an attached drive. */ -typedef struct { - int8_t id, /* drive ID on bus */ - present, /* drive is present */ - hdd_num, /* index to global disk table */ - type; /* drive type ID */ +typedef struct drive_t { + int8_t id; /* drive ID on bus */ + int8_t present; /* drive is present */ + int8_t hdd_num; /* index to global disk table */ + int8_t type; /* drive type ID */ uint16_t cur_cyl; /* last known position of heads */ - uint8_t spt, /* active drive parameters */ - hpc; + uint8_t spt; /* active drive parameters */ + uint8_t hpc; uint16_t tracks; - uint8_t cfg_spt, /* configured drive parameters */ - cfg_hpc; + uint8_t cfg_spt; /* configured drive parameters */ + uint8_t cfg_hpc; uint16_t cfg_tracks; } drive_t; -typedef struct { +typedef struct hdc_t { const char *name; /* controller name */ uint16_t base; /* controller base I/O address */ @@ -248,21 +248,20 @@ typedef struct { uint8_t sense; /* current SENSE ERROR value */ uint8_t status; /* current operational status */ uint8_t intr; - uint64_t callback; pc_timer_t timer; /* Data transfer. */ - int16_t buf_idx, /* buffer index and pointer */ - buf_len; + int16_t buf_idx; /* buffer index and pointer */ + int16_t buf_len; uint8_t *buf_ptr; /* Current operation parameters. */ - dcb_t dcb; /* device control block */ - uint16_t track; /* requested track# */ - uint8_t head, /* requested head# */ - sector, /* requested sector# */ - comp; /* operation completion byte */ - int count; /* requested sector count */ + dcb_t dcb; /* device control block */ + uint16_t track; /* requested track# */ + uint8_t head; /* requested head# */ + uint8_t sector; /* requested sector# */ + uint8_t comp; /* operation completion byte */ + int count; /* requested sector count */ drive_t drives[XTA_NUM]; /* the attached drive(s) */ @@ -343,22 +342,6 @@ next_sector(hdc_t *dev, drive_t *drive) } } -static void -xta_set_callback(hdc_t *dev, uint64_t callback) -{ - if (!dev) { - return; - } - - if (callback) { - dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_disable(&dev->timer); - } -} - /* Perform the seek operation. */ static void do_seek(hdc_t *dev, drive_t *drive, int cyl) @@ -436,6 +419,9 @@ do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb) /* This saves us a LOT of code. */ goto do_fmt; + + default: + break; } /* De-activate the status icon. */ @@ -446,16 +432,13 @@ do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb) static void hdc_callback(void *priv) { - hdc_t *dev = (hdc_t *) priv; - dcb_t *dcb = &dev->dcb; - drive_t *drive; - dprm_t *params; - off64_t addr; - int no_data = 0; - int val; - - /* Cancel timer. */ - xta_set_callback(dev, 0); + hdc_t *dev = (hdc_t *) priv; + dcb_t *dcb = &dev->dcb; + drive_t *drive; + const dprm_t *params; + off64_t addr; + int no_data = 0; + int val; drive = &dev->drives[dcb->drvsel]; dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00; @@ -497,12 +480,16 @@ hdc_callback(void *priv) case STATE_SDONE: set_intr(dev); + break; + + default: + break; } break; case CMD_READ_VERIFY: no_data = 1; - /*FALLTHROUGH*/ + fallthrough; case CMD_READ_SECTORS: if (!drive->present) { @@ -527,7 +514,7 @@ hdc_callback(void *priv) dev->buf_len = 512; dev->state = STATE_SEND; - /*FALLTHROUGH*/ + fallthrough; case STATE_SEND: /* Activate the status icon. */ @@ -551,12 +538,12 @@ hdc_callback(void *priv) dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->intr & DMA_ENA) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* Copy from sector to data. */ memcpy(dev->data, @@ -579,14 +566,14 @@ hdc_callback(void *priv) xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } dev->buf_ptr++; dev->buf_idx++; } } - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); dev->state = STATE_SDONE; break; @@ -606,6 +593,9 @@ hdc_callback(void *priv) /* This saves us a LOT of code. */ dev->state = STATE_SEND; goto do_send; + + default: + break; } break; @@ -632,7 +622,7 @@ hdc_callback(void *priv) dev->buf_len = 512; dev->state = STATE_RECV; - /*FALLTHROUGH*/ + fallthrough; case STATE_RECV: /* Activate the status icon. */ @@ -644,7 +634,7 @@ hdc_callback(void *priv) if (dev->intr & DMA_ENA) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->buf_ptr = dev->data; @@ -663,7 +653,7 @@ hdc_callback(void *priv) xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } @@ -671,7 +661,7 @@ hdc_callback(void *priv) dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -710,6 +700,9 @@ hdc_callback(void *priv) /* This saves us a LOT of code. */ dev->state = STATE_RECV; goto do_recv; + + default: + break; } break; @@ -758,6 +751,9 @@ hdc_callback(void *priv) dev->status &= ~STAT_REQ; set_intr(dev); break; + + default: + break; } break; @@ -769,7 +765,7 @@ hdc_callback(void *priv) dev->state = STATE_RDATA; if (dev->intr & DMA_ENA) { dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { dev->buf_ptr = dev->data; dev->status |= STAT_REQ; @@ -784,7 +780,7 @@ hdc_callback(void *priv) if (val == DMA_NODATA) { xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } @@ -792,7 +788,7 @@ hdc_callback(void *priv) dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -802,6 +798,9 @@ hdc_callback(void *priv) dev->data, dev->buf_len); set_intr(dev); break; + + default: + break; } break; @@ -809,12 +808,15 @@ hdc_callback(void *priv) switch (dev->state) { case STATE_IDLE: dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); + timer_advance_u64(&dev->timer, 5 * HDC_TIME); break; case STATE_RDONE: set_intr(dev); break; + + default: + break; } break; @@ -823,7 +825,7 @@ hdc_callback(void *priv) case STATE_IDLE: if (drive->present) { dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); + timer_advance_u64(&dev->timer, 5 * HDC_TIME); } else { dev->comp |= COMP_ERR; dev->sense = ERR_NOTRDY; @@ -834,6 +836,9 @@ hdc_callback(void *priv) case STATE_RDONE: set_intr(dev); break; + + default: + break; } break; @@ -841,12 +846,15 @@ hdc_callback(void *priv) switch (dev->state) { case STATE_IDLE: dev->state = STATE_RDONE; - xta_set_callback(dev, 10 * HDC_TIME); + timer_advance_u64(&dev->timer, 10 * HDC_TIME); break; case STATE_RDONE: set_intr(dev); break; + + default: + break; } break; @@ -883,7 +891,7 @@ hdc_read(uint16_t port, void *priv) /* All data sent. */ dev->status &= ~STAT_REQ; dev->state = STATE_SDONE; - xta_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } else if (dev->state == STATE_COMPL) { xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp); @@ -900,6 +908,9 @@ hdc_read(uint16_t port, void *priv) case 2: /* "read option jumpers" */ ret = 0xff; /* all switches off */ break; + + default: + break; } return ret; @@ -938,7 +949,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) else dev->state = STATE_IDLE; dev->status &= ~STAT_CD; - xta_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } break; @@ -958,21 +969,26 @@ hdc_write(uint16_t port, uint8_t val, void *priv) break; case 3: /* DMA/IRQ intr register */ - // xta_log("%s: WriteMASK(%02X)\n", dev->name, val); +#if 0 + xta_log("%s: WriteMASK(%02X)\n", dev->name, val); +#endif dev->intr = val; break; + + default: + break; } } static void * xta_init(const device_t *info) { - drive_t *drive; - char *bios_rev = NULL; - char *fn = NULL; - hdc_t *dev; - int c; - int max = XTA_NUM; + drive_t *drive; + const char *bios_rev = NULL; + const char *fn = NULL; + hdc_t *dev; + int c; + int max = XTA_NUM; /* Allocate and initialize device block. */ dev = malloc(sizeof(hdc_t)); @@ -988,7 +1004,7 @@ xta_init(const device_t *info) dev->rom_addr = device_get_config_hex20("bios_addr"); dev->dma = 3; bios_rev = (char *) device_get_config_bios("bios_rev"); - fn = (char *) device_get_bios_file(info, (const char *) bios_rev, 0); + fn = (char *) device_get_bios_file(info, bios_rev, 0); max = 1; break; @@ -998,12 +1014,16 @@ xta_init(const device_t *info) dev->irq = 5; dev->dma = 3; break; + + default: + break; } xta_log("%s: initializing (I/O=%04X, IRQ=%d, DMA=%d", dev->name, dev->base, dev->irq, dev->dma); if (dev->rom_addr != 0x000000) xta_log(", BIOS=%06X", dev->rom_addr); + xta_log(")\n"); /* Load any disks for this device class. */ @@ -1058,8 +1078,8 @@ xta_init(const device_t *info) static void xta_close(void *priv) { - hdc_t *dev = (hdc_t *) priv; - drive_t *drive; + hdc_t *dev = (hdc_t *) priv; + const drive_t *drive; /* Remove the I/O handler. */ io_removehandler(dev->base, 4, diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index d1baba8bec..057d4f0ed6 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -40,18 +40,20 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/timer.h> #include <86box/device.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/plat_unused.h> #define ROM_PATH_XT "roms/hdd/xtide/ide_xt.bin" #define ROM_PATH_XTP "roms/hdd/xtide/ide_xtp.bin" #define ROM_PATH_AT "roms/hdd/xtide/ide_at.bin" +#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" #define ROM_PATH_PS2 "roms/hdd/xtide/SIDE1V12.BIN" #define ROM_PATH_PS2AT "roms/hdd/xtide/ide_at_1_1_5.bin" -#define ROM_PATH_AT_386 "roms/hdd/xtide/ide_386.bin" -typedef struct { +typedef struct xtide_t { void *ide_board; uint8_t data_high; rom_t bios_rom; @@ -84,6 +86,9 @@ xtide_write(uint16_t port, uint8_t val, void *priv) case 0xe: ide_write_devctl(0x0, val, xtide->ide_board); return; + + default: + break; } } @@ -131,13 +136,9 @@ xtide_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); - if (info->local == 1) { - rom_init(&xtide->bios_rom, ROM_PATH_XTP, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } else { - rom_init(&xtide->bios_rom, ROM_PATH_XT, + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } xtide->ide_board = ide_xtide_init(); @@ -148,18 +149,6 @@ xtide_init(const device_t *info) return xtide; } -static int -xtide_available(void) -{ - return (rom_present(ROM_PATH_XT)); -} - -static int -xtide_plus_available(void) -{ - return (rom_present(ROM_PATH_XTP)); -} - static void * xtide_at_init(const device_t *info) { @@ -167,33 +156,17 @@ xtide_at_init(const device_t *info) memset(xtide, 0x00, sizeof(xtide_t)); - if (info->local == 1) { - rom_init(&xtide->bios_rom, ROM_PATH_AT_386, - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } else { - rom_init(&xtide->bios_rom, ROM_PATH_AT, + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - } device_add(&ide_isa_2ch_device); return xtide; } -static int -xtide_at_available(void) -{ - return (rom_present(ROM_PATH_AT)); -} - -static int -xtide_at_386_available(void) -{ - return (rom_present(ROM_PATH_AT_386)); -} - static void * -xtide_acculogic_init(const device_t *info) +xtide_acculogic_init(UNUSED(const device_t *info)) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -228,7 +201,7 @@ xtide_close(void *priv) } static void * -xtide_at_ps2_init(const device_t *info) +xtide_at_ps2_init(UNUSED(const device_t *info)) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -256,6 +229,50 @@ xtide_at_close(void *priv) free(xtide); } +static const device_config_t xtide_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS", + .type = CONFIG_BIOS, + .default_string = "xt", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Regular XT", .internal_name = "xt", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XT, "" } }, + { .name = "XT+ (V20/V30/8018x)", .internal_name = "xt_plus", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XTP, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_config_t xtide_at_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS", + .type = CONFIG_BIOS, + .default_string = "at", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Regular AT", .internal_name = "at", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT, "" } }, + { .name = "386", .internal_name = "at_386", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT_386, "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t xtide_device = { .name = "PC/XT XTIDE", .internal_name = "xtide", @@ -264,24 +281,10 @@ const device_t xtide_device = { .init = xtide_init, .close = xtide_close, .reset = NULL, - { .available = xtide_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t xtide_plus_device = { - .name = "PC/XT XTIDE (V20/V30/8018x)", - .internal_name = "xtide_plus", - .flags = DEVICE_ISA, - .local = 1, - .init = xtide_init, - .close = xtide_close, - .reset = NULL, - { .available = xtide_plus_available }, + { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = xtide_config }; const device_t xtide_at_device = { @@ -292,24 +295,10 @@ const device_t xtide_at_device = { .init = xtide_at_init, .close = xtide_at_close, .reset = NULL, - { .available = xtide_at_available }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t xtide_at_386_device = { - .name = "PC/AT XTIDE (386)", - .internal_name = "xtide_at_386", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, - .init = xtide_at_init, - .close = xtide_at_close, - .reset = NULL, - { .available = xtide_at_386_available }, + { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = xtide_at_config }; const device_t xtide_acculogic_device = { diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 6135c31d81..3bb15c241d 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -102,13 +102,13 @@ hdd_string_to_bus(char *str, int cdrom) } char * -hdd_bus_to_string(int bus, int cdrom) +hdd_bus_to_string(int bus, UNUSED(int cdrom)) { char *s = "none"; switch (bus) { - case HDD_BUS_DISABLED: default: + case HDD_BUS_DISABLED: break; case HDD_BUS_MFM: @@ -160,12 +160,12 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_ if (!hdd->speed_preset) return HDD_OVERHEAD_TIME; - hdd_zone_t *zone = NULL; + const hdd_zone_t *zone = NULL; if (hdd->num_zones <= 0) { fatal("hdd_seek_get_time(): hdd->num_zones < 0)\n"); return 0.0; } - for (int i = 0; i < hdd->num_zones; i++) { + for (uint32_t i = 0; i < hdd->num_zones; i++) { zone = &hdd->zones[i]; if (zone->end_sector >= dst_addr) break; @@ -210,7 +210,7 @@ hdd_readahead_update(hard_disk_t *hdd) uint64_t elapsed_cycles; double elapsed_us; double seek_time; - uint32_t max_read_ahead; + int32_t max_read_ahead; uint32_t space_needed; hdd_cache_t *cache = &hdd->cache; @@ -224,7 +224,7 @@ hdd_readahead_update(hard_disk_t *hdd) seek_time = 0.0; - for (uint32_t i = 0; i < max_read_ahead; i++) { + for (int32_t i = 0; i < max_read_ahead; i++) { seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time); if (seek_time > elapsed_us) break; @@ -461,7 +461,7 @@ hdd_preset_get_from_internal_name(char *s) int c = 0; for (int i = 0; i < (sizeof(hdd_speed_presets) / sizeof(hdd_preset_t)); i++) { - if (!strcmp((char *) hdd_speed_presets[c].internal_name, s)) + if (!strcmp(hdd_speed_presets[c].internal_name, s)) return c; c++; } @@ -486,7 +486,7 @@ hdd_preset_apply(int hdd_id) if (hd->speed_preset >= hdd_preset_get_num()) hd->speed_preset = 0; - hdd_preset_t *preset = &hdd_speed_presets[hd->speed_preset]; + const hdd_preset_t *preset = &hdd_speed_presets[hd->speed_preset]; hd->cache.num_segments = preset->rcache_num_seg; hd->cache.segment_size = preset->rcache_seg_size; diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 856fc382cb..df473d7d92 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -40,12 +40,12 @@ #define HDD_IMAGE_HDX 2 #define HDD_IMAGE_VHD 3 -typedef struct -{ +typedef struct hdd_image_t { FILE *file; /* Used for HDD_IMAGE_RAW, HDD_IMAGE_HDI, and HDD_IMAGE_HDX. */ MVHDMeta *vhd; /* Used for HDD_IMAGE_VHD. */ uint32_t base; - uint32_t pos, last_sector; + uint32_t pos; + uint32_t last_sector; uint8_t type; /* HDD_IMAGE_RAW, HDD_IMAGE_HDI, HDD_IMAGE_HDX, or HDD_IMAGE_VHD */ uint8_t loaded; } hdd_image_t; @@ -85,28 +85,28 @@ image_is_hdi(const char *s) int image_is_hdx(const char *s, int check_signature) { - FILE *f; + FILE *fp; uint64_t filelen; uint64_t signature; if (!strcasecmp(path_get_extension((char *) s), "HDX")) { if (check_signature) { - f = plat_fopen(s, "rb"); - if (!f) + fp = plat_fopen(s, "rb"); + if (!fp) return 0; - if (fseeko64(f, 0, SEEK_END)) + if (fseeko64(fp, 0, SEEK_END)) fatal("image_is_hdx(): Error while seeking"); - filelen = ftello64(f); - if (fseeko64(f, 0, SEEK_SET)) + filelen = ftello64(fp); + if (fseeko64(fp, 0, SEEK_SET)) fatal("image_is_hdx(): Error while seeking"); if (filelen < 44) { - if (f != NULL) - fclose(f); + if (fp != NULL) + fclose(fp); return 0; } - if (fread(&signature, 1, 8, f) != 8) + if (fread(&signature, 1, 8, fp) != 8) fatal("image_is_hdx(): Error reading signature\n"); - fclose(f); + fclose(fp); if (signature == 0xD778A82044445459LL) return 1; else @@ -120,16 +120,16 @@ image_is_hdx(const char *s, int check_signature) int image_is_vhd(const char *s, int check_signature) { - FILE *f; + FILE *fp; if (!strcasecmp(path_get_extension((char *) s), "VHD")) { if (check_signature) { - f = plat_fopen(s, "rb"); - if (!f) + fp = plat_fopen(s, "rb"); + if (!fp) return 0; - bool is_vhd = mvhd_file_is_vhd(f); - fclose(f); + bool is_vhd = mvhd_file_is_vhd(fp); + fclose(fp); return is_vhd ? 1 : 0; } else return 1; @@ -450,7 +450,7 @@ hdd_image_load(int id) else fatal("hdd_image_load(): VHD: Error opening VHD file '%s': %s\n", fn, mvhd_strerr(vhd_error)); } else if (vhd_error == MVHD_ERR_TIMESTAMP) { - fatal("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn); + pclog("hdd_image_load(): VHD: Parent/child timestamp mismatch for VHD file '%s'\n", fn); } hdd[id].tracks = hdd_images[id].vhd->footer.geom.cyl; @@ -637,7 +637,7 @@ hdd_image_get_type(uint8_t id) } void -hdd_image_unload(uint8_t id, int fn_preserve) +hdd_image_unload(uint8_t id, UNUSED(int fn_preserve)) { if (strlen(hdd[id].fn) == 0) return; diff --git a/src/disk/minivhd/create.c b/src/disk/minivhd/create.c index ebfbb69a2b..d06382ef95 100644 --- a/src/disk/minivhd/create.c +++ b/src/disk/minivhd/create.c @@ -245,11 +245,11 @@ mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, M goto end; } - FILE* f = mvhd_fopen(path, "wb+", err); - if (f == NULL) { + FILE* fp = mvhd_fopen(path, "wb+", err); + if (fp == NULL) { goto cleanup_vhdm; } - mvhd_fseeko64(f, 0, SEEK_SET); + mvhd_fseeko64(fp, 0, SEEK_SET); uint32_t size_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); uint32_t s; @@ -269,22 +269,22 @@ mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, M mvhd_fseeko64(raw_img, 0, SEEK_SET); for (s = 0; s < size_sectors; s++) { (void) !fread(img_data, sizeof img_data, 1, raw_img); - fwrite(img_data, sizeof img_data, 1, f); + fwrite(img_data, sizeof img_data, 1, fp); if (progress_callback) progress_callback(s + 1, size_sectors); } } else { gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); for (s = 0; s < size_sectors; s++) { - fwrite(img_data, sizeof img_data, 1, f); + fwrite(img_data, sizeof img_data, 1, fp); if (progress_callback) progress_callback(s + 1, size_sectors); } } mvhd_footer_to_buffer(&vhdm->footer, footer_buff); - fwrite(footer_buff, sizeof footer_buff, 1, f); - fclose(f); - f = NULL; + fwrite(footer_buff, sizeof footer_buff, 1, fp); + fclose(fp); + fp = NULL; free(vhdm); vhdm = mvhd_open(path, false, err); goto end; @@ -352,11 +352,11 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte goto cleanup_vhdm; } - FILE* f = mvhd_fopen(path, "wb+", err); - if (f == NULL) { + FILE* fp = mvhd_fopen(path, "wb+", err); + if (fp == NULL) { goto cleanup_vhdm; } - mvhd_fseeko64(f, 0, SEEK_SET); + mvhd_fseeko64(fp, 0, SEEK_SET); /* Note, the sparse header follows the footer copy at the beginning of the file */ if (par_path == NULL) { @@ -367,7 +367,7 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte mvhd_footer_to_buffer(&vhdm->footer, footer_buff); /* As mentioned, start with a copy of the footer */ - fwrite(footer_buff, sizeof footer_buff, 1, f); + fwrite(footer_buff, sizeof footer_buff, 1, fp); /** * Calculate the number of (2MB or 512KB) data blocks required to store the entire @@ -417,20 +417,20 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte } gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); - fwrite(sparse_buff, sizeof sparse_buff, 1, f); + fwrite(sparse_buff, sizeof sparse_buff, 1, fp); /* The BAT sectors need to be filled with 0xffffffff */ for (uint32_t k = 0; k < num_bat_sect; k++) { - fwrite(bat_sect, sizeof bat_sect, 1, f); + fwrite(bat_sect, sizeof bat_sect, 1, fp); } - mvhd_write_empty_sectors(f, 5); + mvhd_write_empty_sectors(fp, 5); /** * If creating a differencing VHD, the paths to the parent image need to be written * tp the file. Both absolute and relative paths are written * */ if (par_vhdm != NULL) { - uint64_t curr_pos = (uint64_t)mvhd_ftello64(f); + uint64_t curr_pos = (uint64_t)mvhd_ftello64(fp); /* Double check my sums... */ assert(curr_pos == par_loc_offset); @@ -440,25 +440,25 @@ create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_byte for (int i = 0; i < 2; i++) { for (uint32_t j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { - fwrite(empty_sect, sizeof empty_sect, 1, f); + fwrite(empty_sect, sizeof empty_sect, 1, fp); } } /* Now write the location entries */ - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); - fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f); - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); - fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, f); + mvhd_fseeko64(fp, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); + fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, fp); + mvhd_fseeko64(fp, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); + fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, fp); /* and reset the file position to continue */ - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, SEEK_SET); - mvhd_write_empty_sectors(f, 5); + mvhd_fseeko64(fp, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, SEEK_SET); + mvhd_write_empty_sectors(fp, 5); } /* And finish with the footer */ - fwrite(footer_buff, sizeof footer_buff, 1, f); - fclose(f); - f = NULL; + fwrite(footer_buff, sizeof footer_buff, 1, fp); + fclose(fp); + fp = NULL; free(vhdm); vhdm = mvhd_open(path, false, err); goto end; diff --git a/src/disk/minivhd/manage.c b/src/disk/minivhd/manage.c index 053acc40ce..7ac3989e69 100644 --- a/src/disk/minivhd/manage.c +++ b/src/disk/minivhd/manage.c @@ -445,7 +445,7 @@ mvhd_file_is_vhd(FILE* f) } mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); - fread(con_str, sizeof con_str, 1, f); + (void) !fread(con_str, sizeof con_str, 1, f); if (mvhd_is_conectix_str(con_str)) { return 1; } diff --git a/src/disk/mo.c b/src/disk/mo.c index 5a76d43945..c93f4b0559 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -49,6 +49,8 @@ # include #endif +#define IDE_ATAPI_IS_EARLY id->sc->pad0 + mo_drive_t mo_drives[MO_NUM]; /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ @@ -316,9 +318,9 @@ find_mo_for_channel(uint8_t channel) static int mo_load_abort(mo_t *dev) { - if (dev->drv->f) - fclose(dev->drv->f); - dev->drv->f = NULL; + if (dev->drv->fp) + fclose(dev->drv->fp); + dev->drv->fp = NULL; dev->drv->medium_size = 0; dev->drv->sector_size = 0; mo_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ @@ -341,13 +343,18 @@ mo_load(mo_t *dev, char *fn) uint32_t size = 0; unsigned int found = 0; + if (!dev->drv) { + mo_eject(dev->id); + return 0; + } + is_mdi = image_is_mdi(fn); - dev->drv->f = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); - if (!dev->drv->f) { + dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); + if (!dev->drv->fp) { if (!dev->drv->read_only) { - dev->drv->f = plat_fopen(fn, "rb"); - if (dev->drv->f) + dev->drv->fp = plat_fopen(fn, "rb"); + if (dev->drv->fp) dev->drv->read_only = 1; else return mo_load_abort(dev); @@ -355,8 +362,8 @@ mo_load(mo_t *dev, char *fn) return mo_load_abort(dev); } - fseek(dev->drv->f, 0, SEEK_END); - size = (uint32_t) ftell(dev->drv->f); + fseek(dev->drv->fp, 0, SEEK_END); + size = (uint32_t) ftell(dev->drv->fp); if (is_mdi) { /* This is a MDI image. */ @@ -376,7 +383,7 @@ mo_load(mo_t *dev, char *fn) if (!found) return mo_load_abort(dev); - if (fseek(dev->drv->f, dev->drv->base, SEEK_SET) == -1) + if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("mo_load(): Error seeking to the beginning of the file\n"); strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); @@ -401,16 +408,16 @@ mo_disk_reload(mo_t *dev) void mo_disk_unload(mo_t *dev) { - if (dev->drv->f) { - fclose(dev->drv->f); - dev->drv->f = NULL; + if (dev->drv && dev->drv->fp) { + fclose(dev->drv->fp); + dev->drv->fp = NULL; } } void mo_disk_close(mo_t *dev) { - if (dev->drv->f) { + if (dev->drv && dev->drv->fp) { mo_disk_unload(dev); memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); @@ -443,11 +450,11 @@ mo_init(mo_t *dev) dev->drv->bus_mode |= 1; mo_log("MO %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); if (dev->drv->bus_type < MO_BUS_SCSI) { - dev->phase = 1; - dev->request_length = 0xEB14; + dev->tf->phase = 1; + dev->tf->request_length = 0xEB14; } - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; + dev->tf->status = READY_STAT | DSC_STAT; + dev->tf->pos = 0; dev->packet_status = PHASE_NONE; mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0; } @@ -477,33 +484,9 @@ mo_current_mode(mo_t *dev) if (!mo_supports_pio(dev) && mo_supports_dma(dev)) return 2; if (mo_supports_pio(dev) && mo_supports_dma(dev)) { - mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -mo_atapi_phase_to_scsi(mo_t *dev) -{ - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, + (dev->tf->features & 1) ? "DMA" : "PIO"); + return (dev->tf->features & 1) ? 2 : 1; } return 0; @@ -512,8 +495,8 @@ mo_atapi_phase_to_scsi(mo_t *dev) static void mo_mode_sense_load(mo_t *dev) { - FILE *f; - char file_name[512]; + FILE *fp; + char fn[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (mo_drives[dev->id].bus_type == MO_BUS_SCSI) @@ -521,33 +504,33 @@ mo_mode_sense_load(mo_t *dev) else memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default, sizeof(mode_sense_pages_t)); - memset(file_name, 0, 512); + memset(fn, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) - sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); + sprintf(fn, "scsi_mo_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "rb"); - if (f) { + sprintf(fn, "mo_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(fn), "rb"); + if (fp) { /* Nothing to read, not used by MO. */ - fclose(f); + fclose(fp); } } static void mo_mode_sense_save(mo_t *dev) { - FILE *f; - char file_name[512]; + FILE *fp; + char fn[512]; - memset(file_name, 0, 512); + memset(fn, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) - sprintf(file_name, "scsi_mo_%02i_mode_sense_bin", dev->id); + sprintf(fn, "scsi_mo_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "mo_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "wb"); - if (f) { + sprintf(fn, "mo_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(fn), "wb"); + if (fp) { /* Nothing to write, not used by MO. */ - fclose(f); + fclose(fp); } } @@ -559,15 +542,15 @@ mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) case 0: case 3: return dev->ms_pages_saved.pages[page][pos]; - break; case 1: return mo_mode_sense_pages_changeable.pages[page][pos]; - break; case 2: if (dev->drv->bus_type == MO_BUS_SCSI) return mo_mode_sense_pages_default_scsi.pages[page][pos]; else return mo_mode_sense_pages_default.pages[page][pos]; + + default: break; } @@ -619,7 +602,7 @@ mo_update_request_length(mo_t *dev, int len, int block_len) int bt; int min_len = 0; - dev->max_transfer_len = dev->request_length; + dev->max_transfer_len = dev->tf->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { @@ -649,7 +632,8 @@ mo_update_request_length(mo_t *dev, int len, int block_len) break; } } - /*FALLTHROUGH*/ + fallthrough; + default: dev->packet_len = len; break; @@ -662,9 +646,9 @@ mo_update_request_length(mo_t *dev, int len, int block_len) dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->tf->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->tf->request_length = dev->max_transfer_len; return; } @@ -695,9 +679,9 @@ mo_command_common(mo_t *dev) double bytes_per_second; double period; - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; + dev->tf->status = BUSY_STAT; + dev->tf->phase = 1; + dev->tf->pos = 0; if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0.0; else { @@ -759,8 +743,8 @@ static void mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int direction) { mo_log("MO %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos = 0; + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length); + dev->tf->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; @@ -789,11 +773,12 @@ mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int dir } mo_log("MO %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); + dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, + dev->tf->phase); } static void -mo_sense_clear(mo_t *dev, int command) +mo_sense_clear(mo_t *dev, UNUSED(int command)) { mo_sense_key = mo_asc = mo_ascq = 0; } @@ -814,14 +799,14 @@ static void mo_cmd_error(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR; + dev->tf->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * MO_TIME; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; + dev->packet_status = PHASE_ERROR; + dev->callback = 50.0 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq); @@ -831,14 +816,14 @@ static void mo_unit_attention(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * MO_TIME; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; + dev->packet_status = PHASE_ERROR; + dev->callback = 50.0 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); mo_log("MO %i: UNIT ATTENTION\n", dev->id); @@ -924,7 +909,7 @@ mo_invalid_field(mo_t *dev) mo_asc = ASC_INV_FIELD_IN_CMD_PACKET; mo_ascq = 0; mo_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -934,11 +919,11 @@ mo_invalid_field_pl(mo_t *dev) mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; mo_ascq = 0; mo_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static int -mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out) +mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out) { *len = 0; @@ -958,17 +943,17 @@ mo_blocks(mo_t *dev, int32_t *len, int first_batch, int out) *len = dev->requested_blocks * dev->drv->sector_size; for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) break; - if (feof(dev->drv->f)) + if (feof(dev->drv->fp)) break; if (out) { - if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) + if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) fatal("mo_blocks(): Error writing data\n"); } else { - if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->f) != dev->drv->sector_size) + if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) fatal("mo_blocks(): Error reading data\n"); } } @@ -996,14 +981,14 @@ mo_format(mo_t *dev) mo_log("MO %i: Formatting media...\n", dev->id); - fseek(dev->drv->f, 0, SEEK_END); - size = ftell(dev->drv->f); + fseek(dev->drv->fp, 0, SEEK_END); + size = ftell(dev->drv->fp); #ifdef _WIN32 HANDLE fh; LARGE_INTEGER liSize; - fd = _fileno(dev->drv->f); + fd = _fileno(dev->drv->fp); fh = (HANDLE) _get_osfhandle(fd); liSize.QuadPart = 0; @@ -1037,7 +1022,7 @@ mo_format(mo_t *dev) return; } #else - fd = fileno(dev->drv->f); + fd = fileno(dev->drv->fp); ret = ftruncate(fd, 0); @@ -1076,13 +1061,13 @@ mo_erase(mo_t *dev) mo_buf_alloc(dev, dev->drv->sector_size); memset(dev->buffer, 0, dev->drv->sector_size); - fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), SEEK_SET); + fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), SEEK_SET); for (i = 0; i < dev->requested_blocks; i++) { - if (feof(dev->drv->f)) + if (feof(dev->drv->fp)) break; - fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->f); + fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->fp); } mo_log("MO %i: Erased %i bytes of blocks...\n", dev->id, i * dev->drv->sector_size); @@ -1108,7 +1093,8 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) int ready = 0; if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); + mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, + ((dev->tf->request_length >> 5) & 7)); mo_invalid_lun(dev); return 0; } @@ -1133,7 +1119,7 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) return 0; } - ready = (dev->drv->f != NULL); + ready = (dev->drv->fp != NULL); /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark @@ -1179,7 +1165,9 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb) static void mo_seek(mo_t *dev, uint32_t pos) { - /* mo_log("MO %i: Seek %08X\n", dev->id, pos); */ +#if 0 + mo_log("MO %i: Seek %08X\n", dev->id, pos); +#endif dev->sector_pos = pos; } @@ -1196,14 +1184,14 @@ mo_reset(scsi_common_t *sc) mo_t *dev = (mo_t *) sc; mo_rezero(dev); - dev->status = 0; - dev->callback = 0.0; + dev->tf->status = 0; + dev->callback = 0.0; mo_set_callback(dev); - dev->phase = 1; - dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; - dev->unit_attention = 0; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->tf->phase = 1; + dev->tf->request_length = 0xEB14; + dev->packet_status = PHASE_NONE; + dev->unit_attention = 0; + dev->cur_lun = SCSI_LUN_USE_CDB; } static void @@ -1247,7 +1235,7 @@ mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_leng mo_t *dev = (mo_t *) sc; int ready = 0; - ready = (dev->drv->f != NULL); + ready = (dev->drv->fp != NULL); if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -1296,11 +1284,11 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == MO_BUS_SCSI) { - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->tf->status &= ~ERR_STAT; } else { - BufLen = &blen; - dev->error = 0; + BufLen = &blen; + dev->tf->error = 0; } dev->packet_len = 0; @@ -1313,7 +1301,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) if (cdb[0] != 0) { mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention); - mo_log("MO %i: Request length: %04X\n", dev->id, dev->request_length); + mo_log("MO %i: Request length: %04X\n", dev->id, dev->tf->request_length); mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], @@ -1334,7 +1322,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_invalid_field(dev); return; } - /*FALLTHROUGH*/ + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -1417,6 +1405,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; + + default: + break; } if (!dev->sector_len) { @@ -1510,6 +1501,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; + + default: + break; } if ((dev->sector_pos >= dev->drv->medium_size) /* || @@ -1635,6 +1629,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) case 3: /* Load the disk (close tray). */ mo_reload(dev->id); break; + + default: + break; } mo_command_complete(dev); @@ -1687,7 +1684,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[1] = 0x80; /*Removable*/ dev->buffer[2] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->buffer[3] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x21; - // dev->buffer[4] = 31; +#if 0 + dev->buffer[4] = 31; +#endif dev->buffer[4] = 0; if (dev->drv->bus_type == MO_BUS_SCSI) { dev->buffer[6] = 1; /* 16-bit transfers supported */ @@ -1740,6 +1739,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_SEEK_10: pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; + + default: + break; } mo_seek(dev, pos); mo_command_complete(dev); @@ -1778,6 +1780,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_ERASE_12: dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); break; + + default: + break; } /*Erase all remaining sectors*/ @@ -1800,6 +1805,9 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_ERASE_12: dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; + + default: + break; } dev->sector_pos += previous_pos; @@ -1830,9 +1838,11 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) break; } - /* mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ +#if 0 + mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length); +#endif - if (mo_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) mo_buf_free(dev); } @@ -1952,6 +1962,9 @@ mo_phase_data_out(scsi_common_t *sc) return 0; } break; + + default: + break; } mo_command_stop((scsi_common_t *) dev); @@ -2018,7 +2031,7 @@ mo_do_identify(ide_t *ide, int ide_has_dma) { char model[40]; - mo_t *mo = (mo_t *) ide->sc; + const mo_t *mo = (mo_t *) ide->sc; memset(model, 0, 40); @@ -2068,6 +2081,9 @@ mo_drive_reset(int c) dev->cur_lun = SCSI_LUN_USE_CDB; if (mo_drives[c].bus_type == MO_BUS_SCSI) { + if (!dev->tf) + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); + /* SCSI MO, attach to the SCSI bus. */ sd = &scsi_devices[scsi_bus][scsi_id]; @@ -2086,6 +2102,8 @@ mo_drive_reset(int c) that's not attached to anything. */ if (id) { id->sc = (scsi_common_t *) dev; + dev->tf = id->tf; + IDE_ATAPI_IS_EARLY = 0; id->get_max = mo_get_max; id->get_timings = mo_get_timings; id->identify = mo_identify; @@ -2134,6 +2152,9 @@ mo_hard_reset(void) dev = (mo_t *) mo_drives[c].priv; + if (dev->tf == NULL) + continue; + dev->id = c; dev->drv = &mo_drives[c]; @@ -2172,6 +2193,9 @@ mo_close(void) if (dev) { mo_disk_unload(dev); + if (dev->tf) + free(dev->tf); + free(dev); mo_drives[c].priv = NULL; } diff --git a/src/disk/zip.c b/src/disk/zip.c index 62b8f0fe10..d4b6448654 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -36,6 +36,8 @@ #include <86box/hdc_ide.h> #include <86box/zip.h> +#define IDE_ATAPI_IS_EARLY id->sc->pad0 + zip_drive_t zip_drives[ZIP_NUM]; /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ @@ -470,9 +472,9 @@ find_zip_for_channel(uint8_t channel) static int zip_load_abort(zip_t *dev) { - if (dev->drv->f) - fclose(dev->drv->f); - dev->drv->f = NULL; + if (dev->drv->fp) + fclose(dev->drv->fp); + dev->drv->fp = NULL; dev->drv->medium_size = 0; zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; @@ -483,11 +485,16 @@ zip_load(zip_t *dev, char *fn) { int size = 0; - dev->drv->f = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); - if (!dev->drv->f) { + if (!dev->drv) { + zip_eject(dev->id); + return 0; + } + + dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); + if (!dev->drv->fp) { if (!dev->drv->read_only) { - dev->drv->f = plat_fopen(fn, "rb"); - if (dev->drv->f) + dev->drv->fp = plat_fopen(fn, "rb"); + if (dev->drv->fp) dev->drv->read_only = 1; else return zip_load_abort(dev); @@ -495,8 +502,8 @@ zip_load(zip_t *dev, char *fn) return zip_load_abort(dev); } - fseek(dev->drv->f, 0, SEEK_END); - size = ftell(dev->drv->f); + fseek(dev->drv->fp, 0, SEEK_END); + size = ftell(dev->drv->fp); if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { /* This is a ZDI image. */ @@ -521,10 +528,10 @@ zip_load(zip_t *dev, char *fn) dev->drv->medium_size = size >> 9; - if (fseek(dev->drv->f, dev->drv->base, SEEK_SET) == -1) + if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("zip_load(): Error seeking to the beginning of the file\n"); - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + strncpy(dev->drv->image_path, fn, strlen(dev->drv->image_path) + 1); return 1; } @@ -546,16 +553,16 @@ zip_disk_reload(zip_t *dev) void zip_disk_unload(zip_t *dev) { - if (dev->drv->f) { - fclose(dev->drv->f); - dev->drv->f = NULL; + if (dev->drv && dev->drv->fp) { + fclose(dev->drv->fp); + dev->drv->fp = NULL; } } void zip_disk_close(zip_t *dev) { - if (dev->drv->f) { + if (dev->drv && dev->drv->fp) { zip_disk_unload(dev); memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); @@ -588,11 +595,11 @@ zip_init(zip_t *dev) dev->drv->bus_mode |= 1; zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); if (dev->drv->bus_type < ZIP_BUS_SCSI) { - dev->phase = 1; - dev->request_length = 0xEB14; + dev->tf->phase = 1; + dev->tf->request_length = 0xEB14; } - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; + dev->tf->status = READY_STAT | DSC_STAT; + dev->tf->pos = 0; dev->packet_status = PHASE_NONE; zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; } @@ -622,33 +629,9 @@ zip_current_mode(zip_t *dev) if (!zip_supports_pio(dev) && zip_supports_dma(dev)) return 2; if (zip_supports_pio(dev) && zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -zip_atapi_phase_to_scsi(zip_t *dev) -{ - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, + (dev->tf->features & 1) ? "DMA" : "PIO"); + return (dev->tf->features & 1) ? 2 : 1; } return 0; @@ -657,8 +640,8 @@ zip_atapi_phase_to_scsi(zip_t *dev) static void zip_mode_sense_load(zip_t *dev) { - FILE *f; - char file_name[512]; + FILE *fp; + char fn[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (dev->drv->is_250) { @@ -673,33 +656,33 @@ zip_mode_sense_load(zip_t *dev) memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default, sizeof(mode_sense_pages_t)); } - memset(file_name, 0, 512); + memset(fn, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); + sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "rb"); - if (f) { + sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(fn), "rb"); + if (fp) { /* Nothing to read, not used by ZIP. */ - fclose(f); + fclose(fp); } } static void zip_mode_sense_save(zip_t *dev) { - FILE *f; - char file_name[512]; + FILE *fp; + char fn[512]; - memset(file_name, 0, 512); + memset(fn, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(file_name, "scsi_zip_%02i_mode_sense_bin", dev->id); + sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); else - sprintf(file_name, "zip_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "wb"); - if (f) { + sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(fn), "wb"); + if (fp) { /* Nothing to write, not used by ZIP. */ - fclose(f); + fclose(fp); } } @@ -713,13 +696,11 @@ zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) return 0x60; return dev->ms_pages_saved.pages[page][pos]; - break; case 1: if (dev->drv->is_250) return zip_250_mode_sense_pages_changeable.pages[page][pos]; else return zip_mode_sense_pages_changeable.pages[page][pos]; - break; case 2: if (dev->drv->is_250) { if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) @@ -734,6 +715,8 @@ zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) else return zip_mode_sense_pages_default.pages[page][pos]; } + + default: break; } @@ -788,7 +771,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len) int bt; int min_len = 0; - dev->max_transfer_len = dev->request_length; + dev->max_transfer_len = dev->tf->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { @@ -818,7 +801,8 @@ zip_update_request_length(zip_t *dev, int len, int block_len) break; } } - /*FALLTHROUGH*/ + fallthrough; + default: dev->packet_len = len; break; @@ -831,9 +815,9 @@ zip_update_request_length(zip_t *dev, int len, int block_len) dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->tf->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->tf->request_length = dev->max_transfer_len; return; } @@ -864,9 +848,9 @@ zip_command_common(zip_t *dev) double bytes_per_second; double period; - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; + dev->tf->status = BUSY_STAT; + dev->tf->phase = 1; + dev->tf->pos = 0; if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0.0; else { @@ -928,8 +912,8 @@ static void zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction) { zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos = 0; + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length); + dev->tf->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; @@ -958,11 +942,12 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d } zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); + dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, + dev->tf->phase); } static void -zip_sense_clear(zip_t *dev, int command) +zip_sense_clear(zip_t *dev, UNUSED(int command)) { zip_sense_key = zip_asc = zip_ascq = 0; } @@ -983,12 +968,12 @@ static void zip_cmd_error(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; + dev->tf->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; dev->packet_status = PHASE_ERROR; dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); @@ -1000,12 +985,12 @@ static void zip_unit_attention(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; dev->packet_status = PHASE_ERROR; dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); @@ -1093,7 +1078,7 @@ zip_invalid_field(zip_t *dev) zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; zip_ascq = 0; zip_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -1103,7 +1088,7 @@ zip_invalid_field_pl(zip_t *dev) zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; zip_ascq = 0; zip_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -1116,7 +1101,7 @@ zip_data_phase_error(zip_t *dev) } static int -zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out) +zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out) { *len = 0; @@ -1136,17 +1121,17 @@ zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out) *len = dev->requested_blocks << 9; for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->f, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) break; - if (feof(dev->drv->f)) + if (feof(dev->drv->fp)) break; if (out) { - if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) + if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) fatal("zip_blocks(): Error writing data\n"); } else { - if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->f) != 512) + if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) fatal("zip_blocks(): Error reading data\n"); } } @@ -1180,7 +1165,8 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) int ready = 0; if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); + zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, + ((dev->tf->request_length >> 5) & 7)); zip_invalid_lun(dev); return 0; } @@ -1205,7 +1191,7 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) return 0; } - ready = (dev->drv->f != NULL); + ready = (dev->drv->fp != NULL); /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark @@ -1251,7 +1237,9 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb) static void zip_seek(zip_t *dev, uint32_t pos) { - /* zip_log("ZIP %i: Seek %08X\n", dev->id, pos); */ +#if 0 + zip_log("ZIP %i: Seek %08X\n", dev->id, pos); +#endif dev->sector_pos = pos; } @@ -1268,14 +1256,14 @@ zip_reset(scsi_common_t *sc) zip_t *dev = (zip_t *) sc; zip_rezero(dev); - dev->status = 0; - dev->callback = 0.0; + dev->tf->status = 0; + dev->callback = 0.0; zip_set_callback(dev); - dev->phase = 1; - dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; - dev->unit_attention = 0; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->tf->phase = 1; + dev->tf->request_length = 0xEB14; + dev->packet_status = PHASE_NONE; + dev->unit_attention = 0; + dev->cur_lun = SCSI_LUN_USE_CDB; } static void @@ -1319,7 +1307,7 @@ zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_len zip_t *dev = (zip_t *) sc; int ready = 0; - ready = (dev->drv->f != NULL); + ready = (dev->drv->fp != NULL); if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -1367,11 +1355,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == ZIP_BUS_SCSI) { - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->tf->status &= ~ERR_STAT; } else { - BufLen = &blen; - dev->error = 0; + BufLen = &blen; + dev->tf->error = 0; } dev->packet_len = 0; @@ -1382,7 +1370,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) if (cdb[0] != 0) { zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length); + zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->tf->request_length); zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], @@ -1403,7 +1391,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_invalid_field(dev); return; } - /*FALLTHROUGH*/ + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -1459,8 +1447,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ + /* If there's a unit attention condition and there's a buffered not + ready, a standalone REQUEST SENSE should forget about the not + ready, and report unit attention straight away. */ zip_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; @@ -1501,7 +1490,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) switch (cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + /* + For READ (6) and WRITE (6), a length of 0 indicates a + transfer of 256 sectors. + */ + if (dev->sector_len == 0) + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_READ_10: @@ -1510,11 +1506,21 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + + default: break; } + if (dev->sector_pos >= dev->drv->medium_size) { + zip_lba_out_of_range(dev); + return; + } + if (!dev->sector_len) { zip_set_phase(dev, SCSI_PHASE_STATUS); /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ @@ -1525,9 +1531,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) } max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ + /* + If we're reading all blocks in one go for DMA, why not also for + PIO, it should NOT matter anyway, this step should be identical + and only the way the read dat is transferred to the host should + be different. + */ + dev->requested_blocks = max_len; dev->packet_len = max_len * alloc_length; zip_buf_alloc(dev, dev->packet_len); @@ -1549,10 +1559,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_VERIFY_6: @@ -1563,6 +1570,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_command_complete(dev); break; } + fallthrough; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: @@ -1580,9 +1588,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_VERIFY_6: case GPCMD_WRITE_6: dev->sector_len = cdb[4]; + /* + For READ (6) and WRITE (6), a length of 0 indicates a + transfer of 256 sectors. + */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); break; case GPCMD_VERIFY_10: case GPCMD_WRITE_10: @@ -1594,14 +1607,17 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + + default: break; } - if ((dev->sector_pos >= dev->drv->medium_size) /* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ - ) { + if (dev->sector_pos >= dev->drv->medium_size) { zip_lba_out_of_range(dev); return; } @@ -1616,9 +1632,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) } max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ + /* + If we're writing all blocks in one go for DMA, why not also for + PIO, it should NOT matter anyway, this step should be identical + and only the way the read dat is transferred to the host should + be different. + */ + dev->requested_blocks = max_len; dev->packet_len = max_len * alloc_length; zip_buf_alloc(dev, dev->packet_len); @@ -1630,10 +1650,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_WRITE_SAME_10: @@ -1652,9 +1669,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - if ((dev->sector_pos >= dev->drv->medium_size) /* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ - ) { + if (dev->sector_pos >= dev->drv->medium_size) { zip_lba_out_of_range(dev); return; } @@ -1680,10 +1695,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_data_command_finish(dev, 512, 512, alloc_length, 1); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | dev->id, 1); - else - ui_sb_update_icon(SB_ZIP | dev->id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_MODE_SENSE_6: @@ -1768,11 +1780,16 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) case 1: /* Start the disc and read the TOC. */ break; case 2: /* Eject the disc if possible. */ - /* zip_eject(dev->id); */ +#if 0 + zip_eject(dev->id); +#endif break; case 3: /* Load the disc (close tray). */ zip_reload(dev->id); break; + + default: + break; } zip_command_complete(dev); @@ -1850,7 +1867,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[1] = 0x80; /*Removable*/ dev->buffer[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->buffer[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - // dev->buffer[4] = 31; +#if 0 + dev->buffer[4] = 31; +#endif dev->buffer[4] = 0; if (dev->drv->bus_type == ZIP_BUS_SCSI) { dev->buffer[6] = 1; /* 16-bit transfers supported */ @@ -1907,6 +1926,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_SEEK_10: pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; + + default: + break; } zip_seek(dev, pos); zip_command_complete(dev); @@ -1949,7 +1971,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[pos++] = 0; dev->buffer[pos++] = 0; dev->buffer[pos++] = 0; - if (dev->drv->f != NULL) + if (dev->drv->fp != NULL) dev->buffer[pos++] = 16; else dev->buffer[pos++] = 8; @@ -1958,7 +1980,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) if (dev->drv->is_250) { /* ZIP 250 also supports ZIP 100 media, so if the medium is inserted, we return the inserted medium's size, otherwise, the ZIP 250 size. */ - if (dev->drv->f != NULL) { + if (dev->drv->fp != NULL) { dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; dev->buffer[pos++] = (dev->drv->medium_size >> 8) & 0xff; @@ -1978,7 +2000,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[pos++] = (ZIP_SECTORS >> 16) & 0xff; dev->buffer[pos++] = (ZIP_SECTORS >> 8) & 0xff; dev->buffer[pos++] = ZIP_SECTORS & 0xff; - if (dev->drv->f != NULL) + if (dev->drv->fp != NULL) dev->buffer[pos++] = 2; else dev->buffer[pos++] = 3; @@ -1988,7 +2010,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[pos++] = 512 >> 8; dev->buffer[pos++] = 512 & 0xff; - if (dev->drv->f != NULL) { + if (dev->drv->fp != NULL) { /* Formattable capacity descriptor */ dev->buffer[pos++] = (dev->drv->medium_size >> 24) & 0xff; dev->buffer[pos++] = (dev->drv->medium_size >> 16) & 0xff; @@ -2010,9 +2032,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; } - /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ +#if 0 + zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length); +#endif - if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) zip_buf_free(dev); } @@ -2092,9 +2116,9 @@ zip_phase_data_out(scsi_common_t *sc) dev->buffer[6] = (s >> 8) & 0xff; dev->buffer[7] = s & 0xff; } - if (fseek(dev->drv->f, dev->drv->base + (i << 9), SEEK_SET) == -1) + if (fseek(dev->drv->fp, dev->drv->base + (i << 9), SEEK_SET) == -1) fatal("zip_phase_data_out(): Error seeking\n"); - if (fwrite(dev->buffer, 1, 512, dev->drv->f) != 512) + if (fwrite(dev->buffer, 1, 512, dev->drv->fp) != 512) fatal("zip_phase_data_out(): Error writing data\n"); } break; @@ -2171,6 +2195,9 @@ zip_phase_data_out(scsi_common_t *sc) return 0; } break; + + default: + break; } zip_command_stop((scsi_common_t *) dev); @@ -2254,7 +2281,7 @@ zip_250_identify(ide_t *ide, int ide_has_dma) static void zip_identify(ide_t *ide, int ide_has_dma) { - zip_t *zip; + const zip_t *zip; zip = (zip_t *) ide->sc; @@ -2293,6 +2320,9 @@ zip_drive_reset(int c) dev->cur_lun = SCSI_LUN_USE_CDB; if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + if (!dev->tf) + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); + /* SCSI ZIP, attach to the SCSI bus. */ sd = &scsi_devices[scsi_bus][scsi_id]; @@ -2311,6 +2341,8 @@ zip_drive_reset(int c) that's not attached to anything. */ if (id) { id->sc = (scsi_common_t *) dev; + dev->tf = id->tf; + IDE_ATAPI_IS_EARLY = 0; id->get_max = zip_get_max; id->get_timings = zip_get_timings; id->identify = zip_identify; @@ -2359,6 +2391,9 @@ zip_hard_reset(void) dev = (zip_t *) zip_drives[c].priv; + if (dev->tf == NULL) + continue; + dev->id = c; dev->drv = &zip_drives[c]; @@ -2397,6 +2432,9 @@ zip_close(void) if (dev) { zip_disk_unload(dev); + if (dev->tf) + free(dev->tf); + free(dev); zip_drives[c].priv = NULL; } diff --git a/src/dma.c b/src/dma.c index 710ea0abfb..50ae598b82 100644 --- a/src/dma.c +++ b/src/dma.c @@ -31,6 +31,7 @@ #include <86box/io.h> #include <86box/pic.h> #include <86box/dma.h> +#include <86box/plat_unused.h> dma_t dma[8]; uint8_t dma_e; @@ -50,9 +51,9 @@ static uint16_t dma_sg_base; static uint16_t dma16_buffer[65536]; static uint32_t dma_mask; -static struct { - int xfr_command, - xfr_channel; +static struct dma_ps2_t { + int xfr_command; + int xfr_channel; int byte_ptr; int is_ps2; @@ -117,7 +118,7 @@ dma_sg_next_addr(dma_t *dev) dev->eot = dev->count >> 31; dev->count &= 0xfffe; dev->cb = (uint16_t) dev->count; - dev->cc = (int) dev->count; + dev->cc = dev->count; if (!dev->count) dev->count = 65536; if (ts == 2) @@ -132,9 +133,7 @@ dma_sg_next_addr(dma_t *dev) static void dma_block_transfer(int channel) { - int bit16; - - bit16 = (channel >= 4); + int bit16 = (channel >= 4); if (dma_advanced) bit16 = !!(dma_transfer_size(&(dma[channel])) == 2); @@ -228,6 +227,9 @@ dma_sg_write(uint16_t port, uint8_t val, void *priv) dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); dev->ptr %= (mem_size * 1024); break; + + default: + break; } } @@ -258,6 +260,9 @@ dma_sg_writew(uint16_t port, uint16_t val, void *priv) dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); dev->ptr %= (mem_size * 1024); break; + + default: + break; } } @@ -284,13 +289,16 @@ dma_sg_writel(uint16_t port, uint32_t val, void *priv) dev->ptr %= (mem_size * 1024); dev->ptr0 = val & 0xff; break; + + default: + break; } } static uint8_t dma_sg_read(uint16_t port, void *priv) { - dma_t *dev = (dma_t *) priv; + const dma_t *dev = (dma_t *) priv; uint8_t ret = 0xff; @@ -325,6 +333,9 @@ dma_sg_read(uint16_t port, void *priv) case 0x23: ret = dev->ptr >> 24; break; + + default: + break; } dma_log("DMA S/G BYTE read : %04X %02X\n", port, ret); @@ -335,7 +346,7 @@ dma_sg_read(uint16_t port, void *priv) static uint16_t dma_sg_readw(uint16_t port, void *priv) { - dma_t *dev = (dma_t *) priv; + const dma_t *dev = (dma_t *) priv; uint16_t ret = 0xffff; @@ -356,6 +367,9 @@ dma_sg_readw(uint16_t port, void *priv) case 0x22: ret = dev->ptr >> 16; break; + + default: + break; } dma_log("DMA S/G WORD read : %04X %04X\n", port, ret); @@ -366,7 +380,7 @@ dma_sg_readw(uint16_t port, void *priv) static uint32_t dma_sg_readl(uint16_t port, void *priv) { - dma_t *dev = (dma_t *) priv; + const dma_t *dev = (dma_t *) priv; uint32_t ret = 0xffffffff; @@ -384,6 +398,9 @@ dma_sg_readl(uint16_t port, void *priv) case 0x20: ret = dev->ptr0 | (dev->ptr & 0xffffff00); break; + + default: + break; } dma_log("DMA S/G DWORD read : %04X %08X\n", port, ret); @@ -392,7 +409,7 @@ dma_sg_readl(uint16_t port, void *priv) } static void -dma_ext_mode_write(uint16_t addr, uint8_t val, void *priv) +dma_ext_mode_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = (val & 0x03); @@ -416,11 +433,14 @@ dma_ext_mode_write(uint16_t addr, uint8_t val, void *priv) case 0x03: dma[channel].transfer_mode = 0x0102; break; + + default: + break; } } static uint8_t -dma_sg_int_status_read(uint16_t addr, void *priv) +dma_sg_int_status_read(UNUSED(uint16_t addr), UNUSED(void *priv)) { uint8_t ret = 0x00; @@ -433,7 +453,7 @@ dma_sg_int_status_read(uint16_t addr, void *priv) } static uint8_t -dma_read(uint16_t addr, void *priv) +dma_read(uint16_t addr, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; uint8_t temp; @@ -468,13 +488,16 @@ dma_read(uint16_t addr, void *priv) case 0xd: /*Temporary register*/ return 0; + + default: + break; } return (dmaregs[0][addr & 0xf]); } static void -dma_write(uint16_t addr, uint8_t val, void *priv) +dma_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = (addr >> 1) & 3; @@ -562,13 +585,16 @@ dma_write(uint16_t addr, uint8_t val, void *priv) case 0xf: /*Mask write*/ dma_m = (dma_m & 0xf0) | (val & 0xf); return; + + default: + break; } } static uint8_t -dma_ps2_read(uint16_t addr, void *priv) +dma_ps2_read(uint16_t addr, UNUSED(void *priv)) { - dma_t *dma_c = &dma[dma_ps2.xfr_channel]; + const dma_t *dma_c = &dma[dma_ps2.xfr_channel]; uint8_t temp = 0xff; switch (addr) { @@ -589,6 +615,9 @@ dma_ps2_read(uint16_t addr, void *priv) temp = (dma_c->ac >> 16) & 0xff; dma_ps2.byte_ptr = 0; break; + + default: + break; } break; @@ -626,12 +655,15 @@ dma_ps2_read(uint16_t addr, void *priv) fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); } break; + + default: + break; } return temp; } static void -dma_ps2_write(uint16_t addr, uint8_t val, void *priv) +dma_ps2_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { dma_t *dma_c = &dma[dma_ps2.xfr_channel]; uint8_t mode; @@ -654,6 +686,9 @@ dma_ps2_write(uint16_t addr, uint8_t val, void *priv) if (!(dma_m & (1 << dma_ps2.xfr_channel))) dma_ps2_run(dma_ps2.xfr_channel); break; + + default: + break; } break; @@ -683,6 +718,9 @@ dma_ps2_write(uint16_t addr, uint8_t val, void *priv) dma_c->ac = (dma_c->ac & 0x00ffff) | (val << 16); dma_ps2.byte_ptr = 0; break; + + default: + break; } dma_c->ab = dma_c->ac; break; @@ -719,11 +757,14 @@ dma_ps2_write(uint16_t addr, uint8_t val, void *priv) fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); } break; + + default: + break; } } static uint8_t -dma16_read(uint16_t addr, void *priv) +dma16_read(uint16_t addr, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; uint8_t temp; @@ -760,13 +801,16 @@ dma16_read(uint16_t addr, void *priv) temp |= dma_stat >> 4; dma_stat &= ~0xf0; return temp; + + default: + break; } return (dmaregs[1][addr & 0xf]); } static void -dma16_write(uint16_t addr, uint8_t val, void *priv) +dma16_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { int channel = ((addr >> 2) & 3) + 4; addr >>= 1; @@ -855,6 +899,9 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) case 0xf: /*Mask write*/ dma_m = (dma_m & 0x0f) | ((val & 0xf) << 4); return; + + default: + break; } } @@ -864,7 +911,7 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) } static void -dma_page_write(uint16_t addr, uint8_t val, void *priv) +dma_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { uint8_t convert[8] = CHANNELS; @@ -897,27 +944,58 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -dma_page_read(uint16_t addr, void *priv) +dma_page_read(uint16_t addr, UNUSED(void *priv)) { uint8_t convert[8] = CHANNELS; uint8_t ret = 0xff; - addr &= 0x0f; - ret = dmaregs[2][addr]; + if (((addr & 0xfffc) == 0x80) && (CS == 0xf000) && + ((cpu_state.pc & 0xfffffff8) == 0x00007278) && + !strcmp(machine_get_internal_name(), "megapc")) switch (addr) { + /* The Amstrad MegaPC Quadtel BIOS times a sequence of: + mov ax,di + div bx + And expects this value to be at least 0x06e0 for 20 MHz, + and at least 0x0898 for 25 MHz, everything below 0x06e0 + is assumed to be 16 MHz. Given that for some reason, this + does not occur on 86Box, we have to work around it here, + we return 0x0580 for 16 MHz, because it logically follows + in the sequence (0x06e0 = 0x0898 * (20 / 25), and + 0x0580 = 0x06e0 * (16 / 20)). */ + case 0x0081: + if (cpu_busspeed >= 25000000) + ret = 0x98; + else if (cpu_busspeed >= 20000000) + ret = 0xe0; + else + ret = 0x80; + break; + case 0x0082: + if (cpu_busspeed >= 25000000) + ret = 0x08; + else if (cpu_busspeed >= 20000000) + ret = 0x06; + else + ret = 0x05; + break; + } else { + addr &= 0x0f; + ret = dmaregs[2][addr]; - if (addr >= 8) - addr = convert[addr & 0x07] | 4; - else - addr = convert[addr & 0x07]; + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; - if (addr < 8) - ret = dma[addr].page_l; + if (addr < 8) + ret = dma[addr].page_l; + } return ret; } static void -dma_high_page_write(uint16_t addr, uint8_t val, void *priv) +dma_high_page_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { uint8_t convert[8] = CHANNELS; @@ -937,7 +1015,7 @@ dma_high_page_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -dma_high_page_read(uint16_t addr, void *priv) +dma_high_page_read(uint16_t addr, UNUSED(void *priv)) { uint8_t convert[8] = CHANNELS; uint8_t ret = 0xff; @@ -1224,14 +1302,12 @@ dma_sg(uint8_t *data, int transfer_length, int out, void *priv) } } } - - return 1; } uint8_t _dma_read(uint32_t addr, dma_t *dma_c) { - uint8_t temp; + uint8_t temp = 0; if (dma_advanced) { if (dma_c->sg_status & 1) @@ -1247,7 +1323,7 @@ _dma_read(uint32_t addr, dma_t *dma_c) static uint16_t _dma_readw(uint32_t addr, dma_t *dma_c) { - uint16_t temp; + uint16_t temp = 0; if (dma_advanced) { if (dma_c->sg_status & 1) diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 0000000000..72084e11be --- /dev/null +++ b/src/fifo.c @@ -0,0 +1,596 @@ +/* + * 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. + * + * FIFO infrastructure. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#ifdef FIFO_STANDALONE +#define fatal printf +#define pclog_ex printf +#define pclog printf +#include "include/86box/fifo.h" +#else +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/fifo.h> +#endif + +#ifdef ENABLE_FIFO_LOG +int fifo_do_log = ENABLE_FIFO_LOG; + +static void +fifo_log(const char *fmt, ...) +{ + va_list ap; + + if (fifo_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define fifo_log(fmt, ...) +#endif + +int +fifo_get_count(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->len; + + if (fifo->end == fifo->start) + ret = fifo->full ? fifo->len : 0; + else + ret = abs(fifo->end - fifo->start); + + return ret; +} + +void +fifo_write(uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) + fifo->overrun = 1; + else { + fifo->buf[fifo->end] = val; + fifo->end = (fifo->end + 1) & 0x0f; + + if (fifo->end == fifo->start) + fifo->full = 1; + + fifo->empty = 0; + + if (fifo_get_count(fifo) >= fifo->trigger_len) + fifo->ready = 1; + } +} + +void +fifo_write_evt(uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) { + fifo->d_overrun = (fifo->overrun != 1); + fifo->overrun = 1; + if (fifo->d_overrun && (fifo->d_overrun_evt != NULL)) + fifo->d_overrun_evt(fifo->priv); + } else { + fifo->buf[fifo->end] = val; + fifo->end = (fifo->end + 1) & 0x0f; + + if (fifo->end == fifo->start) { + fifo->d_full = (fifo->full != 1); + fifo->full = 1; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + } + + fifo->d_empty = (fifo->empty != 0); + fifo->empty = 0; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + + if (fifo_get_count(fifo) >= fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 1); + fifo->ready = 1; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + } + } +} + +uint8_t +fifo_read(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + fifo->start = (fifo->start + 1) & 0x0f; + + fifo->full = 0; + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->ready = 0; + + if (count == 0) + fifo->empty = 1; + } + } + + return ret; +} + +uint8_t +fifo_read_evt(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = 0; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + fifo->start = (fifo->start + 1) & 0x0f; + + fifo->d_full = (fifo->full != 0); + fifo->full = 0; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 0); + fifo->ready = 0; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + + if (count == 0) { + fifo->d_empty = (fifo->empty != 1); + fifo->empty = 1; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + } + } + } + + return ret; +} + +void +fifo_clear_overrun(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_overrun = (fifo->overrun != 0); + fifo->overrun = 0; +} + +int +fifo_get_full(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + + return fifo->full; +} + +int +fifo_get_d_full(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_full; + + fifo->d_full = 0; + + return ret; +} + +int +fifo_get_empty(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + + return fifo->empty; +} + +int +fifo_get_d_empty(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_empty; + + fifo->d_empty = 0; + + return ret; +} + +int +fifo_get_overrun(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + + return fifo->overrun; +} + +int +fifo_get_d_overrun(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_overrun; + + fifo->d_overrun = 0; + + return ret; +} + +int +fifo_get_ready(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + + return fifo->ready; +} + +int +fifo_get_d_ready(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_ready; + + fifo->d_ready = 0; + + return ret; +} + +int +fifo_get_trigger_len(void *priv) +{ + const fifo_t *fifo = (fifo_t *) priv; + + return fifo->trigger_len; +} + +void +fifo_set_trigger_len(void *priv, int trigger_len) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->trigger_len = trigger_len; +} + +void +fifo_set_len(void *priv, int len) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->len = len; +} + +void +fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full_evt = d_full_evt; +} + +void +fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_empty_evt = d_empty_evt; +} + +void +fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_overrun_evt = d_overrun_evt; +} + +void +fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_ready_evt = d_ready_evt; +} + +void +fifo_set_priv(void *priv, void *sub_priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->priv = sub_priv; +} + +void +fifo_reset(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->start = fifo->end = 0; + fifo->full = fifo->overrun = 0; + fifo->empty = 1; + fifo->ready = 0; +} + +void +fifo_reset_evt(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->start = fifo->end = 0; + fifo->full = fifo->overrun = 0; + fifo->empty = 1; + fifo->ready = 0; + fifo->d_full = fifo->d_overrun = 0; + fifo->d_empty = fifo->d_ready = 0; + + if (fifo->d_full_evt != NULL) + fifo->d_full_evt(fifo->priv); + + if (fifo->d_overrun_evt != NULL) + fifo->d_overrun_evt(fifo->priv); + + if (fifo->d_empty_evt != NULL) + fifo->d_empty_evt(fifo->priv); + + if (fifo->d_ready_evt != NULL) + fifo->d_ready_evt(fifo->priv); +} + +void +fifo_close(void *priv) +{ + free(priv); +} + +void * +fifo_init(int len) +{ + void *fifo = NULL; + + if (len == 64) + fifo = calloc(1, sizeof(fifo64_t)); + else if (len == 16) + fifo = calloc(1, sizeof(fifo16_t)); + else { + fatal("FIFO : Invalid FIFO length: %i\n", len); + return NULL; + } + + if (fifo == NULL) + fatal("FIFO%i: Failed to allocate memory for the FIFO\n", len); + else + ((fifo_t *) fifo)->len = len; + + return fifo; +} + +#ifdef FIFO_STANDALONE +enum { + SERIAL_INT_LSR = 1, + SERIAL_INT_RECEIVE = 2, + SERIAL_INT_TRANSMIT = 4, + SERIAL_INT_MSR = 8, + SERIAL_INT_TIMEOUT = 16 +}; + +typedef struct serial_t { + uint8_t lsr; + uint8_t int_status; + uint8_t tsr; + uint8_t tsr_empty; + + fifo16_t *rcvr_fifo; + fifo16_t *xmit_fifo; +} serial_t; + +static void +serial_receive_timer(fifo16_t *f16, uint8_t val) +{ + fifo_write_evt(val, f16); + + printf("Write %02X to FIFO [F: %i, E: %i, O: %i, R: %i]\n", val, + fifo_get_full(f16), fifo_get_empty(f16), + fifo_get_overrun(f16), fifo_get_ready(f16)); + +#if 0 + if (fifo_get_d_overrun(f16)) + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(f16) << 1); +#endif + + if (fifo_get_d_overrun(f16)) printf(" FIFO overrun state changed: %i -> %i\n", + !fifo_get_overrun(f16), fifo_get_overrun(f16)); + +#if 0 + if (fifo_get_d_empty(f16)) { + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16); + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } +#endif + + if (fifo_get_d_empty(f16)) + printf(" FIFO empty state changed: %i -> %i\n", + !fifo_get_empty(f16), fifo_get_empty(f16)); + +#if 0 + if (fifo_get_d_ready(f16)) { + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(); + } +#endif + if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n", + !fifo_get_ready(f16), fifo_get_ready(f16)); +} + +static uint8_t +serial_read(fifo16_t *f16) +{ + uint8_t ret; + + ret = fifo_read_evt(f16); + + printf("Read %02X from FIFO [F: %i, E: %i, O: %i, R: %i]\n", ret, + fifo_get_full(f16), fifo_get_empty(f16), + fifo_get_overrun(f16), fifo_get_ready(f16)); + +#if 0 + if (fifo_get_d_ready(f16)) { + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(); + } +#endif + + if (fifo_get_d_ready(f16)) + printf(" FIFO ready state changed: %i -> %i\n", + !fifo_get_ready(f16), fifo_get_ready(f16)); + +#if 0 + if (fifo_get_d_empty(f16)) { + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16); + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } +#endif + if (fifo_get_d_empty(f16)) + printf(" FIFO empty state changed: %i -> %i\n", + !fifo_get_empty(f16), fifo_get_empty(f16)); + + return ret; +} + +static void +serial_xmit_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0x9f) | (fifo_get_empty(dev->xmit_fifo) << 5) | + ((dev->tsr_empty && fifo_get_empty(dev->xmit_fifo)) << 6); + dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | + (fifo_get_empty(dev->xmit_fifo) ? SERIAL_INT_TRANSMIT : 0); + // serial_update_ints(); + + printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); + printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status); +} + +static void +serial_rcvr_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo); + // timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + + printf("NS16550: serial_rcvr_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); +} + +static void +serial_rcvr_d_overrun_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1); + + printf("NS16550: serial_rcvr_d_overrun_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); +} + +static void +serial_rcvr_d_ready_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0); + // serial_update_ints(); + + printf("NS16550: serial_rcvr_d_ready_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status); +} + +int +main(int argc, char *argv[]) +{ + uint8_t val; + uint8_t ret; + + printf("Initializing serial...\n"); + serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t)); + dev->tsr_empty = 1; + + printf("Initializing dev->xmit_fifo...\n"); + dev->xmit_fifo = fifo16_init(); + fifo_set_trigger_len(dev->xmit_fifo, 255); + + fifo_set_priv(dev->xmit_fifo, dev); + fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt); + + printf("\nResetting dev->xmit_fifo...\n"); + fifo_reset_evt(dev->xmit_fifo); + + printf("\nInitializing dev->rcvr_fifo...\n"); + dev->rcvr_fifo = fifo16_init(); + fifo_set_trigger_len(dev->rcvr_fifo, 4); + + fifo_set_priv(dev->rcvr_fifo, dev); + fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt); + fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt); + fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt); + + printf("\nResetting dev->rcvr_fifo...\n"); + fifo_reset_evt(dev->rcvr_fifo); + + printf("\nSending/receiving data...\n"); + serial_receive_timer(dev->rcvr_fifo, '8'); + serial_receive_timer(dev->rcvr_fifo, '6'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'B'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'o'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'x'); + ret = serial_read(dev->rcvr_fifo); + ret = serial_read(dev->rcvr_fifo); + + fifo_close(dev->rcvr_fifo); + fifo_close(dev->xmit_fifo); + + free(dev); + + return 0; +} +#endif diff --git a/src/fifo8.c b/src/fifo8.c index 683c446718..feef0deb2c 100644 --- a/src/fifo8.c +++ b/src/fifo8.c @@ -84,7 +84,7 @@ fifo8_pop(Fifo8 *fifo) const uint8_t * fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num) { - uint8_t *ret; + const uint8_t *ret; assert(max > 0 && max <= fifo->num); *num = MIN(fifo->capacity - fifo->head, max); diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index c3bdf293ac..f30d861683 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -36,6 +36,8 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> extern uint64_t motoron[FDD_NUM]; @@ -94,7 +96,7 @@ fdc_log(const char *fmt, ...) # define fdc_log(fmt, ...) #endif -/* +#if 0 const device_t fdc_none_device = { .name = "None", .internal_name = "none", @@ -108,7 +110,7 @@ const device_t fdc_none_device = { .force_redraw = NULL, .config = NULL }; -*/ +#endif const device_t fdc_internal_device = { .name = "Internal", @@ -130,7 +132,9 @@ typedef const struct { static fdc_cards_t fdc_cards[] = { // clang-format off -// { &fdc_none_device }, +#if 0 + { &fdc_none_device }, +#endif { &fdc_internal_device }, { &fdc_b215_device }, { &fdc_pii151b_device }, @@ -164,7 +168,7 @@ fdc_card_has_config(int card) return (device_has_config(fdc_cards[card].device) ? 1 : 0); } -char * +const char * fdc_card_get_internal_name(int card) { return device_get_internal_name(fdc_cards[card].device); @@ -176,7 +180,7 @@ fdc_card_get_from_internal_name(char *s) int c = 0; while (fdc_cards[c].device != NULL) { - if (!strcmp((char *) fdc_cards[c].device->internal_name, s)) + if (!strcmp(fdc_cards[c].device->internal_name, s)) return c; c++; } @@ -187,10 +191,8 @@ fdc_card_get_from_internal_name(char *s) void fdc_card_init(void) { - if (!fdc_cards[fdc_type].device) - return; - - device_add(fdc_cards[fdc_type].device); + if ((fdc_type > 0) && fdc_cards[fdc_type].device) + device_add(fdc_cards[fdc_type].device); } uint8_t @@ -200,9 +202,9 @@ fdc_get_current_drive(void) } void -fdc_ctrl_reset(void *p) +fdc_ctrl_reset(void *priv) { - fdc_t *fdc = (fdc_t *) p; + fdc_t *fdc = (fdc_t *) priv; fdc->stat = 0x80; fdc->pnum = fdc->ptot = 0; @@ -210,6 +212,7 @@ fdc_ctrl_reset(void *p) fdc->lock = 0; fdc->head = 0; fdc->step = 0; + fdc->power_down = 0; if (!(fdc->flags & FDC_FLAG_AT)) fdc->rate = 2; } @@ -224,8 +227,8 @@ int fdc_get_compare_condition(fdc_t *fdc) { switch (fdc->interrupt) { - case 0x11: default: + case 0x11: return 0; case 0x19: return 1; @@ -255,7 +258,7 @@ fdc_set_wrong_am(fdc_t *fdc) int fdc_get_drive(fdc_t *fdc) { - return fdc->drive; + return (int) fdc->drive; } int fdc_get_bitcell_period(fdc_t *fdc); @@ -268,7 +271,7 @@ fdc_get_perp(fdc_t *fdc) if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR)) return 0; - return fdc->perp; + return (int) fdc->perp; } int @@ -290,7 +293,7 @@ fdc_get_gap2(fdc_t *fdc, int drive) int fdc_get_format_n(fdc_t *fdc) { - return fdc->format_n; + return (int) fdc->format_n; } int @@ -319,7 +322,7 @@ fdc_stop_id_request(fdc_t *fdc) int fdc_get_gap(fdc_t *fdc) { - return fdc->gap; + return (int) fdc->gap; } int @@ -331,7 +334,7 @@ fdc_get_dtl(fdc_t *fdc) int fdc_get_format_sectors(fdc_t *fdc) { - return fdc->format_sectors; + return (int) fdc->format_sectors; } static void @@ -416,6 +419,12 @@ fdc_update_rates(fdc_t *fdc) fdc_rate(fdc, 3); } +void +fdc_set_power_down(fdc_t *fdc, uint8_t power_down) +{ + fdc->power_down = power_down; +} + void fdc_update_max_track(fdc_t *fdc, int max_track) { @@ -425,7 +434,7 @@ fdc_update_max_track(fdc_t *fdc, int max_track) void fdc_update_enh_mode(fdc_t *fdc, int enh_mode) { - fdc->enh_mode = enh_mode; + fdc->enh_mode = !!enh_mode; fdc_update_rates(fdc); } @@ -488,7 +497,7 @@ fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate) void fdc_update_drv2en(fdc_t *fdc, int drv2en) { - fdc->drv2en = drv2en; + fdc->drv2en = !!drv2en; } void @@ -498,31 +507,34 @@ fdc_update_rate(fdc_t *fdc, int drive) fdc->bit_rate = 500; else if ((fdc->rwc[drive] == 3) && fdc->enh_mode) fdc->bit_rate = 250; - else - switch (fdc->rate) { - case 0: /*High density*/ - fdc->bit_rate = 500; - break; - case 1: /*Double density (360 rpm)*/ - switch (fdc->drvrate[drive]) { - case 0: - fdc->bit_rate = 300; - break; - case 1: - fdc->bit_rate = 500; - break; - case 2: - fdc->bit_rate = 2000; - break; - } - break; - case 2: /*Double density*/ - fdc->bit_rate = 250; - break; - case 3: /*Extended density*/ - fdc->bit_rate = 1000; - break; - } + else switch (fdc->rate) { + default: + break; + case 0: /*High density*/ + fdc->bit_rate = 500; + break; + case 1: /*Double density (360 rpm)*/ + switch (fdc->drvrate[drive]) { + default: + break; + case 0: + fdc->bit_rate = 300; + break; + case 1: + fdc->bit_rate = 500; + break; + case 2: + fdc->bit_rate = 2000; + break; + } + break; + case 2: /*Double density*/ + fdc->bit_rate = 250; + break; + case 3: /*Extended density*/ + fdc->bit_rate = 1000; + break; + } fdc->bitcell_period = (1000000 / fdc->bit_rate) * 2; /*Bitcell period in ns*/ } @@ -541,8 +553,9 @@ fdc_get_bit_rate(fdc_t *fdc) return 2; case 1000: return 3; + default: - return 2; + break; } return 2; } @@ -563,6 +576,9 @@ fdc_get_densel(fdc_t *fdc, int drive) return 0; case 2: return 1; + + default: + break; } } @@ -572,6 +588,9 @@ fdc_get_densel(fdc_t *fdc, int drive) return 1; case 3: return 0; + + default: + break; } } else { switch (fdc->densel_force) { @@ -579,6 +598,9 @@ fdc_get_densel(fdc_t *fdc, int drive) return 0; case 1: return 1; + + default: + break; } } @@ -589,6 +611,9 @@ fdc_get_densel(fdc_t *fdc, int drive) case 1: case 2: return fdc->densel_polarity ? 0 : 1; + + default: + break; } return 0; @@ -598,7 +623,9 @@ static void fdc_rate(fdc_t *fdc, int drive) { fdc_update_rate(fdc, drive); - // fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force); +#if 0 + fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force); +#endif fdc_log("FDD %c: [%i] Setting rate: %i, %i, %i (%i, %i, %i)\n", 0x41 + drive, fdc->enh_mode, fdc->drvrate[drive], fdc->rate, fdc_get_densel(fdc, drive), fdc->rwc[drive], fdc->densel_force, fdc->densel_polarity); fdd_set_densel(fdc_get_densel(fdc, drive)); fdc_log("FDD %c: [%i] Densel: %i\n", 0x41 + drive, fdc->enh_mode, fdc_get_densel(fdc, drive)); @@ -665,10 +692,6 @@ fdc_io_command_phase1(fdc_t *fdc, int out) fdc->stat |= 0x20; else dma_set_drq(fdc->dma_ch, 1); - if (out) - fdc->pos = 0; - else - fdc->inread = 1; } static void @@ -718,7 +741,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) cycles -= ISA_CYCLES(8); - switch (addr & 7) { + if (!fdc->power_down || ((addr & 7) == 2) || ((addr & 7) == 4)) switch (addr & 7) { case 0: return; case 1: @@ -753,14 +776,20 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = fdc->ptot = 0; } if ((val & 4) && !(fdc->dor & 4)) { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - fdc->perp &= 0xfc; + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); + fdc->perp &= 0xfc; - fdc_ctrl_reset(fdc); + for (i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + } } /* We can now simplify this since each motor now spins separately. */ for (i = 0; i < FDD_NUM; i++) { @@ -831,7 +860,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 4; fdc->stat |= 0x90; - fdc->pos = 0; fdc->format_state = 0; } else fdc_bad_command(fdc); @@ -843,7 +871,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x03: /*Specify*/ @@ -865,7 +892,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x06: /*Read data*/ @@ -884,7 +910,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 8; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x17: /*Powerdown mode*/ @@ -892,7 +917,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } - /*FALLTHROUGH*/ + fallthrough; case 0x07: /*Recalibrate*/ fdc->pnum = 0; fdc->ptot = 1; @@ -901,28 +926,24 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x08: /*Sense interrupt status*/ fdc_log("fdc->fintr = %i, fdc->reset_stat = %i\n", fdc->fintr, fdc->reset_stat); fdc->lastdrive = fdc->drive; - fdc->pos = 0; fdc_sis(fdc); break; case 0x0a: /*Read sector ID*/ fdc->pnum = 0; fdc->ptot = 1; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; break; case 0x0d: /*Format track*/ fdc->pnum = 0; fdc->ptot = 5; fdc->stat |= 0x90; - fdc->pos = 0; fdc->mfm = (fdc->command & 0x40) ? 1 : 0; fdc->format_state = 0; break; case 0x0e: /*Dump registers*/ fdc->lastdrive = fdc->drive; fdc->interrupt = 0x0e; - fdc->pos = 0; fdc_callback(fdc); break; case 0x0f: /*Seek*/ @@ -935,13 +956,12 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } - /*FALLTHROUGH*/ + fallthrough; case 0x10: /*Get version*/ case 0x14: /*Unlock*/ case 0x94: /*Lock*/ fdc->lastdrive = fdc->drive; fdc->interrupt = fdc->command; - fdc->pos = 0; fdc_callback(fdc); break; case 0x12: /*Set perpendicular mode*/ @@ -949,7 +969,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 1; fdc->stat |= 0x90; - fdc->pos = 0; } else fdc_bad_command(fdc); break; @@ -957,7 +976,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pnum = 0; fdc->ptot = 3; fdc->stat |= 0x90; - fdc->pos = 0; break; default: fdc_bad_command(fdc); @@ -1057,7 +1075,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x16: /* Verify */ if (fdc->params[0] & 0x80) fdc->sc = fdc->params[7]; - /*FALLTHROUGH*/ + fallthrough; case 0x06: /* Read data */ case 0x0c: /* Read deleted data */ fdc_io_command_phase1(fdc, 0); @@ -1128,7 +1146,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->format_sectors = fdc->params[2]; fdc->format_n = fdc->params[1]; fdc->format_state = 1; - fdc->pos = 0; fdc->stat = 0x10; break; case 0x0f: /* Seek */ @@ -1136,7 +1153,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat = (1 << fdc->drive); if (!(fdc->flags & FDC_FLAG_PCJR)) fdc->stat |= 0x80; - /* fdc->head = (fdc->params[0] & 4) ? 1 : 0; */ +#if 0 + fdc->head = (fdc->params[0] & 4) ? 1 : 0; +#endif fdc->head = 0; /* TODO: See if this is correct. */ fdc->st0 = fdc->params[0] & 0x03; fdc->st0 |= (fdc->params[0] & 4); @@ -1223,6 +1242,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->perp |= (fdc->params[0] & 0x03); } return; + + default: + break; } } else fdc->stat = 0x90 | (fdc->stat & 0xf); @@ -1235,6 +1257,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) if (fdc->flags & FDC_FLAG_PS1) fdc->noprec = !!(val & 0x04); return; + + default: + break; } } @@ -1242,12 +1267,12 @@ uint8_t fdc_read(uint16_t addr, void *priv) { fdc_t *fdc = (fdc_t *) priv; - uint8_t ret; + uint8_t ret = 0xff; int drive = 0; cycles -= ISA_CYCLES(8); - switch (addr & 7) { + if (!fdc->power_down || ((addr & 7) == 2)) switch (addr & 7) { case 0: /* STA */ if (fdc->flags & FDC_FLAG_PS1) { drive = real_drive(fdc, fdc->dor & 3); @@ -1293,6 +1318,9 @@ fdc_read(uint16_t addr, void *priv) case 3: ret |= 0x61; break; + + default: + break; } } else { if (is486 || !fdc->enable_3f1) @@ -1479,7 +1507,6 @@ fdc_poll_readwrite_finish(fdc_t *fdc, int compare) if ((fdc->interrupt == 5) || (fdc->interrupt == 9)) fdd_do_writeback(real_drive(fdc, fdc->drive)); - fdc->inread = 0; fdc->interrupt = -2; fdc_poll_common_finish(fdc, compare, 0); @@ -1510,10 +1537,21 @@ fdc_callback(void *priv) case -2: /*End of command*/ fdc->stat = (fdc->stat & 0xf) | 0x80; return; + case -5: /*Reset in power down mode */ + fdc->perp &= 0xfc; + + for (uint8_t i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + + fdc->fintr = 0; + memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); + return; case -1: /*Reset*/ fdc_int(fdc, 1); fdc->fintr = 0; - memset(fdc->pcn, 0, 4 * sizeof(int)); + memset(fdc->pcn, 0x00, 4 * sizeof(uint16_t)); fdc->reset_stat = 4; return; case 0x01: /* Mode */ @@ -1536,7 +1574,6 @@ fdc_callback(void *priv) fdc->stat = 0x50; } } - fdc->inread = 1; return; case 0x04: /* Sense drive status */ fdc->res[10] = (fdc->params[0] & 7) | 0x20; @@ -1677,8 +1714,10 @@ fdc_callback(void *priv) fdc->stat = 0x90; } break; + + default: + break; } - fdc->inread = 1; return; case 0x07: /* Recalibrate */ fdc->pcn[fdc->params[0] & 3] = 0; @@ -1780,6 +1819,9 @@ fdc_callback(void *priv) fdc->paramstogo = 1; fdc->interrupt = 0; return; + + default: + break; } } @@ -1964,18 +2006,11 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) return 0; } -void -fdc_finishread(fdc_t *fdc) -{ - fdc->inread = 0; -} - void fdc_track_finishread(fdc_t *fdc, int condition) { fdc->stat = 0x10; fdc->satisfying_sectors |= condition; - fdc->inread = 0; fdc_callback(fdc); } @@ -1985,7 +2020,6 @@ fdc_sector_finishcompare(fdc_t *fdc, int satisfying) fdc->stat = 0x10; if (satisfying) fdc->satisfying_sectors++; - fdc->inread = 0; fdc_callback(fdc); } @@ -1993,7 +2027,6 @@ void fdc_sector_finishread(fdc_t *fdc) { fdc->stat = 0x10; - fdc->inread = 0; fdc_callback(fdc); } @@ -2113,7 +2146,7 @@ fdc_getdata(fdc_t *fdc, int last) } void -fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2) +fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, UNUSED(uint8_t crc1), UNUSED(uint8_t crc2)) { fdc_int(fdc, 1); fdc->stat = 0xD0; @@ -2316,6 +2349,8 @@ fdc_reset(void *priv) for (uint8_t i = 0; i < FDD_NUM; i++) ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc->power_down = 0; } static void @@ -2378,7 +2413,7 @@ fdc_init(const device_t *info) void fdc_3f1_enable(fdc_t *fdc, int enable) { - fdc->enable_3f1 = enable; + fdc->enable_3f1 = !!enable; } const device_t fdc_xt_device = { diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index d71721d7be..084ce8c818 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -29,19 +29,19 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> +#include <86box/plat_unused.h> #define ROM_B215 "roms/floppy/magitronic/Magitronic B215 - BIOS ROM.bin" #define ROM_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff) #define DRIVE_SELECT (int) (real_drive(dev->fdc_controller, i)) -typedef struct -{ +typedef struct b215_t { fdc_t *fdc_controller; rom_t rom; } b215_t; static uint8_t -b215_read(uint16_t addr, void *priv) +b215_read(UNUSED(uint16_t addr), void *priv) { b215_t *dev = (b215_t *) priv; @@ -58,7 +58,7 @@ b215_read(uint16_t addr, void *priv) */ int drive_spec[2]; - for (int i = 0; i <= 1; i++) { + for (uint8_t i = 0; i <= 1; i++) { if (fdd_is_525(DRIVE_SELECT)) { if (!fdd_is_dd(DRIVE_SELECT)) drive_spec[i] = 1; @@ -88,7 +88,7 @@ b215_close(void *priv) } static void * -b215_init(const device_t *info) +b215_init(UNUSED(const device_t *info)) { b215_t *dev = (b215_t *) malloc(sizeof(b215_t)); memset(dev, 0, sizeof(b215_t)); diff --git a/src/floppy/fdc_monster.c b/src/floppy/fdc_monster.c index 00a9d968ab..1629ac1c46 100644 --- a/src/floppy/fdc_monster.c +++ b/src/floppy/fdc_monster.c @@ -32,12 +32,12 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> +#include <86box/plat_unused.h> #define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff) #define ROM_MONSTER_FDC "roms/floppy/monster-fdc/floppy_bios.bin" -typedef struct -{ +typedef struct monster_fdc_t { rom_t bios_rom; fdc_t *fdc_pri; fdc_t *fdc_sec; @@ -52,7 +52,7 @@ monster_fdc_close(void *priv) } static void * -monster_fdc_init(const device_t *info) +monster_fdc_init(UNUSED(const device_t *info)) { monster_fdc_t *dev; diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index be471faceb..5fd38d2502 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -80,8 +80,7 @@ MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be. #define ROM_PII_151B "roms/floppy/dtk/pii-151b.rom" #define ROM_PII_158B "roms/floppy/dtk/pii-158b.rom" -typedef struct -{ +typedef struct pii_t { rom_t bios_rom; } pii_t; diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 16d414af39..09e791c4ed 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -64,7 +64,7 @@ #define FLAG_IGNORE_DENSEL 512 #define FLAG_PS2 1024 -typedef struct { +typedef struct fdd_t { int type; int track; int densel; @@ -451,10 +451,10 @@ fdd_get_densel(int drive) void fdd_load(int drive, char *fn) { - int c = 0; - int size; - char *p; - FILE *f; + int c = 0; + int size; + const char *p; + FILE * fp; fdd_log("FDD: loading drive %d with '%s'\n", drive, fn); @@ -463,12 +463,12 @@ fdd_load(int drive, char *fn) p = path_get_extension(fn); if (!p) return; - f = plat_fopen(fn, "rb"); - if (f) { - if (fseek(f, -1, SEEK_END) == -1) + fp = plat_fopen(fn, "rb"); + if (fp) { + if (fseek(fp, -1, SEEK_END) == -1) fatal("fdd_load(): Error seeking to the end of the file\n"); - size = ftell(f) + 1; - fclose(f); + size = ftell(fp) + 1; + fclose(fp); while (loaders[c].ext) { if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { driveloaders[drive] = c; @@ -548,8 +548,8 @@ fdd_set_motor_enable(int drive, int motor_enable) static void fdd_poll(void *priv) { - int drive; - DRIVE *drv = (DRIVE *) priv; + int drive; + const DRIVE *drv = (DRIVE *) priv; drive = drv->id; @@ -586,6 +586,9 @@ fdd_get_bitcell_period(int rate) case 3: /*Extended density*/ bit_rate = 1000; break; + + default: + break; } return 1000000 / bit_rate * 2; /*Bitcell period in ns*/ diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index f0bf6b7f7a..fa1c070f15 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -125,32 +125,38 @@ enum { FMT_POSTTRK_GAP4 }; -typedef struct { +typedef struct sliding_buffer_t { uint8_t buffer[10]; uint32_t pos; uint32_t len; } sliding_buffer_t; -typedef struct { +typedef struct find_t { uint32_t bits_obtained; uint16_t bytes_obtained; uint16_t sync_marks; uint32_t sync_pos; } find_t; -typedef struct { +typedef struct split_byte_t { unsigned nibble0 : 4; unsigned nibble1 : 4; } split_byte_t; -typedef union { +typedef union decoded_t { uint8_t byte; split_byte_t nibbles; } decoded_t; -typedef struct { - uint8_t c, h, r, n; - uint8_t flags, pad, pad0, pad1; +typedef struct sector_t { + uint8_t c; + uint8_t h; + uint8_t r; + uint8_t n; + uint8_t flags; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; void *prev; } sector_t; @@ -173,11 +179,18 @@ typedef struct { * If bits 6, 5 are 0, and bit 7 is 1, the extra bitcell count * specifies the entire bitcell count */ -typedef struct { - FILE *f; - uint8_t state, fill, sector_count, format_state, - error_condition, id_found; - uint16_t version, disk_flags, satisfying_bytes, turbo_pos; +typedef struct d86f_t { + FILE *fp; + uint8_t state; + uint8_t fill; + uint8_t sector_count; + uint8_t format_state; + uint8_t error_condition; + uint8_t id_found; + uint16_t version; + uint16_t disk_flags; + uint16_t satisfying_bytes; + uint16_t turbo_pos; uint16_t cur_track; uint16_t track_encoded_data[2][53048]; uint16_t *track_surface_data[2]; @@ -191,9 +204,13 @@ typedef struct { #ifdef D86F_COMPRESS int is_compressed; #endif - int32_t extra_bit_cells[2]; - uint32_t file_size, index_count, track_pos, datac, - id_pos, dma_over; + int32_t extra_bit_cells[2]; + uint32_t file_size; + uint32_t index_count; + uint32_t track_pos; + uint32_t datac; + uint32_t id_pos; + uint32_t dma_over; uint32_t index_hole_pos[2]; uint32_t track_offset[512]; sector_id_t last_sector; @@ -203,7 +220,8 @@ typedef struct { crc_t calc_crc; crc_t track_crc; char original_file_name[2048]; - uint8_t *filebuf, *outbuf; + uint8_t *filebuf; + uint8_t *outbuf; sector_t *last_side_sector[2]; } d86f_t; @@ -337,7 +355,7 @@ d86f_reverse_bytes(int drive) uint16_t d86f_disk_flags(int drive) { - d86f_t *dev = d86f[drive]; + const d86f_t *dev = d86f[drive]; return dev->disk_flags; } @@ -345,49 +363,49 @@ d86f_disk_flags(int drive) uint32_t d86f_index_hole_pos(int drive, int side) { - d86f_t *dev = d86f[drive]; + const d86f_t *dev = d86f[drive]; return dev->index_hole_pos[side]; } uint32_t -null_index_hole_pos(int drive, int side) +null_index_hole_pos(UNUSED(int drive), UNUSED(int side)) { return 0; } uint16_t -null_disk_flags(int drive) +null_disk_flags(UNUSED(int drive)) { return 0x09; } uint16_t -null_side_flags(int drive) +null_side_flags(UNUSED(int drive)) { return 0x0A; } void -null_writeback(int drive) +null_writeback(UNUSED(int drive)) { return; } void -null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +null_set_sector(UNUSED(int drive), UNUSED(int side), UNUSED(uint8_t c), UNUSED(uint8_t h), UNUSED(uint8_t r), UNUSED(uint8_t n)) { return; } void -null_write_data(int drive, int side, uint16_t pos, uint8_t data) +null_write_data(UNUSED(int drive), UNUSED(int side), UNUSED(uint16_t pos), UNUSED(uint8_t data)) { return; } int -null_format_conditions(int drive) +null_format_conditions(UNUSED(int drive)) { return 0; } @@ -395,13 +413,13 @@ null_format_conditions(int drive) int32_t d86f_extra_bit_cells(int drive, int side) { - d86f_t *dev = d86f[drive]; + const d86f_t *dev = d86f[drive]; return dev->extra_bit_cells[side]; } int32_t -null_extra_bit_cells(int drive, int side) +null_extra_bit_cells(UNUSED(int drive), UNUSED(int side)) { return 0; } @@ -415,7 +433,7 @@ common_encoded_data(int drive, int side) } void -common_read_revolution(int drive) +common_read_revolution(UNUSED(int drive)) { return; } @@ -423,8 +441,8 @@ common_read_revolution(int drive) uint16_t d86f_side_flags(int drive) { - d86f_t *dev = d86f[drive]; - int side; + const d86f_t *dev = d86f[drive]; + int side; side = fdd_get_head(drive); @@ -619,9 +637,9 @@ d86f_get_array_size(int drive, int side, int words) array_size = 0; else switch (hole) { + default: case 0: case 1: - default: array_size = 12500; switch (rm) { case 1: @@ -793,9 +811,9 @@ d86f_is_mfm(int drive) uint32_t d86f_get_data_len(int drive) { - d86f_t *dev = d86f[drive]; - uint32_t i; - uint32_t ret = 128; + const d86f_t *dev = d86f[drive]; + uint32_t i; + uint32_t ret = 128; if (dev->req_sector.id.n) ret = (uint32_t) 128 << dev->req_sector.id.n; @@ -812,7 +830,7 @@ d86f_has_extra_bit_cells(int drive) } uint32_t -d86f_header_size(int drive) +d86f_header_size(UNUSED(int drive)) { return 8; } @@ -884,15 +902,14 @@ d86f_wrong_densel(int drive) is_3mode = 1; switch (d86f_hole(drive)) { - case 0: default: + case 0: if (fdd_is_dd(drive)) return 0; if (fdd_get_densel(drive)) return 1; else return 0; - break; case 1: if (fdd_is_dd(drive)) @@ -905,7 +922,6 @@ d86f_wrong_densel(int drive) else return 1; } - break; case 2: if (fdd_is_dd(drive) || !fdd_is_ed(drive)) @@ -914,7 +930,6 @@ d86f_wrong_densel(int drive) return 0; else return 1; - break; } } @@ -965,6 +980,9 @@ d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) case 0xfc: return result | d86f_encode_get_clock(0x01); + + default: + break; } } else { switch (b.byte) { @@ -975,6 +993,9 @@ d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) case 0xfc: return result | d86f_encode_get_clock(0xd7); + + default: + break; } } } @@ -1022,6 +1043,9 @@ d86f_get_bitcell_period(int drive) case 5: rate = 2000.0; break; + + default: + break; } if (!mfm) @@ -1176,7 +1200,7 @@ d86f_put_bit(int drive, int side, int bit) } static uint8_t -decodefm(int drive, uint16_t dat) +decodefm(UNUSED(int drive), uint16_t dat) { uint8_t temp = 0; @@ -1219,8 +1243,8 @@ d86f_calccrc(d86f_t *dev, uint8_t byte) int d86f_word_is_aligned(int drive, int side, uint32_t base_pos) { - d86f_t *dev = d86f[drive]; - uint32_t adjusted_track_pos = dev->track_pos; + const d86f_t *dev = d86f[drive]; + uint32_t adjusted_track_pos = dev->track_pos; if (base_pos == 0xFFFFFFFF) return 0; @@ -1250,18 +1274,19 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui if (dev->last_word[side] == req_am) { dev->calc_crc.word = 0xFFFF; fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - dev->preceding_bit[side] = dev->last_word[side] & 1; + find->sync_marks = find->bits_obtained = + find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + dev->preceding_bit[side] = dev->last_word[side] & 1; dev->state++; return; } if (wrong_am && (dev->last_word[side] == wrong_am)) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_nodataam(d86f_fdc); return; } @@ -1304,8 +1329,9 @@ d86f_write_find_address_mark_fm(int drive, int side, find_t *find) /* If we hadn't found enough set bits but have found a clear bit, null the counter of set bits. */ if (!(dev->last_word[side] & 1)) { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; + find->sync_marks = find->bits_obtained = + find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; } } @@ -1323,10 +1349,10 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u } if (wrong_am && (dev->last_word[side] == wrong_am) && (find->sync_marks >= 3)) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_nodataam(d86f_fdc); return; } @@ -1409,22 +1435,26 @@ d86f_read_sector_id(int drive, int side, int match) if (!(dev->id_find.bits_obtained & 15)) { /* We've got a byte. */ if (dev->id_find.bytes_obtained < 4) { - dev->last_sector.byte_array[dev->id_find.bytes_obtained] = decodefm(drive, dev->last_word[side]); + dev->last_sector.byte_array[dev->id_find.bytes_obtained] = + decodefm(drive, dev->last_word[side]); fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc)); } else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) { - dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = decodefm(drive, dev->last_word[side]); + dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = + decodefm(drive, dev->last_word[side]); } dev->id_find.bytes_obtained++; if (dev->id_find.bytes_obtained == 6) { /* We've got the ID. */ - if ((dev->calc_crc.word != dev->track_crc.word) && (dev->last_sector.dword == dev->req_sector.dword)) { - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); + if ((dev->calc_crc.word != dev->track_crc.word) && + (dev->last_sector.dword == dev->req_sector.dword)) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = 0; + d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, + dev->calc_crc.word, dev->last_sector.dword); if ((dev->state != STATE_02_READ_ID) && (dev->state != STATE_0A_READ_ID)) { dev->error_condition = 0; dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); fdc_headercrcerror(d86f_fdc); } else if (dev->state == STATE_0A_READ_ID) dev->state--; @@ -1434,25 +1464,37 @@ d86f_read_sector_id(int drive, int side, int match) } } else if ((dev->calc_crc.word == dev->track_crc.word) && (dev->state == STATE_0A_READ_ID)) { /* CRC is valid and this is a read sector ID command. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; - fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_sectorid(d86f_fdc, + dev->last_sector.id.c, dev->last_sector.id.h, + dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); dev->state = STATE_IDLE; } else { /* CRC is valid. */ - dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->id_find.sync_marks = dev->id_find.bits_obtained = + dev->id_find.bytes_obtained = 0; dev->id_found |= 1; if ((dev->last_sector.dword == dev->req_sector.dword) || !match) { - d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); + d86f_handler[drive].set_sector(drive, side, + dev->last_sector.id.c, dev->last_sector.id.h, + dev->last_sector.id.r, dev->last_sector.id.n); if (dev->state == STATE_02_READ_ID) { /* READ TRACK command, we need some special handling here. */ - /* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */ - if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { - dev->error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */ + /* Code corrected: Only the C, H, and N portions of the + sector ID are compared, the R portion + (the sector number) is ignored. */ + if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || + (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || + (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { + /* Mark that the sector ID is not the one expected by the FDC. */ + dev->error_condition |= 4; /* Make sure we use the sector size from the FDC. */ dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; } - /* If the two ID's are identical, then we do not need to do anything regarding the sector size. */ + /* If the two ID's are identical, then we do not need to do + anything regarding the sector size. */ } dev->state++; } else { @@ -1524,6 +1566,9 @@ d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte) if ((received_byte >= disk_byte) || (received_byte == 0xFF)) dev->satisfying_bytes++; break; + + default: + break; } } @@ -1549,7 +1594,8 @@ d86f_read_sector_data(int drive, int side) data = d86f_handler[drive].read_data(drive, side, dev->data_find.bytes_obtained); else { #ifdef HACK_FOR_DBASE_III - if ((dev->last_sector.id.c == 39) && (dev->last_sector.id.h == 0) && (dev->last_sector.id.r == 5) && (dev->data_find.bytes_obtained >= 272)) + if ((dev->last_sector.id.c == 39) && (dev->last_sector.id.h == 0) && + (dev->last_sector.id.r == 5) && (dev->data_find.bytes_obtained >= 272)) data = (random_generate() & 0xff); else #endif @@ -1562,7 +1608,9 @@ d86f_read_sector_data(int drive, int side) } else { if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, data, dev->data_find.bytes_obtained == (d86f_get_data_len(drive) - 1)); + read_status = fdc_data(d86f_fdc, data, + dev->data_find.bytes_obtained == + (d86f_get_data_len(drive) - 1)); if (read_status == -1) dev->dma_over++; } @@ -1570,17 +1618,19 @@ d86f_read_sector_data(int drive, int side) } fdd_calccrc(data, &(dev->calc_crc)); } else if (dev->data_find.bytes_obtained < crc_pos) - dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]); + dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = + decodefm(drive, dev->last_word[side]); dev->data_find.bytes_obtained++; if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { /* We've got the data. */ if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { - d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); + d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, + dev->calc_crc.word, dev->last_sector.dword); + dev->data_find.sync_marks = dev->data_find.bits_obtained = + dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; fdc_datacrcerror(d86f_fdc); } else if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state == STATE_02_READ_DATA)) { dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; @@ -1632,7 +1682,7 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) d86f_handler[drive].write_data(drive, side, dev->data_find.bytes_obtained - 1, dev->current_byte[side]); } else { /* We're in the data field of the sector, use a CRC byte. */ - dev->current_byte[side] = dev->calc_crc.bytes[(dev->data_find.bytes_obtained & 1)]; + dev->current_byte[side] = dev->calc_crc.bytes[dev->data_find.bytes_obtained & 1]; } dev->current_bit[side] = (15 - (dev->data_find.bits_obtained & 15)) >> 1; @@ -1814,7 +1864,7 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 void d86f_write_direct(int drive, int side, uint16_t byte, uint8_t type) { - d86f_t *dev = d86f[drive]; + const d86f_t *dev = d86f[drive]; d86f_write_direct_common(drive, side, byte, type, dev->track_pos >> 4); } @@ -1832,7 +1882,7 @@ endian_swap(uint16_t word) } void -d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, int do_write) +d86f_format_finish(int drive, int side, int mfm, UNUSED(uint16_t sc), uint16_t gap_fill, int do_write) { d86f_t *dev = d86f[drive]; @@ -1853,7 +1903,7 @@ d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, } void -d86f_format_turbo_finish(int drive, int side, int do_write) +d86f_format_turbo_finish(int drive, UNUSED(int side), int do_write) { d86f_t *dev = d86f[drive]; @@ -1924,7 +1974,7 @@ d86f_format_track(int drive, int side, int do_write) if (dev->datac == 3) fdc_stop_id_request(d86f_fdc); } - /*FALLTHROUGH*/ + fallthrough; case FMT_PRETRK_SYNC: case FMT_SECTOR_DATA_SYNC: @@ -2053,13 +2103,14 @@ d86f_format_track(int drive, int side, int do_write) /* Sector within allotted amount, change state to SECTOR_ID_SYNC. */ dev->format_state = FMT_SECTOR_ID_SYNC; fdc_request_next_sector_id(d86f_fdc); - break; } else { dev->format_state = FMT_POSTTRK_GAP4; dev->sector_count = 0; - break; } break; + + default: + break; } } } @@ -2078,9 +2129,9 @@ d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n) static uint8_t d86f_sector_flags(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { - d86f_t *dev = d86f[drive]; - sector_t *s; - sector_t *t; + const d86f_t *dev = d86f[drive]; + sector_t *s; + sector_t *t; if (dev->last_side_sector[side]) { s = dev->last_side_sector[side]; @@ -2118,7 +2169,8 @@ d86f_turbo_read(int drive, int side) } else { if (dev->turbo_pos < (128UL << dev->req_sector.id.n)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, dat, dev->turbo_pos == ((128UL << dev->req_sector.id.n) - 1)); + read_status = fdc_data(d86f_fdc, dat, + dev->turbo_pos == ((128UL << dev->req_sector.id.n) - 1)); if (read_status == -1) dev->dma_over++; } @@ -2135,7 +2187,6 @@ d86f_turbo_read(int drive, int side) #endif dev->error_condition = 0; dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); fdc_datacrcerror(d86f_fdc); } else if ((flags & SECTOR_CRC_ERROR) && (dev->state == STATE_02_READ_DATA)) { #ifdef ENABLE_D86F_LOG @@ -2229,9 +2280,9 @@ d86f_turbo_format(int drive, int side, int nop) int d86f_sector_is_present(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { - d86f_t *dev = d86f[drive]; - sector_t *s; - sector_t *t; + const d86f_t *dev = d86f[drive]; + sector_t *s; + sector_t *t; if (dev->last_side_sector[side]) { s = dev->last_side_sector[side]; @@ -2266,7 +2317,7 @@ d86f_turbo_poll(int drive, int side) case STATE_0D_SPIN_TO_INDEX: dev->sector_count = 0; dev->datac = 5; - /*FALLTHROUGH*/ + fallthrough; case STATE_02_SPIN_TO_INDEX: dev->state++; @@ -2311,7 +2362,7 @@ d86f_turbo_poll(int drive, int side) dev->last_sector.id.r = dev->req_sector.id.r; dev->last_sector.id.n = dev->req_sector.id.n; d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); - /*FALLTHROUGH*/ + fallthrough; case STATE_0A_FIND_ID: dev->turbo_pos = 0; @@ -2772,22 +2823,22 @@ d86f_construct_encoded_buffer(int drive, int side) /* *_fuzm are fuzzy bit masks, *_holm are hole masks, dst_neim are masks is mask for bits that are neither fuzzy nor holes in both, and src1_d and src2_d are filtered source data. */ - uint16_t src1_fuzm; - uint16_t src2_fuzm; - uint16_t dst_fuzm; - uint16_t src1_holm; - uint16_t src2_holm; - uint16_t dst_holm; - uint16_t dst_neim; - uint16_t src1_d; - uint16_t src2_d; - uint32_t len; - uint16_t *dst = dev->track_encoded_data[side]; - uint16_t *dst_s = dev->track_surface_data[side]; - uint16_t *src1 = dev->thin_track_encoded_data[0][side]; - uint16_t *src1_s = dev->thin_track_surface_data[0][side]; - uint16_t *src2 = dev->thin_track_encoded_data[1][side]; - uint16_t *src2_s = dev->thin_track_surface_data[1][side]; + uint16_t src1_fuzm; + uint16_t src2_fuzm; + uint16_t dst_fuzm; + uint16_t src1_holm; + uint16_t src2_holm; + uint16_t dst_holm; + uint16_t dst_neim; + uint16_t src1_d; + uint16_t src2_d; + uint32_t len; + uint16_t *dst = dev->track_encoded_data[side]; + uint16_t *dst_s = dev->track_surface_data[side]; + const uint16_t *src1 = dev->thin_track_encoded_data[0][side]; + const uint16_t *src1_s = dev->thin_track_surface_data[0][side]; + const uint16_t *src2 = dev->thin_track_encoded_data[1][side]; + const uint16_t *src2_s = dev->thin_track_surface_data[1][side]; len = d86f_get_array_size(drive, side, 1); for (uint32_t i = 0; i < len; i++) { @@ -2824,17 +2875,17 @@ d86f_construct_encoded_buffer(int drive, int side) void d86f_decompose_encoded_buffer(int drive, int side) { - d86f_t *dev = d86f[drive]; - uint16_t temp; - uint16_t temp2; - uint32_t len; - uint16_t *dst = dev->track_encoded_data[side]; - uint16_t *src1 = dev->thin_track_encoded_data[0][side]; - uint16_t *src1_s = dev->thin_track_surface_data[0][side]; - uint16_t *src2 = dev->thin_track_encoded_data[1][side]; - uint16_t *src2_s = dev->thin_track_surface_data[1][side]; - dst = d86f_handler[drive].encoded_data(drive, side); - len = d86f_get_array_size(drive, side, 1); + d86f_t *dev = d86f[drive]; + uint16_t temp; + uint16_t temp2; + uint32_t len; + const uint16_t *dst = dev->track_encoded_data[side]; + uint16_t *src1 = dev->thin_track_encoded_data[0][side]; + uint16_t *src1_s = dev->thin_track_surface_data[0][side]; + uint16_t *src2 = dev->thin_track_encoded_data[1][side]; + uint16_t *src2_s = dev->thin_track_surface_data[1][side]; + dst = d86f_handler[drive].encoded_data(drive, side); + len = d86f_get_array_size(drive, side, 1); for (uint32_t i = 0; i < len; i++) { if (d86f_has_surface_desc(drive)) { @@ -2877,12 +2928,12 @@ d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, ui if (dev->track_offset[logical_track]) { if (!thin_track) { - if (fseek(dev->f, dev->track_offset[logical_track], SEEK_SET) == -1) + if (fseek(dev->fp, dev->track_offset[logical_track], SEEK_SET) == -1) fatal("d86f_read_track(): Error seeking to offset dev->track_offset[logical_track]\n"); - if (fread(&(dev->side_flags[side]), 1, 2, dev->f) != 2) + if (fread(&(dev->side_flags[side]), 1, 2, dev->fp) != 2) fatal("d86f_read_track(): Error reading side flags\n"); if (d86f_has_extra_bit_cells(drive)) { - if (fread(&(dev->extra_bit_cells[side]), 1, 4, dev->f) != 4) + if (fread(&(dev->extra_bit_cells[side]), 1, 4, dev->fp) != 4) fatal("d86f_read_track(): Error reading number of extra bit cells\n"); /* If RPM shift is 0% and direction is 1, do not adjust extra bit cells, as that is the whole track length. */ @@ -2894,18 +2945,18 @@ d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, ui } } else dev->extra_bit_cells[side] = 0; - (void) !fread(&(dev->index_hole_pos[side]), 4, 1, dev->f); + (void) !fread(&(dev->index_hole_pos[side]), 4, 1, dev->fp); } else - fseek(dev->f, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); + fseek(dev->fp, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); array_size = d86f_get_array_size(drive, side, 0); - (void) !fread(da, 1, array_size, dev->f); + (void) !fread(da, 1, array_size, dev->fp); if (d86f_has_surface_desc(drive)) - (void) !fread(sa, 1, array_size, dev->f); + (void) !fread(sa, 1, array_size, dev->fp); } else { if (!thin_track) { switch ((dev->disk_flags >> 1) & 3) { - case 0: default: + case 0: dev->side_flags[side] = 0x0A; break; @@ -2979,24 +3030,24 @@ d86f_seek(int drive, int track) } void -d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) +d86f_write_track(int drive, FILE **fp, int side, uint16_t *da0, uint16_t *sa0) { uint32_t array_size = d86f_get_array_size(drive, side, 0); uint16_t side_flags = d86f_handler[drive].side_flags(drive); uint32_t extra_bit_cells = d86f_handler[drive].extra_bit_cells(drive, side); uint32_t index_hole_pos = d86f_handler[drive].index_hole_pos(drive, side); - fwrite(&side_flags, 1, 2, *f); + fwrite(&side_flags, 1, 2, *fp); if (d86f_has_extra_bit_cells(drive)) - fwrite(&extra_bit_cells, 1, 4, *f); + fwrite(&extra_bit_cells, 1, 4, *fp); - fwrite(&index_hole_pos, 1, 4, *f); + fwrite(&index_hole_pos, 1, 4, *fp); - fwrite(da0, 1, array_size, *f); + fwrite(da0, 1, array_size, *fp); if (d86f_has_surface_desc(drive)) - fwrite(sa0, 1, array_size, *f); + fwrite(sa0, 1, array_size, *fp); } int @@ -3019,7 +3070,7 @@ d86f_set_cur_track(int drive, int track) } void -d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) +d86f_write_tracks(int drive, FILE **fp, uint32_t *track_table) { d86f_t *dev = d86f[drive]; int sides; @@ -3049,13 +3100,13 @@ d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) logical_track = dev->cur_track + thin_track; if (track_table && !tbl[logical_track]) { - fseek(*f, 0, SEEK_END); - tbl[logical_track] = ftell(*f); + fseek(*fp, 0, SEEK_END); + tbl[logical_track] = ftell(*fp); } if (tbl[logical_track]) { - fseek(*f, tbl[logical_track], SEEK_SET); - d86f_write_track(drive, f, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); + fseek(*fp, tbl[logical_track], SEEK_SET); + d86f_write_track(drive, fp, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); } } } @@ -3068,14 +3119,14 @@ d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) logical_track = dev->cur_track; if (track_table && !tbl[logical_track]) { - fseek(*f, 0, SEEK_END); - tbl[logical_track] = ftell(*f); + fseek(*fp, 0, SEEK_END); + tbl[logical_track] = ftell(*fp); } if (tbl[logical_track]) { - if (fseek(*f, tbl[logical_track], SEEK_SET) == -1) + if (fseek(*fp, tbl[logical_track], SEEK_SET) == -1) fatal("d86f_write_tracks(): Error seeking to offset tbl[logical_track]\n"); - d86f_write_track(drive, f, side, d86f_handler[drive].encoded_data(drive, side), dev->track_surface_data[side]); + d86f_write_track(drive, fp, side, d86f_handler[drive].encoded_data(drive, side), dev->track_surface_data[side]); } } } @@ -3097,22 +3148,22 @@ d86f_writeback(int drive) #endif header_size = d86f_header_size(drive); - if (!dev->f) + if (!dev->fp) return; /* First write the track offsets table. */ - if (fseek(dev->f, 0, SEEK_SET) == -1) + if (fseek(dev->fp, 0, SEEK_SET) == -1) fatal("86F write_back(): Error seeking to the beginning of the file\n"); - if (fread(header, 1, header_size, dev->f) != header_size) + if (fread(header, 1, header_size, dev->fp) != header_size) fatal("86F write_back(): Error reading header size\n"); - if (fseek(dev->f, 8, SEEK_SET) == -1) + if (fseek(dev->fp, 8, SEEK_SET) == -1) fatal("86F write_back(): Error seeking\n"); size = d86f_get_track_table_size(drive); - if (fwrite(dev->track_offset, 1, size, dev->f) != size) + if (fwrite(dev->track_offset, 1, size, dev->fp) != size) fatal("86F write_back(): Error writing data\n"); - d86f_write_tracks(drive, &dev->f, NULL); + d86f_write_tracks(drive, &dev->fp, NULL); #ifdef D86F_COMPRESS if (dev->is_compressed) { @@ -3124,16 +3175,16 @@ d86f_writeback(int drive) /* Write the header to the original file. */ fwrite(header, 1, header_size, cf); - fseek(dev->f, 0, SEEK_END); - len = ftell(dev->f); + fseek(dev->fp, 0, SEEK_END); + len = ftell(dev->fp); len -= header_size; - fseek(dev->f, header_size, SEEK_SET); + fseek(dev->fp, header_size, SEEK_SET); /* Compress data from the temporary uncompressed file to the original, compressed file. */ dev->filebuf = (uint8_t *) malloc(len); dev->outbuf = (uint8_t *) malloc(len - 1); - fread(dev->filebuf, 1, len, dev->f); + fread(dev->filebuf, 1, len, dev->fp); ret = lzf_compress(dev->filebuf, len, dev->outbuf, len - 1); if (!ret) @@ -3156,7 +3207,7 @@ d86f_stop(int drive) } int -d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) +d86f_common_command(int drive, int sector, int track, int side, UNUSED(int rate), int sector_size) { d86f_t *dev = d86f[drive]; @@ -3240,7 +3291,7 @@ d86f_comparesector(int drive, int sector, int track, int side, int rate, int sec } void -d86f_readaddress(int drive, int side, int rate) +d86f_readaddress(int drive, UNUSED(int side), UNUSED(int rate)) { d86f_t *dev = d86f[drive]; @@ -3290,7 +3341,7 @@ d86f_add_track(int drive, int track, int side) } void -d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) +d86f_common_format(int drive, int side, UNUSED(int rate), uint8_t fill, int proxy) { d86f_t *dev = d86f[drive]; uint16_t temp; @@ -3393,7 +3444,7 @@ d86f_export(int drive, char *fn) uint32_t tt[512]; d86f_t *dev = d86f[drive]; d86f_t *temp86; - FILE *f; + FILE *fp; int tracks = 86; int inc = 1; uint32_t magic = 0x46423638; @@ -3402,19 +3453,19 @@ d86f_export(int drive, char *fn) memset(tt, 0, 512 * sizeof(uint32_t)); - f = plat_fopen(fn, "wb"); - if (!f) + fp = plat_fopen(fn, "wb"); + if (!fp) return 0; /* Allocate a temporary drive for conversion. */ temp86 = (d86f_t *) malloc(sizeof(d86f_t)); memcpy(temp86, dev, sizeof(d86f_t)); - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&disk_flags, 2, 1, f); + fwrite(&magic, 4, 1, fp); + fwrite(&version, 2, 1, fp); + fwrite(&disk_flags, 2, 1, fp); - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), fp); /* In the case of a thick track drive, always increment track by two, since two tracks are going to get output at once. */ @@ -3427,17 +3478,17 @@ d86f_export(int drive, char *fn) else fdd_do_seek(drive, i); dev->cur_track = i; - d86f_write_tracks(drive, &f, tt); + d86f_write_tracks(drive, &fp, tt); } - fclose(f); + fclose(fp); - f = plat_fopen(fn, "rb+"); + fp = plat_fopen(fn, "rb+"); - fseek(f, 8, SEEK_SET); - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); + fseek(fp, 8, SEEK_SET); + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), fp); - fclose(f); + fclose(fp); fdd_do_seek(drive, fdd_current_track(drive)); @@ -3464,10 +3515,10 @@ d86f_load(int drive, char *fn) writeprot[drive] = 0; - dev->f = plat_fopen(fn, "rb+"); - if (!dev->f) { - dev->f = plat_fopen(fn, "rb"); - if (!dev->f) { + dev->fp = plat_fopen(fn, "rb+"); + if (!dev->fp) { + dev->fp = plat_fopen(fn, "rb"); + if (!dev->fp) { memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; @@ -3480,16 +3531,16 @@ d86f_load(int drive, char *fn) } fwriteprot[drive] = writeprot[drive]; - fseek(dev->f, 0, SEEK_END); - len = ftell(dev->f); - fseek(dev->f, 0, SEEK_SET); + fseek(dev->fp, 0, SEEK_END); + len = ftell(dev->fp); + fseek(dev->fp, 0, SEEK_SET); - (void) !fread(&magic, 4, 1, dev->f); + (void) !fread(&magic, 4, 1, dev->fp); if (len < 16) { /* File is WAY too small, abort. */ - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; @@ -3498,13 +3549,13 @@ d86f_load(int drive, char *fn) if ((magic != 0x46423638) && (magic != 0x66623638)) { /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); - fclose(dev->f); + fclose(dev->fp); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; } - if (fread(&(dev->version), 1, 2, dev->f) != 2) + if (fread(&(dev->version), 1, 2, dev->fp) != 2) fatal("d86f_load(): Error reading format version\n"); if (dev->version != D86FVER) { @@ -3516,8 +3567,8 @@ d86f_load(int drive, char *fn) } else { d86f_log("86F: Unrecognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); } - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; @@ -3525,7 +3576,7 @@ d86f_load(int drive, char *fn) d86f_log("86F: Recognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); } - (void) !fread(&(dev->disk_flags), 2, 1, dev->f); + (void) !fread(&(dev->disk_flags), 2, 1, dev->fp); if (d86f_has_surface_desc(drive)) { for (uint8_t i = 0; i < 2; i++) @@ -3544,31 +3595,31 @@ d86f_load(int drive, char *fn) if (len < 51052) { #endif /* File too small, abort. */ - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; } #ifdef DO_CRC64 - fseek(dev->f, 8, SEEK_SET); - fread(&read_crc64, 1, 8, dev->f); + fseek(dev->fp, 8, SEEK_SET); + fread(&read_crc64, 1, 8, dev->fp); - fseek(dev->f, 0, SEEK_SET); + fseek(dev->fp, 0, SEEK_SET); crc64 = 0xffffffffffffffff; dev->filebuf = malloc(len); - fread(dev->filebuf, 1, len, dev->f); + fread(dev->filebuf, 1, len, dev->fp); *(uint64_t *) &(dev->filebuf[8]) = 0xffffffffffffffff; crc64 = (uint64_t) crc64speed(0, dev->filebuf, len); free(dev->filebuf); if (crc64 != read_crc64) { d86f_log("86F: CRC64 error\n"); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; @@ -3580,11 +3631,11 @@ d86f_load(int drive, char *fn) memcpy(temp_file_name, drive ? nvr_path("TEMP$$$1.$$$") : nvr_path("TEMP$$$0.$$$"), 256); memcpy(dev->original_file_name, fn, strlen(fn) + 1); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; - dev->f = plat_fopen(temp_file_name, "wb"); - if (!dev->f) { + dev->fp = plat_fopen(temp_file_name, "wb"); + if (!dev->fp) { d86f_log("86F: Unable to create temporary decompressed file\n"); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); @@ -3593,9 +3644,9 @@ d86f_load(int drive, char *fn) tf = plat_fopen(fn, "rb"); - for (i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { fread(&temp, 1, 2, tf); - fwrite(&temp, 1, 2, dev->f); + fwrite(&temp, 1, 2, dev->fp); } dev->filebuf = (uint8_t *) malloc(len); @@ -3603,14 +3654,14 @@ d86f_load(int drive, char *fn) fread(dev->filebuf, 1, len, tf); temp = lzf_decompress(dev->filebuf, len, dev->outbuf, 67108864); if (temp) { - fwrite(dev->outbuf, 1, temp, dev->f); + fwrite(dev->outbuf, 1, temp, dev->fp); } free(dev->outbuf); free(dev->filebuf); fclose(tf); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; if (!temp) { d86f_log("86F: Error decompressing file\n"); @@ -3620,15 +3671,15 @@ d86f_load(int drive, char *fn) return; } - dev->f = plat_fopen(temp_file_name, "rb+"); + dev->fp = plat_fopen(temp_file_name, "rb+"); } #endif if (dev->disk_flags & 0x100) { /* Zoned disk. */ d86f_log("86F: Disk is zoned (Apple or Sony)\n"); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; #ifdef D86F_COMPRESS if (dev->is_compressed) plat_remove(temp_file_name); @@ -3641,8 +3692,8 @@ d86f_load(int drive, char *fn) if (dev->disk_flags & 0x600) { /* Zone type is not 0 but the disk is fixed-RPM. */ d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; #ifdef D86F_COMPRESS if (dev->is_compressed) plat_remove(temp_file_name); @@ -3658,29 +3709,29 @@ d86f_load(int drive, char *fn) } if (writeprot[drive]) { - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; #ifdef D86F_COMPRESS if (dev->is_compressed) - dev->f = plat_fopen(temp_file_name, "rb"); + dev->fp = plat_fopen(temp_file_name, "rb"); else #endif - dev->f = plat_fopen(fn, "rb"); + dev->fp = plat_fopen(fn, "rb"); } /* OK, set the drive data, other code needs it. */ d86f[drive] = dev; - fseek(dev->f, 8, SEEK_SET); + fseek(dev->fp, 8, SEEK_SET); - (void) !fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f); + (void) !fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->fp); if (!(dev->track_offset[0])) { /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); d86f[drive] = NULL; @@ -3690,8 +3741,8 @@ d86f_load(int drive, char *fn) if ((d86f_get_sides(drive) == 2) && !(dev->track_offset[1])) { /* File is 2-sided but has no track 0 side 1, abort. */ d86f_log("86F: No Track 0 side 1\n"); - fclose(dev->f); - dev->f = NULL; + fclose(dev->fp); + dev->fp = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); d86f[drive] = NULL; @@ -3699,12 +3750,12 @@ d86f_load(int drive, char *fn) } /* Load track 0 flags as default. */ - if (fseek(dev->f, dev->track_offset[0], SEEK_SET) == -1) + if (fseek(dev->fp, dev->track_offset[0], SEEK_SET) == -1) fatal("d86f_load(): Track 0: Error seeking to the beginning of the file\n"); - if (fread(&(dev->side_flags[0]), 1, 2, dev->f) != 2) + if (fread(&(dev->side_flags[0]), 1, 2, dev->fp) != 2) fatal("d86f_load(): Track 0: Error reading side flags\n"); if (dev->disk_flags & 0x80) { - if (fread(&(dev->extra_bit_cells[0]), 1, 4, dev->f) != 4) + if (fread(&(dev->extra_bit_cells[0]), 1, 4, dev->fp) != 4) fatal("d86f_load(): Track 0: Error reading the amount of extra bit cells\n"); if ((dev->disk_flags & 0x1060) != 0x1000) { if (dev->extra_bit_cells[0] < -32768) @@ -3717,12 +3768,12 @@ d86f_load(int drive, char *fn) } if (d86f_get_sides(drive) == 2) { - if (fseek(dev->f, dev->track_offset[1], SEEK_SET) == -1) + if (fseek(dev->fp, dev->track_offset[1], SEEK_SET) == -1) fatal("d86f_load(): Track 1: Error seeking to the beginning of the file\n"); - if (fread(&(dev->side_flags[1]), 1, 2, dev->f) != 2) + if (fread(&(dev->side_flags[1]), 1, 2, dev->fp) != 2) fatal("d86f_load(): Track 1: Error reading side flags\n"); if (dev->disk_flags & 0x80) { - if (fread(&(dev->extra_bit_cells[1]), 1, 4, dev->f) != 4) + if (fread(&(dev->extra_bit_cells[1]), 1, 4, dev->fp) != 4) fatal("d86f_load(): Track 4: Error reading the amount of extra bit cells\n"); if ((dev->disk_flags & 0x1060) != 0x1000) { if (dev->extra_bit_cells[1] < -32768) @@ -3735,8 +3786,8 @@ d86f_load(int drive, char *fn) } } else { switch ((dev->disk_flags >> 1) >> 3) { - case 0: default: + case 0: dev->side_flags[1] = 0x0a; break; @@ -3753,10 +3804,10 @@ d86f_load(int drive, char *fn) dev->extra_bit_cells[1] = 0; } - fseek(dev->f, 0, SEEK_END); - dev->file_size = ftell(dev->f); + fseek(dev->fp, 0, SEEK_END); + dev->file_size = ftell(dev->fp); - fseek(dev->f, 0, SEEK_SET); + fseek(dev->fp, 0, SEEK_SET); d86f_register_86f(drive); @@ -3819,9 +3870,9 @@ d86f_close(int drive) } } - if (dev->f) { - fclose(dev->f); - dev->f = NULL; + if (dev->fp) { + fclose(dev->fp); + dev->fp = NULL; } #ifdef D86F_COMPRESS if (dev->is_compressed) diff --git a/src/floppy/fdd_common.c b/src/floppy/fdd_common.c index 78434a2adb..d0659d990c 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -359,7 +359,7 @@ fdd_get_gap3_size(int rate, int size, int sector) uint8_t fdd_sector_size_code(int size) { - int ret = 2; + uint8_t ret = 2; switch (size) { case 128: diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index a1a2a61ee2..f14bf2cd48 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -36,8 +36,8 @@ #include <86box/fdc.h> #include -typedef struct { - FILE *f; +typedef struct fdi_t { + FILE *fp; FDI *h; int lasttrack; @@ -176,10 +176,10 @@ fdi_density(void) static int32_t extra_bit_cells(int drive, int side) { - fdi_t *dev = fdi[drive]; - int density = 0; - int raw_size = 0; - int is_300_rpm = 0; + const fdi_t *dev = fdi[drive]; + int density = 0; + int raw_size = 0; + int is_300_rpm = 0; density = fdi_density(); @@ -249,8 +249,8 @@ read_revolution(int drive) static uint32_t index_hole_pos(int drive, int side) { - fdi_t *dev = fdi[drive]; - int density; + const fdi_t *dev = fdi[drive]; + int density; density = fdi_density(); @@ -260,8 +260,8 @@ index_hole_pos(int drive, int side) static uint32_t get_raw_size(int drive, int side) { - fdi_t *dev = fdi[drive]; - int density; + const fdi_t *dev = fdi[drive]; + int density; density = fdi_density(); @@ -291,7 +291,7 @@ fdi_seek(int drive, int track) d86f_set_cur_track(drive, track); - if (dev->f == NULL) + if (dev->fp == NULL) return; if (track < 0) @@ -327,16 +327,16 @@ fdi_load(int drive, char *fn) d86f_unregister(drive); - dev->f = plat_fopen(fn, "rb"); - if (fread(header, 1, 25, dev->f) != 25) + dev->fp = plat_fopen(fn, "rb"); + if (fread(header, 1, 25, dev->fp) != 25) fatal("fdi_load(): Error reading header\n"); - if (fseek(dev->f, 0, SEEK_SET) == -1) + if (fseek(dev->fp, 0, SEEK_SET) == -1) fatal("fdi_load(): Error seeking to the beginning of the file\n"); header[25] = 0; if (strcmp(header, "Formatted Disk Image file") != 0) { /* This is a Japanese FDI file. */ fdi_log("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); img_load(drive, fn); return; @@ -345,7 +345,7 @@ fdi_load(int drive, char *fn) /* Set up the drive unit. */ fdi[drive] = dev; - dev->h = fdi2raw_header(dev->f); + dev->h = fdi2raw_header(dev->fp); dev->lasttrack = fdi2raw_get_last_track(dev->h); dev->sides = fdi2raw_get_last_head(dev->h) + 1; @@ -386,8 +386,8 @@ fdi_close(int drive) if (dev->h) fdi2raw_header_free(dev->h); - if (dev->f) - fclose(dev->f); + if (dev->fp) + fclose(dev->fp); /* Release the memory. */ free(dev); diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index c03481db3b..a5cd8f056f 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -31,7 +31,7 @@ #include <86box/fdd_imd.h> #include <86box/fdc.h> -typedef struct { +typedef struct imd_track_t { uint8_t is_present; uint32_t file_offs; uint8_t params[5]; @@ -47,11 +47,12 @@ typedef struct { uint8_t max_sector_size; } imd_track_t; -typedef struct { - FILE *f; +typedef struct imd_t { + FILE *fp; char *buffer; uint32_t start_offs; - int track_count, sides; + int track_count; + int sides; int track; uint16_t disk_flags; int track_width; @@ -135,21 +136,20 @@ get_raw_tsize(int side_flags, int slower_rpm) static int track_is_xdf(int drive, int side, int track) { - imd_t *dev = imd[drive]; - int i; - int effective_sectors; - int xdf_sectors; - int high_sectors; - int low_sectors; - int max_high_id; - int expected_high_count; - int expected_low_count; - uint8_t *r_map; - uint8_t *n_map; + imd_t *dev = imd[drive]; + int effective_sectors; + int xdf_sectors; + int high_sectors; + int low_sectors; + int max_high_id; + int expected_high_count; + int expected_low_count; + const uint8_t *r_map; + const uint8_t *n_map; effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - for (i = 0; i < 256; i++) + for (uint16_t i = 0; i < 256; i++) dev->xdf_ordered_pos[i][side] = 0; if (dev->tracks[track][side].params[2] & 0xC0) @@ -174,7 +174,7 @@ track_is_xdf(int drive, int side, int track) expected_low_count = 0; } - for (i = 0; i < dev->tracks[track][side].params[3]; i++) { + for (uint8_t i = 0; i < dev->tracks[track][side].params[3]; i++) { if ((r_map[i] >= 0x81) && (r_map[i] <= max_high_id)) { high_sectors++; dev->xdf_ordered_pos[(int) r_map[i]][side] = i; @@ -195,7 +195,7 @@ track_is_xdf(int drive, int side, int track) n_map = (uint8_t *) (dev->buffer + dev->tracks[track][side].n_map_offs); - for (i = 0; i < dev->tracks[track][side].params[3]; i++) { + for (uint8_t i = 0; i < dev->tracks[track][side].params[3]; i++) { effective_sectors++; if (!(r_map[i]) && !(n_map[i])) effective_sectors--; @@ -223,10 +223,10 @@ track_is_xdf(int drive, int side, int track) static int track_is_interleave(int drive, int side, int track) { - imd_t *dev = imd[drive]; - int effective_sectors; - char *r_map; - int track_spt; + imd_t *dev = imd[drive]; + int effective_sectors; + const char *r_map; + int track_spt; effective_sectors = 0; @@ -262,9 +262,9 @@ track_is_interleave(int drive, int side, int track) static void sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, int len) { - imd_t *dev = imd[drive]; - int type = dev->buffer[dev->tracks[track][side].sector_data_offs[sector]]; - uint8_t fill_char; + const imd_t *dev = imd[drive]; + int type = dev->buffer[dev->tracks[track][side].sector_data_offs[sector]]; + uint8_t fill_char; if (type == 0) memset(buffer, 0x00, len); @@ -281,35 +281,35 @@ sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, in static void imd_seek(int drive, int track) { - uint32_t track_buf_pos[2] = { 0, 0 }; - uint8_t id[4] = { 0, 0, 0, 0 }; - uint8_t type; - imd_t *dev = imd[drive]; - int sector; - int current_pos; - int c = 0; - int h; - int n; - int ssize = 512; - int track_rate = 0; - int track_gap2 = 22; - int track_gap3 = 12; - int xdf_type = 0; - int interleave_type = 0; - int is_trackx = 0; - int xdf_spt = 0; - int xdf_sector = 0; - int ordered_pos = 0; - int real_sector = 0; - int actual_sector = 0; - char *c_map = NULL; - char *h_map = NULL; - char *r_map; - char *n_map = NULL; - uint8_t *data; - int flags = 0x00; - - if (dev->f == NULL) + uint32_t track_buf_pos[2] = { 0, 0 }; + uint8_t id[4] = { 0, 0, 0, 0 }; + uint8_t type; + imd_t *dev = imd[drive]; + int sector; + int current_pos; + int c = 0; + int h; + int n; + int ssize = 512; + int track_rate = 0; + int track_gap2 = 22; + int track_gap3 = 12; + int xdf_type = 0; + int interleave_type = 0; + int is_trackx = 0; + int xdf_spt = 0; + int xdf_sector = 0; + int ordered_pos = 0; + int real_sector = 0; + int actual_sector = 0; + const char *c_map = NULL; + const char *h_map = NULL; + const char *r_map; + const char *n_map = NULL; + uint8_t *data; + int flags = 0x00; + + if (dev->fp == NULL) return; if (!dev->track_width && fdd_doublestep_40(drive)) @@ -451,7 +451,7 @@ imd_seek(int drive, int track) static uint16_t disk_flags(int drive) { - imd_t *dev = imd[drive]; + const imd_t *dev = imd[drive]; return (dev->disk_flags); } @@ -459,9 +459,9 @@ disk_flags(int drive) static uint16_t side_flags(int drive) { - imd_t *dev = imd[drive]; - int side = 0; - uint16_t sflags = 0; + const imd_t *dev = imd[drive]; + int side = 0; + uint16_t sflags = 0; side = fdd_get_head(drive); sflags = dev->current_side_flags[side]; @@ -472,19 +472,19 @@ side_flags(int drive) static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { - imd_t *dev = imd[drive]; - int track = dev->track; - int sc; - int sh; - int sn; - char *c_map = NULL; - char *h_map = NULL; - char *r_map = NULL; - char *n_map = NULL; - uint8_t id[4] = { 0, 0, 0, 0 }; - sc = dev->tracks[track][side].params[1]; - sh = dev->tracks[track][side].params[2]; - sn = dev->tracks[track][side].params[4]; + imd_t *dev = imd[drive]; + int track = dev->track; + int sc; + int sh; + int sn; + const char *c_map = NULL; + const char *h_map = NULL; + const char *r_map = NULL; + const char *n_map = NULL; + uint8_t id[4] = { 0, 0, 0, 0 }; + sc = dev->tracks[track][side].params[1]; + sh = dev->tracks[track][side].params[2]; + sn = dev->tracks[track][side].params[4]; if (sh & 0x80) c_map = dev->buffer + dev->tracks[track][side].c_map_offs; @@ -512,39 +512,39 @@ set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) static void imd_writeback(int drive) { - imd_t *dev = imd[drive]; - int track = dev->track; - char *n_map = 0; - uint8_t h; - uint8_t n; - uint8_t spt; - uint32_t ssize; + imd_t *dev = imd[drive]; + int track = dev->track; + const char *n_map = 0; + uint8_t h; + uint8_t n; + uint8_t spt; + uint32_t ssize; if (writeprot[drive]) return; for (int side = 0; side < dev->sides; side++) { if (dev->tracks[track][side].is_present) { - fseek(dev->f, dev->tracks[track][side].file_offs, SEEK_SET); + fseek(dev->fp, dev->tracks[track][side].file_offs, SEEK_SET); h = dev->tracks[track][side].params[2]; spt = dev->tracks[track][side].params[3]; n = dev->tracks[track][side].params[4]; - fwrite(dev->tracks[track][side].params, 1, 5, dev->f); + fwrite(dev->tracks[track][side].params, 1, 5, dev->fp); if (h & 0x80) - fwrite(dev->buffer + dev->tracks[track][side].c_map_offs, 1, spt, dev->f); + fwrite(dev->buffer + dev->tracks[track][side].c_map_offs, 1, spt, dev->fp); if (h & 0x40) - fwrite(dev->buffer + dev->tracks[track][side].h_map_offs, 1, spt, dev->f); + fwrite(dev->buffer + dev->tracks[track][side].h_map_offs, 1, spt, dev->fp); if (n == 0xFF) { n_map = dev->buffer + dev->tracks[track][side].n_map_offs; - fwrite(n_map, 1, spt, dev->f); + fwrite(n_map, 1, spt, dev->fp); } for (uint8_t i = 0; i < spt; i++) { ssize = (n == 0xFF) ? n_map[i] : n; ssize = 128 << ssize; - fwrite(dev->buffer + dev->tracks[track][side].sector_data_offs[i], 1, ssize, dev->f); + fwrite(dev->buffer + dev->tracks[track][side].sector_data_offs[i], 1, ssize, dev->fp); } } } @@ -553,8 +553,8 @@ imd_writeback(int drive) static uint8_t poll_read_data(int drive, int side, uint16_t pos) { - imd_t *dev = imd[drive]; - int type = dev->current_data[side][0]; + const imd_t *dev = imd[drive]; + int type = dev->current_data[side][0]; if ((type == 0) || (type > 8)) return 0xf6; /* Should never happen. */ @@ -568,8 +568,8 @@ poll_read_data(int drive, int side, uint16_t pos) static void poll_write_data(int drive, int side, uint16_t pos, uint8_t data) { - imd_t *dev = imd[drive]; - int type = dev->current_data[side][0]; + const imd_t *dev = imd[drive]; + int type = dev->current_data[side][0]; if (writeprot[drive]) return; @@ -583,10 +583,10 @@ poll_write_data(int drive, int side, uint16_t pos, uint8_t data) static int format_conditions(int drive) { - imd_t *dev = imd[drive]; - int track = dev->track; - int side; - int temp; + const imd_t *dev = imd[drive]; + int track = dev->track; + int side; + int temp; side = fdd_get_head(drive); temp = (fdc_get_format_sectors(imd_fdc) == dev->tracks[track][side].params[3]); @@ -604,29 +604,28 @@ imd_init(void) void imd_load(int drive, char *fn) { - uint32_t magic = 0; - uint32_t fsize = 0; - char *buffer; - char *buffer2; - imd_t *dev; - int i = 0; - int track_spt = 0; - int sector_size = 0; - int track = 0; - int side = 0; - int extra = 0; - uint32_t last_offset = 0; - uint32_t data_size = 512; - uint32_t mfm = 0; - uint32_t pre_sector = 0; - uint32_t track_total = 0; - uint32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; - uint8_t converted_rate; - uint8_t type; - int size_diff; - int gap_sum; + uint32_t magic = 0; + uint32_t fsize = 0; + const char *buffer; + const char *buffer2; + imd_t *dev; + int track_spt = 0; + int sector_size = 0; + int track = 0; + int side = 0; + int extra = 0; + uint32_t last_offset = 0; + uint32_t data_size = 512; + uint32_t mfm = 0; + uint32_t pre_sector = 0; + uint32_t track_total = 0; + uint32_t raw_tsize = 0; + uint32_t minimum_gap3 = 0; + uint32_t minimum_gap4 = 0; + uint8_t converted_rate; + uint8_t type; + int size_diff; + int gap_sum; d86f_unregister(drive); @@ -636,10 +635,10 @@ imd_load(int drive, char *fn) dev = (imd_t *) malloc(sizeof(imd_t)); memset(dev, 0x00, sizeof(imd_t)); - dev->f = plat_fopen(fn, "rb+"); - if (dev->f == NULL) { - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { + dev->fp = plat_fopen(fn, "rb+"); + if (dev->fp == NULL) { + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); return; @@ -651,40 +650,40 @@ imd_load(int drive, char *fn) writeprot[drive] = 1; fwriteprot[drive] = writeprot[drive]; - if (fseek(dev->f, 0, SEEK_SET) == -1) + if (fseek(dev->fp, 0, SEEK_SET) == -1) fatal("imd_load(): Error seeking to the beginning of the file\n"); - if (fread(&magic, 1, 4, dev->f) != 4) + if (fread(&magic, 1, 4, dev->fp) != 4) fatal("imd_load(): Error reading the magic number\n"); if (magic != 0x20444D49) { imd_log("IMD: Not a valid ImageDisk image\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; } else imd_log("IMD: Valid ImageDisk image\n"); - if (fseek(dev->f, 0, SEEK_END) == -1) + if (fseek(dev->fp, 0, SEEK_END) == -1) fatal("imd_load(): Error seeking to the end of the file\n"); - fsize = ftell(dev->f); + fsize = ftell(dev->fp); if (fsize <= 0) { imd_log("IMD: Too small ImageDisk image\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; } - if (fseek(dev->f, 0, SEEK_SET) == -1) + if (fseek(dev->fp, 0, SEEK_SET) == -1) fatal("imd_load(): Error seeking to the beginning of the file again\n"); dev->buffer = malloc(fsize); - if (fread(dev->buffer, 1, fsize, dev->f) != fsize) + if (fread(dev->buffer, 1, fsize, dev->fp) != fsize) fatal("imd_load(): Error reading data\n"); buffer = dev->buffer; buffer2 = memchr(buffer, 0x1A, fsize); if (buffer2 == NULL) { imd_log("IMD: No ASCII EOF character\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -695,7 +694,7 @@ imd_load(int drive, char *fn) buffer2++; if ((buffer2 - buffer) == fsize) { imd_log("IMD: File ends after ASCII EOF character\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -774,7 +773,7 @@ imd_load(int drive, char *fn) dev->tracks[track][side].data_offs = last_offset; - for (i = 0; i < track_spt; i++) { + for (int i = 0; i < track_spt; i++) { data_size = buffer2[i]; data_size = 128 << data_size; dev->tracks[track][side].sector_data_offs[i] = last_offset; @@ -783,7 +782,7 @@ imd_load(int drive, char *fn) /* Invalid sector data type, possibly a malformed HxC IMG image (it outputs data errored sectors with a variable amount of bytes, against the specification). */ imd_log("IMD: Invalid sector data type %02X\n", dev->buffer[dev->tracks[track][side].sector_data_offs[i]]); - fclose(dev->f); + fclose(dev->fp); free(dev); imd[drive] = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); @@ -806,7 +805,7 @@ imd_load(int drive, char *fn) } else { dev->tracks[track][side].data_offs = last_offset; - for (i = 0; i < track_spt; i++) { + for (int i = 0; i < track_spt; i++) { data_size = sector_size; data_size = 128 << data_size; dev->tracks[track][side].sector_data_offs[i] = last_offset; @@ -815,7 +814,7 @@ imd_load(int drive, char *fn) /* Invalid sector data type, possibly a malformed HxC IMG image (it outputs data errored sectors with a variable amount of bytes, against the specification). */ imd_log("IMD: Invalid sector data type %02X\n", dev->buffer[dev->tracks[track][side].sector_data_offs[i]]); - fclose(dev->f); + fclose(dev->fp); free(dev); imd[drive] = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); @@ -864,7 +863,7 @@ imd_load(int drive, char *fn) if (size_diff < gap_sum) { /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ imd_log("IMD: Unable to fit the %i sectors in a track\n", track_spt); - fclose(dev->f); + fclose(dev->fp); free(dev); imd[drive] = NULL; memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); @@ -895,7 +894,9 @@ imd_load(int drive, char *fn) if (dev->sides == 2) dev->disk_flags |= 8; - /* imd_log("%i tracks, %i sides\n", dev->track_count, dev->sides); */ +#if 0 + imd_log("%i tracks, %i sides\n", dev->track_count, dev->sides); +#endif /* Attach this format to the D86F engine. */ d86f_handler[drive].disk_flags = disk_flags; @@ -928,10 +929,10 @@ imd_close(int drive) d86f_unregister(drive); - if (dev->f != NULL) { + if (dev->fp != NULL) { free(dev->buffer); - fclose(dev->f); + fclose(dev->fp); } /* Release the memory. */ diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index d9ffaf92d9..404cbf9fae 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -40,8 +40,8 @@ #include <86box/fdd_img.h> #include <86box/fdc.h> -typedef struct { - FILE *f; +typedef struct img_t { + FILE *fp; uint8_t track_data[2][688128]; int sectors, tracks, sides; uint8_t sector_size; @@ -418,17 +418,17 @@ write_back(int drive) int ssize = 128 << ((int) dev->sector_size); int size; - if (dev->f == NULL) + if (dev->fp == NULL) return; if (dev->disk_at_once) return; - if (fseek(dev->f, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) + if (fseek(dev->fp, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) pclog("IMG write_back(): Error seeking to the beginning of the file\n"); for (int side = 0; side < dev->sides; side++) { size = dev->sectors * ssize; - if (fwrite(dev->track_data[side], 1, size, dev->f) != size) + if (fwrite(dev->track_data[side], 1, size, dev->fp) != size) fatal("IMG write_back(): Error writing data\n"); } } @@ -436,7 +436,7 @@ write_back(int drive) static uint16_t disk_flags(int drive) { - img_t *dev = img[drive]; + const img_t *dev = img[drive]; return (dev->disk_flags); } @@ -444,13 +444,13 @@ disk_flags(int drive) static uint16_t side_flags(int drive) { - img_t *dev = img[drive]; + const img_t *dev = img[drive]; return (dev->track_flags); } static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +set_sector(int drive, UNUSED(int side), UNUSED(uint8_t c), uint8_t h, uint8_t r, UNUSED(uint8_t n)) { img_t *dev = img[drive]; @@ -459,15 +459,15 @@ set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) } static uint8_t -poll_read_data(int drive, int side, uint16_t pos) +poll_read_data(int drive, UNUSED(int side), uint16_t pos) { - img_t *dev = img[drive]; + const img_t *dev = img[drive]; return (dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); } static void -poll_write_data(int drive, int side, uint16_t pos, uint8_t data) +poll_write_data(int drive, UNUSED(int side), uint16_t pos, uint8_t data) { img_t *dev = img[drive]; @@ -477,8 +477,8 @@ poll_write_data(int drive, int side, uint16_t pos, uint8_t data) static int format_conditions(int drive) { - img_t *dev = img[drive]; - int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); + const img_t *dev = img[drive]; + int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); temp = temp && (fdc_get_format_n(img_fdc) == dev->sector_size); temp = temp && (dev->xdf_type == 0); @@ -507,7 +507,7 @@ img_seek(int drive, int track) int ssize = 128 << ((int) dev->sector_size); uint32_t cur_pos = 0; - if (dev->f == NULL) + if (dev->fp == NULL) return; if (!dev->track_width && fdd_doublestep_40(drive)) @@ -519,7 +519,7 @@ img_seek(int drive, int track) is_t0 = (track == 0) ? 1 : 0; if (!dev->disk_at_once) { - if (fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) + if (fseek(dev->fp, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) fatal("img_seek(): Error seeking\n"); } @@ -528,7 +528,7 @@ img_seek(int drive, int track) cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); memcpy(dev->track_data[side], dev->disk_data + cur_pos, (size_t) dev->sectors * ssize); } else { - read_bytes = fread(dev->track_data[side], 1, (size_t) dev->sectors * ssize, dev->f); + read_bytes = fread(dev->track_data[side], 1, (size_t) dev->sectors * ssize, dev->fp); if (read_bytes < (dev->sectors * ssize)) memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); } @@ -668,8 +668,8 @@ img_load(int drive, char *fn) uint16_t track_bytes = 0; uint8_t *literal; img_t *dev; - int temp_rate; - int guess = 0; + int temp_rate = 0; + int guess = 0; int size; ext = path_get_extension(fn); @@ -682,10 +682,10 @@ img_load(int drive, char *fn) dev = (img_t *) malloc(sizeof(img_t)); memset(dev, 0x00, sizeof(img_t)); - dev->f = plat_fopen(fn, "rb+"); - if (dev->f == NULL) { - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { + dev->fp = plat_fopen(fn, "rb+"); + if (dev->fp == NULL) { + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -710,23 +710,23 @@ img_load(int drive, char *fn) if (!strcasecmp(ext, "FDI")) { /* This is a Japanese FDI image, so let's read the header */ img_log("img_load(): File is a Japanese FDI image...\n"); - fseek(dev->f, 0x10, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, 0x0C, SEEK_SET); - (void) !fread(&size, 1, 4, dev->f); + fseek(dev->fp, 0x10, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->fp); + fseek(dev->fp, 0x0C, SEEK_SET); + (void) !fread(&size, 1, 4, dev->fp); bpb_total = size / bpb_bps; - fseek(dev->f, 0x08, SEEK_SET); - (void) !fread(&(dev->base), 1, 4, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); + fseek(dev->fp, 0x08, SEEK_SET); + (void) !fread(&(dev->base), 1, 4, dev->fp); + fseek(dev->fp, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->fp); if (bpb_mid < 0xF0) bpb_mid = 0xF0; - fseek(dev->f, 0x14, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x18, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, dev->base, SEEK_SET); - first_byte = fgetc(dev->f); + fseek(dev->fp, 0x14, SEEK_SET); + bpb_sectors = fgetc(dev->fp); + fseek(dev->fp, 0x18, SEEK_SET); + bpb_sides = fgetc(dev->fp); + fseek(dev->fp, dev->base, SEEK_SET); + first_byte = fgetc(dev->fp); fdi = 1; cqm = 0; @@ -734,53 +734,53 @@ img_load(int drive, char *fn) fdf = 0; } else { /* Read the first four bytes. */ - fseek(dev->f, 0x00, SEEK_SET); - first_byte = fgetc(dev->f); - fseek(dev->f, 0x01, SEEK_SET); - second_byte = fgetc(dev->f); - fseek(dev->f, 0x02, SEEK_SET); - third_byte = fgetc(dev->f); - fseek(dev->f, 0x03, SEEK_SET); - fourth_byte = fgetc(dev->f); + fseek(dev->fp, 0x00, SEEK_SET); + first_byte = fgetc(dev->fp); + fseek(dev->fp, 0x01, SEEK_SET); + second_byte = fgetc(dev->fp); + fseek(dev->fp, 0x02, SEEK_SET); + third_byte = fgetc(dev->fp); + fseek(dev->fp, 0x03, SEEK_SET); + fourth_byte = fgetc(dev->fp); if ((first_byte == 0x1A) && (second_byte == 'F') && (third_byte == 'D') && (fourth_byte == 'F')) { /* This is a FDF image. */ img_log("img_load(): File is a FDF image...\n"); fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + fclose(dev->fp); + dev->fp = plat_fopen(fn, "rb"); fdf = 1; cqm = 0; dev->disk_at_once = 1; - fseek(dev->f, 0x50, SEEK_SET); - (void) !fread(&dev->tracks, 1, 4, dev->f); + fseek(dev->fp, 0x50, SEEK_SET); + (void) !fread(&dev->tracks, 1, 4, dev->fp); /* Decode the entire file - pass 1, no write to buffer, determine length. */ - fseek(dev->f, 0x80, SEEK_SET); + fseek(dev->fp, 0x80, SEEK_SET); size = 0; track_bytes = 0; bpos = dev->disk_data; - while (!feof(dev->f)) { + while (!feof(dev->fp)) { if (!track_bytes) { /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); + first_byte = fgetc(dev->fp); + (void) !fread(&track_bytes, 1, 2, dev->fp); img_log("Block header: %02X %04X ", first_byte, track_bytes); /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); + (void) !fread(&track_bytes, 1, 2, dev->fp); img_log("%04X\n", track_bytes); } - if (feof(dev->f)) + if (feof(dev->fp)) break; if (first_byte == 0xFF) break; if (first_byte) { - run = fgetc(dev->f); + run = fgetc(dev->fp); /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ track_bytes--; @@ -788,12 +788,12 @@ img_load(int drive, char *fn) if (run & 0x80) { /* Repeat. */ track_bytes--; - rep_byte = fgetc(dev->f); + rep_byte = fgetc(dev->fp); } else { /* Literal. */ track_bytes -= (run & 0x7f); literal = (uint8_t *) malloc(run & 0x7f); - (void) !fread(literal, 1, (run & 0x7f), dev->f); + (void) !fread(literal, 1, (run & 0x7f), dev->fp); free(literal); } size += (run & 0x7f); @@ -803,12 +803,12 @@ img_load(int drive, char *fn) /* Literal block. */ size += (track_bytes - fdf_suppress_final_byte); literal = (uint8_t *) malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); + (void) !fread(literal, 1, track_bytes, dev->fp); free(literal); track_bytes = 0; } - if (feof(dev->f)) + if (feof(dev->fp)) break; } @@ -816,28 +816,28 @@ img_load(int drive, char *fn) dev->disk_data = (uint8_t *) malloc(size); /* Decode the entire file - pass 2, write to buffer. */ - fseek(dev->f, 0x80, SEEK_SET); + fseek(dev->fp, 0x80, SEEK_SET); track_bytes = 0; bpos = dev->disk_data; - while (!feof(dev->f)) { + while (!feof(dev->fp)) { if (!track_bytes) { /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); + first_byte = fgetc(dev->fp); + (void) !fread(&track_bytes, 1, 2, dev->fp); img_log("Block header: %02X %04X ", first_byte, track_bytes); /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); + (void) !fread(&track_bytes, 1, 2, dev->fp); img_log("%04X\n", track_bytes); } - if (feof(dev->f)) + if (feof(dev->fp)) break; if (first_byte == 0xFF) break; if (first_byte) { - run = fgetc(dev->f); + run = fgetc(dev->fp); real_run = (run & 0x7f); /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ @@ -848,14 +848,14 @@ img_load(int drive, char *fn) track_bytes--; if (!track_bytes) real_run -= fdf_suppress_final_byte; - rep_byte = fgetc(dev->f); + rep_byte = fgetc(dev->fp); if (real_run) memset(bpos, rep_byte, real_run); } else { /* Literal. */ track_bytes -= real_run; literal = (uint8_t *) malloc(real_run); - (void) !fread(literal, 1, real_run, dev->f); + (void) !fread(literal, 1, real_run, dev->fp); if (!track_bytes) real_run -= fdf_suppress_final_byte; if (run & 0x7f) @@ -866,14 +866,14 @@ img_load(int drive, char *fn) } else { /* Literal block. */ literal = (uint8_t *) malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); + (void) !fread(literal, 1, track_bytes, dev->fp); memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); free(literal); bpos += (track_bytes - fdf_suppress_final_byte); track_bytes = 0; } - if (feof(dev->f)) + if (feof(dev->fp)) break; } @@ -892,48 +892,48 @@ img_load(int drive, char *fn) if (((first_byte == 'C') && (second_byte == 'Q')) || ((first_byte == 'c') && (second_byte == 'q'))) { img_log("img_load(): File is a CopyQM image...\n"); fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + fclose(dev->fp); + dev->fp = plat_fopen(fn, "rb"); - fseek(dev->f, 0x03, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->fp, 0x03, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->fp); #if 0 - fseek(dev->f, 0x0B, SEEK_SET); - (void) !fread(&bpb_total, 1, 2, dev->f); + fseek(dev->fp, 0x0B, SEEK_SET); + (void) !fread(&bpb_total, 1, 2, dev->fp); #endif - fseek(dev->f, 0x10, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x12, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, 0x5B, SEEK_SET); - dev->tracks = fgetc(dev->f); + fseek(dev->fp, 0x10, SEEK_SET); + bpb_sectors = fgetc(dev->fp); + fseek(dev->fp, 0x12, SEEK_SET); + bpb_sides = fgetc(dev->fp); + fseek(dev->fp, 0x5B, SEEK_SET); + dev->tracks = fgetc(dev->fp); bpb_total = ((uint16_t) bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; - fseek(dev->f, 0x74, SEEK_SET); - dev->interleave = fgetc(dev->f); - fseek(dev->f, 0x76, SEEK_SET); - dev->skew = fgetc(dev->f); + fseek(dev->fp, 0x74, SEEK_SET); + dev->interleave = fgetc(dev->fp); + fseek(dev->fp, 0x76, SEEK_SET); + dev->skew = fgetc(dev->fp); dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - fseek(dev->f, 0x6F, SEEK_SET); - (void) !fread(&comment_len, 1, 2, dev->f); + fseek(dev->fp, 0x6F, SEEK_SET); + (void) !fread(&comment_len, 1, 2, dev->fp); - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; + fseek(dev->fp, -1, SEEK_END); + size = ftell(dev->fp) + 1; - fseek(dev->f, 133 + comment_len, SEEK_SET); + fseek(dev->fp, 133 + comment_len, SEEK_SET); cur_pos = 0; - while (!feof(dev->f)) { - (void) !fread(&block_len, 1, 2, dev->f); + while (!feof(dev->fp)) { + (void) !fread(&block_len, 1, 2, dev->fp); - if (!feof(dev->f)) { + if (!feof(dev->fp)) { if (block_len < 0) { - rep_byte = fgetc(dev->f); + rep_byte = fgetc(dev->fp); block_len = -block_len; if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; @@ -946,10 +946,10 @@ img_load(int drive, char *fn) } else if (block_len > 0) { if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->fp); break; } else { - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->fp); cur_pos += block_len; } } @@ -969,22 +969,22 @@ img_load(int drive, char *fn) fwriteprot[drive] = writeprot[drive] = 1; } else img_log("img_load(): File is a raw image...\n"); - fseek(dev->f, dev->base + 0x0B, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x13, SEEK_SET); - (void) !fread(&bpb_total, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - fseek(dev->f, dev->base + 0x18, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, dev->base + 0x1A, SEEK_SET); - bpb_sides = fgetc(dev->f); + fseek(dev->fp, dev->base + 0x0B, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->fp); + fseek(dev->fp, dev->base + 0x13, SEEK_SET); + (void) !fread(&bpb_total, 1, 2, dev->fp); + fseek(dev->fp, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->fp); + fseek(dev->fp, dev->base + 0x18, SEEK_SET); + bpb_sectors = fgetc(dev->fp); + fseek(dev->fp, dev->base + 0x1A, SEEK_SET); + bpb_sides = fgetc(dev->fp); cqm = 0; } - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; + fseek(dev->fp, -1, SEEK_END); + size = ftell(dev->fp) + 1; if (ddi) size -= 0x2400; @@ -1031,9 +1031,6 @@ img_load(int drive, char *fn) } else if (size <= (320 * 1024)) { dev->sectors = 8; dev->tracks = 40; - } else if (size <= (320 * 1024)) { - dev->sectors = 8; - dev->tracks = 40; } else if (size <= (360 * 1024)) { /*DD 360K*/ dev->sectors = 9; dev->tracks = 40; @@ -1128,7 +1125,7 @@ img_load(int drive, char *fn) dev->tracks = 86; } else { img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -1141,9 +1138,9 @@ img_load(int drive, char *fn) /* The BPB readings appear to be valid, so let's set the values. */ if (fdi) { /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ - if (fseek(dev->f, 0x1C, SEEK_SET) == -1) + if (fseek(dev->fp, 0x1C, SEEK_SET) == -1) fatal("Japanese FDI: Failed when seeking to 0x1C\n"); - (void) !fread(&(dev->tracks), 1, 4, dev->f); + (void) !fread(&(dev->tracks), 1, 4, dev->fp); } else { if (!cqm && !fdf) { /* Number of tracks = number of total sectors divided by sides times sectors per track. */ @@ -1185,7 +1182,7 @@ img_load(int drive, char *fn) if (temp_rate == 0xFF) { img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -1202,7 +1199,7 @@ img_load(int drive, char *fn) } if (!dev->gap3_size) { img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); - fclose(dev->f); + fclose(dev->fp); free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -1262,9 +1259,9 @@ img_close(int drive) d86f_unregister(drive); - if (dev->f != NULL) { - fclose(dev->f); - dev->f = NULL; + if (dev->fp != NULL) { + fclose(dev->fp); + dev->fp = NULL; } if (dev->disk_data != NULL) diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c index 4b8fafb236..36a041a68f 100644 --- a/src/floppy/fdd_json.c +++ b/src/floppy/fdd_json.c @@ -62,26 +62,26 @@ #define NSIDES 2 #define NSECTORS 256 -typedef struct { - uint8_t track, /* ID: track number */ - side, /* side number */ - sector; /* sector number 1.. */ - uint16_t size; /* encoded size of sector */ - uint8_t *data; /* allocated data for it */ +typedef struct sector_t { + uint8_t track; /* ID: track number */ + uint8_t side; /* side number */ + uint8_t sector; /* sector number 1.. */ + uint16_t size; /* encoded size of sector */ + uint8_t *data; /* allocated data for it */ } sector_t; -typedef struct { - FILE *f; +typedef struct json_t { + FILE *fp; /* Geometry. */ - uint8_t tracks, /* number of tracks */ - sides, /* number of sides */ - sectors, /* number of sectors per track */ - spt[NTRACKS][NSIDES]; /* number of sectors per track */ + uint8_t tracks; /* number of tracks */ + uint8_t sides; /* number of sides */ + uint8_t sectors; /* number of sectors per track */ + uint8_t spt[NTRACKS][NSIDES]; /* number of sectors per track */ - uint8_t track, /* current track */ - side, /* current side */ - sector[NSIDES]; /* current sector */ + uint8_t track; /* current track */ + uint8_t side; /* current side */ + uint8_t sector[NSIDES]; /* current sector */ uint8_t dmf; /* disk is DMF format */ uint8_t interleave; @@ -92,8 +92,8 @@ typedef struct { uint8_t gap3_len; int track_width; - uint16_t disk_flags, /* flags for the entire disk */ - track_flags; /* flags for the current track */ + uint16_t disk_flags; /* flags for the entire disk */ + uint16_t track_flags; /* flags for the current track */ uint8_t interleave_ordered[NTRACKS][NSIDES]; @@ -215,7 +215,7 @@ load_image(json_t *dev) int level; char *ptr; - if (dev->f == NULL) { + if (dev->fp == NULL) { json_log("JSON: no file loaded!\n"); return 0; } @@ -232,8 +232,8 @@ load_image(json_t *dev) level = state = 0; while (state >= 0) { /* Get a character from the input. */ - c = fgetc(dev->f); - if ((c == EOF) || ferror(dev->f)) { + c = fgetc(dev->fp); + if ((c == EOF) || ferror(dev->fp)) { state = -1; break; } @@ -372,6 +372,9 @@ load_image(json_t *dev) } dev->track++; break; + + default: + break; } } @@ -396,7 +399,7 @@ json_seek(int drive, int track) int rsec; int asec; - if (dev->f == NULL) { + if (dev->fp == NULL) { json_log("JSON: seek: no file loaded!\n"); return; } @@ -464,7 +467,7 @@ json_seek(int drive, int track) static uint16_t disk_flags(int drive) { - json_t *dev = images[drive]; + const json_t *dev = images[drive]; return (dev->disk_flags); } @@ -472,7 +475,7 @@ disk_flags(int drive) static uint16_t track_flags(int drive) { - json_t *dev = images[drive]; + const json_t *dev = images[drive]; return (dev->track_flags); } @@ -502,8 +505,8 @@ set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) static uint8_t poll_read_data(int drive, int side, uint16_t pos) { - json_t *dev = images[drive]; - uint8_t sec = dev->sector[side]; + const json_t *dev = images[drive]; + uint8_t sec = dev->sector[side]; return (dev->sects[dev->track][side][sec].data[pos]); } @@ -517,10 +520,10 @@ json_init(void) void json_load(int drive, char *fn) { - double bit_rate; - int temp_rate; - sector_t *sec; - json_t *dev; + double bit_rate; + int temp_rate; + const sector_t *sec; + json_t *dev; /* Just in case- remove ourselves from 86F. */ d86f_unregister(drive); @@ -530,8 +533,8 @@ json_load(int drive, char *fn) memset(dev, 0x00, sizeof(json_t)); /* Open the image file. */ - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { free(dev); memset(fn, 0x00, sizeof(char)); return; @@ -546,7 +549,7 @@ json_load(int drive, char *fn) /* Load all sectors from the image file. */ if (!load_image(dev)) { json_log("JSON: failed to initialize\n"); - (void) fclose(dev->f); + (void) fclose(dev->fp); free(dev); images[drive] = NULL; memset(fn, 0x00, sizeof(char)); @@ -608,8 +611,8 @@ json_load(int drive, char *fn) if (temp_rate == 0xff) { json_log("JSON: invalid image (temp_rate=0xff)\n"); - (void) fclose(dev->f); - dev->f = NULL; + (void) fclose(dev->fp); + dev->fp = NULL; free(dev); images[drive] = NULL; memset(fn, 0x00, sizeof(char)); @@ -630,8 +633,8 @@ json_load(int drive, char *fn) if (!dev->gap3_len) { json_log("JSON: image of unknown format was inserted into drive %c:!\n", 'C' + drive); - (void) fclose(dev->f); - dev->f = NULL; + (void) fclose(dev->fp); + dev->fp = NULL; free(dev); images[drive] = NULL; memset(fn, 0x00, sizeof(char)); @@ -692,8 +695,8 @@ json_close(int drive) } } - if (dev->f != NULL) - (void) fclose(dev->f); + if (dev->fp != NULL) + (void) fclose(dev->fp); /* Release the memory. */ free(dev); diff --git a/src/floppy/fdd_mfm.c b/src/floppy/fdd_mfm.c index 55c5491503..b4c859d5d8 100644 --- a/src/floppy/fdd_mfm.c +++ b/src/floppy/fdd_mfm.c @@ -32,7 +32,7 @@ #include <86box/fdc.h> #pragma pack(push, 1) -typedef struct { +typedef struct mfm_header_t { uint8_t hdr_name[7]; uint16_t tracks_no; @@ -45,14 +45,14 @@ typedef struct { uint32_t track_list_offset; } mfm_header_t; -typedef struct { +typedef struct mfm_track_t { uint16_t track_no; uint8_t side_no; uint32_t track_size; uint32_t track_offset; } mfm_track_t; -typedef struct { +typedef struct mfm_adv_track_t { uint16_t track_no; uint8_t side_no; uint16_t rpm; @@ -62,18 +62,21 @@ typedef struct { } mfm_adv_track_t; #pragma pack(pop) -typedef struct { - FILE *f; +typedef struct mfm_t { + FILE *fp; mfm_header_t hdr; mfm_track_t *tracks; mfm_adv_track_t *adv_tracks; - uint16_t disk_flags, pad; + uint16_t disk_flags; + uint16_t pad; uint16_t side_flags[2]; - int br_rounded, rpm_rounded, - total_tracks, cur_track; + int br_rounded; + int rpm_rounded; + int total_tracks; + int cur_track; uint8_t track_data[2][256 * 1024]; } mfm_t; @@ -102,8 +105,8 @@ mfm_log(const char *fmt, ...) static int get_track_index(int drive, int side, int track) { - mfm_t *dev = mfm[drive]; - int ret = -1; + const mfm_t *dev = mfm[drive]; + int ret = -1; for (int i = 0; i < dev->total_tracks; i++) { if ((dev->tracks[i].track_no == track) && (dev->tracks[i].side_no == side)) { @@ -118,8 +121,8 @@ get_track_index(int drive, int side, int track) static int get_adv_track_index(int drive, int side, int track) { - mfm_t *dev = mfm[drive]; - int ret = -1; + const mfm_t *dev = mfm[drive]; + int ret = -1; for (int i = 0; i < dev->total_tracks; i++) { if ((dev->adv_tracks[i].track_no == track) && (dev->adv_tracks[i].side_no == side)) { @@ -134,9 +137,9 @@ get_adv_track_index(int drive, int side, int track) static void get_adv_track_bitrate(int drive, int side, int track, int *br, int *rpm) { - mfm_t *dev = mfm[drive]; - int track_index; - double dbr; + const mfm_t *dev = mfm[drive]; + int track_index; + double dbr; track_index = get_adv_track_index(drive, side, track); @@ -170,16 +173,16 @@ set_disk_flags(int drive) } switch (br) { - case 500: - temp_disk_flags |= 2; - break; - - case 300: - case 250: default: + case 250: + case 300: temp_disk_flags |= 0; break; + case 500: + temp_disk_flags |= 2; + break; + case 1000: temp_disk_flags |= 4; break; @@ -194,7 +197,7 @@ set_disk_flags(int drive) static uint16_t disk_flags(int drive) { - mfm_t *dev = mfm[drive]; + const mfm_t *dev = mfm[drive]; return dev->disk_flags; } @@ -254,8 +257,8 @@ set_side_flags(int drive, int side) static uint16_t side_flags(int drive) { - mfm_t *dev = mfm[drive]; - int side; + const mfm_t *dev = mfm[drive]; + int side; side = fdd_get_head(drive); @@ -265,11 +268,11 @@ side_flags(int drive) static uint32_t get_raw_size(int drive, int side) { - mfm_t *dev = mfm[drive]; - int track_index; - int is_300_rpm; - int br = 250; - int rpm = 300; + const mfm_t *dev = mfm[drive]; + int track_index; + int is_300_rpm; + int br = 250; + int rpm = 300; if (dev->hdr.if_type & 0x80) { track_index = get_adv_track_index(drive, side, dev->cur_track); @@ -285,8 +288,8 @@ get_raw_size(int drive, int side) if (track_index == -1) { mfm_log("MFM: Unable to find track (%i, %i)\n", dev->cur_track, side); switch (br) { - case 250: default: + case 250: return is_300_rpm ? 100000 : 83333; case 300: return is_300_rpm ? 120000 : 100000; @@ -342,12 +345,12 @@ mfm_read_side(int drive, int side) memset(dev->track_data[side], 0x00, track_bytes); else { if (dev->hdr.if_type & 0x80) - ret = fseek(dev->f, dev->adv_tracks[track_index].track_offset, SEEK_SET); + ret = fseek(dev->fp, dev->adv_tracks[track_index].track_offset, SEEK_SET); else - ret = fseek(dev->f, dev->tracks[track_index].track_offset, SEEK_SET); + ret = fseek(dev->fp, dev->tracks[track_index].track_offset, SEEK_SET); if (ret == -1) fatal("mfm_read_side(): Error seeking to the beginning of the file\n"); - if (fread(dev->track_data[side], 1, track_bytes, dev->f) != track_bytes) + if (fread(dev->track_data[side], 1, track_bytes, dev->fp) != track_bytes) fatal("mfm_read_side(): Error reading track bytes\n"); } @@ -370,7 +373,7 @@ mfm_seek(int drive, int track) dev->cur_track = track; d86f_set_cur_track(drive, track); - if (dev->f == NULL) + if (dev->fp == NULL) return; if (track < 0) @@ -396,8 +399,8 @@ mfm_load(int drive, char *fn) dev = (mfm_t *) malloc(sizeof(mfm_t)); memset(dev, 0x00, sizeof(mfm_t)); - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { free(dev); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; @@ -407,7 +410,7 @@ mfm_load(int drive, char *fn) /* Read the header. */ size = sizeof(mfm_header_t); - if (fread(&dev->hdr, 1, size, dev->f) != size) + if (fread(&dev->hdr, 1, size, dev->fp) != size) fatal("mfm_load(): Error reading header\n"); /* Calculate tracks * sides, allocate the tracks array, and read it. */ @@ -415,12 +418,12 @@ mfm_load(int drive, char *fn) if (dev->hdr.if_type & 0x80) { dev->adv_tracks = (mfm_adv_track_t *) malloc(dev->total_tracks * sizeof(mfm_adv_track_t)); size = dev->total_tracks * sizeof(mfm_adv_track_t); - if (fread(dev->adv_tracks, 1, size, dev->f) != size) + if (fread(dev->adv_tracks, 1, size, dev->fp) != size) fatal("mfm_load(): Error reading advanced tracks\n"); } else { dev->tracks = (mfm_track_t *) malloc(dev->total_tracks * sizeof(mfm_track_t)); size = dev->total_tracks * sizeof(mfm_track_t); - if (fread(dev->tracks, 1, size, dev->f) != size) + if (fread(dev->tracks, 1, size, dev->fp) != size) fatal("mfm_load(): Error reading tracks\n"); } @@ -501,8 +504,8 @@ mfm_close(int drive) if (dev->adv_tracks) free(dev->adv_tracks); - if (dev->f) - fclose(dev->f); + if (dev->fp) + fclose(dev->fp); /* Release the memory. */ free(dev); diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 56f594c0bf..46e29343be 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -60,16 +60,19 @@ /* update when cumulative frequency */ /* reaches to this value */ -typedef struct { - uint16_t r, - bufcnt, bufndx, bufpos, /* string buffer */ - /* the following to allow block reads - from input in next_word() */ - ibufcnt, ibufndx; /* input buffer counters */ - uint8_t inbuf[BUFSZ]; /* input buffer */ +typedef struct tdlzhuf_t { + uint16_t r; + uint16_t bufcnt; /* string buffer */ + uint16_t bufndx; /* string buffer */ + uint16_t bufpos; /* string buffer */ + /* the following to allow block reads + from input in next_word() */ + uint16_t ibufcnt; /* input buffer counters */ + uint16_t ibufndx; /* input buffer counters */ + uint8_t inbuf[BUFSZ]; /* input buffer */ } tdlzhuf; -typedef struct { +typedef struct td0dsk_t { FILE *fdd_file; off_t fdd_file_offset; @@ -90,7 +93,7 @@ typedef struct { uint8_t getlen; } td0dsk_t; -typedef struct { +typedef struct td0_sector_t { uint8_t track; uint8_t head; uint8_t sector; @@ -100,8 +103,8 @@ typedef struct { uint8_t *data; } td0_sector_t; -typedef struct { - FILE *f; +typedef struct td0_t { + FILE *fp; int tracks; int track_width; @@ -224,9 +227,9 @@ fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) { td0_t *dev = td0[drive]; - if (fseek(dev->f, offset, SEEK_SET) == -1) + if (fseek(dev->fp, offset, SEEK_SET) == -1) fatal("fdd_image_read(): Error seeking to the beginning of the file\n"); - if (fread(buffer, 1, len, dev->f) != len) + if (fread(buffer, 1, len, dev->fp) != len) fatal("fdd_image_read(): Error reading data\n"); } @@ -364,7 +367,7 @@ state_reconst(td0dsk_t *state) for (i = 0, j = N_CHAR; j < T; i += 2, j++) { k = i + 1; f = state->freq[j] = state->freq[i] + state->freq[k]; - for (k = j - 1; f < state->freq[k]; k--) { }; + for (k = j - 1; f < state->freq[k]; k--) { } k++; l = (j - k) * 2; @@ -405,7 +408,7 @@ state_update(td0dsk_t *state, int c) /* swap nodes to keep the tree freq-ordered */ if (k > state->freq[l = c + 1]) { - while (k > state->freq[++l]) { }; + while (k > state->freq[++l]) { } l--; state->freq[c] = state->freq[l]; state->freq[l] = k; @@ -592,45 +595,45 @@ get_raw_tsize(int side_flags, int slower_rpm) static int td0_initialize(int drive) { - td0_t *dev = td0[drive]; - uint8_t header[12]; - int fm; - int head; - int track; - int track_count = 0; - int head_count = 0; - int track_spt; - int track_spt_adjusted; - int offset = 0; - int density = 0; - int temp_rate = 0; - uint32_t file_size; - uint16_t len; - uint16_t rep; - td0dsk_t disk_decode; - uint8_t *hs; - uint16_t size; - uint8_t *dbuf = dev->processed_buf; - uint32_t total_size = 0; - uint32_t id_field = 0; - uint32_t pre_sector = 0; - int32_t track_size = 0; - int32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; - int i; - int j; - int k; - int size_diff; - int gap_sum; - - if (dev->f == NULL) { + td0_t *dev = td0[drive]; + uint8_t header[12]; + int fm; + int head; + int track; + int track_count = 0; + int head_count = 0; + int track_spt; + int track_spt_adjusted; + int offset = 0; + int density = 0; + int temp_rate = 0; + uint32_t file_size; + uint16_t len; + uint16_t rep; + td0dsk_t disk_decode; + const uint8_t *hs; + uint16_t size; + uint8_t *dbuf = dev->processed_buf; + uint32_t total_size = 0; + uint32_t id_field = 0; + uint32_t pre_sector = 0; + int32_t track_size = 0; + int32_t raw_tsize = 0; + uint32_t minimum_gap3 = 0; + uint32_t minimum_gap4 = 0; + int i; + int j; + int k; + int size_diff; + int gap_sum; + + if (dev->fp == NULL) { td0_log("TD0: Attempted to initialize without loading a file first\n"); return 0; } - fseek(dev->f, 0, SEEK_END); - file_size = ftell(dev->f); + fseek(dev->fp, 0, SEEK_END); + file_size = ftell(dev->fp); if (file_size < 12) { td0_log("TD0: File is too small to even contain the header\n"); @@ -642,21 +645,21 @@ td0_initialize(int drive) return 0; } - fseek(dev->f, 0, SEEK_SET); - (void) !fread(header, 1, 12, dev->f); + fseek(dev->fp, 0, SEEK_SET); + (void) !fread(header, 1, 12, dev->fp); head_count = header[9]; if (header[0] == 't') { td0_log("TD0: File is compressed\n"); - disk_decode.fdd_file = dev->f; + disk_decode.fdd_file = dev->fp; state_init_Decode(&disk_decode); disk_decode.fdd_file_offset = 12; state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); } else { td0_log("TD0: File is uncompressed\n"); - if (fseek(dev->f, 12, SEEK_SET) == -1) + if (fseek(dev->fp, 12, SEEK_SET) == -1) fatal("td0_initialize(): Error seeking to offet 12\n"); - if (fread(dev->imagebuf, 1, file_size - 12, dev->f) != (file_size - 12)) + if (fread(dev->imagebuf, 1, file_size - 12, dev->fp) != (file_size - 12)) fatal("td0_initialize(): Error reading image buffer\n"); } @@ -707,6 +710,9 @@ td0_initialize(int drive) dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); dev->max_sector_size = (density == 1) ? 6 : ((density == 2) ? 7 : 5); /* 16384, 8192, or 4096 bytes. */ break; + + default: + break; } dev->disk_flags = header[5] & 0x06; @@ -883,7 +889,7 @@ td0_initialize(int drive) static uint16_t disk_flags(int drive) { - td0_t *dev = td0[drive]; + const td0_t *dev = td0[drive]; return (dev->disk_flags); } @@ -891,9 +897,9 @@ disk_flags(int drive) static uint16_t side_flags(int drive) { - td0_t *dev = td0[drive]; - int side = 0; - uint16_t sflags = 0; + const td0_t *dev = td0[drive]; + int side = 0; + uint16_t sflags = 0; side = fdd_get_head(drive); sflags = dev->current_side_flags[side]; @@ -920,7 +926,7 @@ set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) static uint8_t poll_read_data(int drive, int side, uint16_t pos) { - td0_t *dev = td0[drive]; + const td0_t *dev = td0[drive]; return (dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); } @@ -1061,7 +1067,7 @@ td0_seek(int drive, int track) int fm; int sector_adjusted; - if (dev->f == NULL) + if (dev->fp == NULL) return; if (!dev->track_width && fdd_doublestep_40(drive)) @@ -1179,8 +1185,8 @@ td0_abort(int drive) free(dev->imagebuf); if (dev->processed_buf) free(dev->processed_buf); - if (dev->f) - fclose(dev->f); + if (dev->fp) + fclose(dev->fp); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); td0[drive] = NULL; @@ -1200,8 +1206,8 @@ td0_load(int drive, char *fn) memset(dev, 0x00, sizeof(td0_t)); td0[drive] = dev; - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { + dev->fp = plat_fopen(fn, "rb"); + if (dev->fp == NULL) { memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; } @@ -1282,8 +1288,8 @@ td0_close(int drive) memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); } - if (dev->f != NULL) - fclose(dev->f); + if (dev->fp != NULL) + fclose(dev->fp); /* Release resources. */ free(dev); diff --git a/src/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index 0be984d8ae..c6a41a52d0 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -30,17 +30,15 @@ #include #include -/* IF UAE */ -/*#include "sysconfig.h" -#include "sysdeps.h" -#include "zfile.h"*/ -/* ELSE */ #define xmalloc malloc #define HAVE_STDARG_H #include <86box/86box.h> #include +#include <86box/plat_unused.h> +#ifdef DEBUG #undef DEBUG +#endif #define VERBOSE #undef VERBOSE @@ -69,7 +67,8 @@ datalog(uint8_t *src, int len) { static char buf[1000]; static int offset; - int i = 0, offset2; + int i = 0; + int offset2; offset2 = offset; buf[offset++] = '\''; @@ -99,24 +98,24 @@ static int fdi_allocated; #ifdef DEBUG static void -fdi_free(void *p) +fdi_free(void *priv) { int size; - if (!p) + if (!priv) return; - size = ((int *) p)[-1]; + size = ((int *) priv)[-1]; fdi_allocated -= size; write_log("%d freed (%d)\n", size, fdi_allocated); - free((int *) p - 1); + free((int *) priv - 1); } static void * fdi_malloc(int size) { - void *p = xmalloc(size + sizeof(int)); - ((int *) p)[0] = size; + void *priv = xmalloc(size + sizeof(int)); + ((int *) prv)[0] = size; fdi_allocated += size; write_log("%d allocated (%d)\n", size, fdi_allocated); - return (int *) p + 1; + return (int *) priv + 1; } #else # define fdi_free free @@ -360,7 +359,7 @@ decode_raw_track(FDI *fdi) /* unknown track */ static void -zxx(FDI *fdi) +zxx(UNUSED(FDI *fdi)) { fdi2raw_log("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); } @@ -373,7 +372,7 @@ static void zyy (FDI *fdi) #endif /* empty track */ static void -track_empty(FDI *fdi) +track_empty(UNUSED(FDI *fdi)) { return; } @@ -647,8 +646,9 @@ s0d(FDI *fdi) /* ***** */ /* just for testing integrity of Amiga sectors */ - -/*static void rotateonebit (uint8_t *start, uint8_t *end, int shift) +#if 0 +static void +rotateonebit (uint8_t *start, uint8_t *end, int shift) { if (shift == 0) return; @@ -657,9 +657,10 @@ s0d(FDI *fdi) start[0] |= start[1] >> (8 - shift); start++; } -}*/ +} -/*static uint16_t getmfmword (uint8_t *mbuf) +static uint16_t +getmfmword (uint8_t *mbuf) { uint32_t v; @@ -670,13 +671,15 @@ s0d(FDI *fdi) v |= mbuf[2]; v >>= check_offset; return (uint16_t)v; -}*/ +} #define MFMMASK 0x55555555 -/*static uint32_t getmfmlong (uint8_t * mbuf) +static uint32_t +getmfmlong (uint8_t * mbuf) { return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK; -}*/ +} +#endif #if 0 static int amiga_check_track (FDI *fdi) @@ -1237,7 +1240,7 @@ s1d(FDI *fdi) /* end marker */ static void -sff(FDI *fdi) +sff(UNUSED(FDI *fdi)) { } @@ -1289,6 +1292,9 @@ track_atari_st(struct fdi *fdi, int max_sector) case 10: gap3 = 24; break; + + default: + break; } s15(fdi); for (int i = 0; i < max_sector; i++) { @@ -1493,16 +1499,16 @@ fdi_decompress(int pulses, uint8_t *sizep, uint8_t *src, int *dofree) } static void -dumpstream(int track, uint8_t *stream, int len) +dumpstream(UNUSED(int track), UNUSED(uint8_t *stream), UNUSED(int len)) { #if 0 char name[100]; - FILE *f; + FILE *fp; sprintf (name, "track_%d.raw", track); - f = fopen(name, "wb"); - fwrite (stream, 1, len * 4, f); - fclose (f); + fp = fopen(name, "wb"); + fwrite (stream, 1, len * 4, fp); + fclose (fp); #endif } @@ -1713,7 +1719,9 @@ fdi2_decode(FDI *fdi, uint32_t totalavg, uint32_t *avgp, uint32_t *minp, uint32_ /* calculates the current average bitrate from previous decoded data */ uint32_t avg_size = (uint32_t) ((total << (2 + mfm)) / totaldiv); /* this is the new average size for one MFM bit */ - /* uint32_t avg_size = (uint32_t)((((float)total)*((float)(mfm+1))*4.0) / ((float)totaldiv)); */ +#if 0 + uint32_t avg_size = (uint32_t)((((float)total)*((float)(mfm+1))*4.0) / ((float)totaldiv)); +#endif /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */ if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) || (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) { avg_size = standard_MFM_8_bit_cell_size; @@ -1912,9 +1920,9 @@ fdi2_decode(FDI *fdi, uint32_t totalavg, uint32_t *avgp, uint32_t *minp, uint32_ static void fdi2_celltiming(FDI *fdi, uint32_t totalavg, int bitoffset, uint16_t *out) { - uint16_t *pt2; - uint16_t *pt; - double avg_bit_len; + const uint16_t *pt2; + uint16_t *pt; + double avg_bit_len; avg_bit_len = (double) totalavg / (double) bitoffset; pt2 = fdi->track_dst_buffer_timing; @@ -1932,27 +1940,27 @@ fdi2_celltiming(FDI *fdi, uint32_t totalavg, int bitoffset, uint16_t *out) static int decode_lowlevel_track(FDI *fdi, int track, struct fdi_cache *cache) { - uint8_t *p1; - uint32_t *p2; - uint32_t *avgp; - uint32_t *minp = 0; - uint32_t *maxp = 0; - uint8_t *idxp = 0; - uint32_t maxidx; - uint32_t totalavg; - uint32_t weakbits; - int i; - int j; - int len; - int pulses; - int indexoffset; - int avg_free; - int min_free = 0; - int max_free = 0; - int idx_free; - int idx_off1 = 0; - int idx_off2 = 0; - int idx_off3 = 0; + uint8_t *p1; + const uint32_t *p2; + uint32_t *avgp; + uint32_t *minp = 0; + uint32_t *maxp = 0; + uint8_t *idxp = 0; + uint32_t maxidx; + uint32_t totalavg; + uint32_t weakbits; + int j; + int k; + int len; + int pulses; + int indexoffset; + int avg_free; + int min_free = 0; + int max_free = 0; + int idx_free; + int idx_off1 = 0; + int idx_off2 = 0; + int idx_off3 = 0; p1 = fdi->track_src; pulses = get_u32(p1); @@ -1971,7 +1979,7 @@ decode_lowlevel_track(FDI *fdi, int track, struct fdi_cache *cache) maxp = (uint32_t *) fdi_decompress(pulses, p1 + 6, p1 + len, &max_free); len += get_u24(p1 + 6) & 0x3fffff; /* Computes the real min and max values */ - for (i = 0; i < pulses; i++) { + for (int i = 0; i < pulses; i++) { maxp[i] = avgp[i] + minp[i] - maxp[i]; minp[i] = avgp[i] - minp[i]; } @@ -1997,7 +2005,7 @@ decode_lowlevel_track(FDI *fdi, int track, struct fdi_cache *cache) } else { idxp = fdi_malloc(pulses * 2); idx_free = 1; - for (i = 0; i < pulses; i++) { + for (int i = 0; i < pulses; i++) { idxp[i * 2 + 0] = 2; idxp[i * 2 + 1] = 0; } @@ -2008,43 +2016,43 @@ decode_lowlevel_track(FDI *fdi, int track, struct fdi_cache *cache) maxidx = 0; indexoffset = 0; p1 = idxp; - for (i = 0; i < pulses; i++) { + for (int i = 0; i < pulses; i++) { if ((uint32_t) p1[idx_off1] + (uint32_t) p1[idx_off2] > maxidx) maxidx = p1[idx_off1] + p1[idx_off2]; p1 += idx_off3; } p1 = idxp; - for (i = 0; (i < pulses) && (p1[idx_off2] != 0); i++) /* falling edge, replace with idx_off1 for rising edge */ + for (k = 0; (k < pulses) && (p1[idx_off2] != 0); k++) /* falling edge, replace with idx_off1 for rising edge */ p1 += idx_off3; - if (i < pulses) { - j = i; + if (k < pulses) { + j = k; do { - i++; + k++; p1 += idx_off3; - if (i >= pulses) { - i = 0; + if (k >= pulses) { + k = 0; p1 = idxp; } - } while ((i != j) && (p1[idx_off2] == 0)); /* falling edge, replace with idx_off1 for rising edge */ - if (i != j) /* index pulse detected */ + } while ((k != j) && (p1[idx_off2] == 0)); /* falling edge, replace with idx_off1 for rising edge */ + if (k != j) /* index pulse detected */ { - while ((i != j) && (p1[idx_off1] > p1[idx_off2])) { /* falling edge, replace with "<" for rising edge */ - i++; + while ((k != j) && (p1[idx_off1] > p1[idx_off2])) { /* falling edge, replace with "<" for rising edge */ + k++; p1 += idx_off3; - if (i >= pulses) { - i = 0; + if (k >= pulses) { + k = 0; p1 = idxp; } } - if (i != j) - indexoffset = i; /* index position detected */ + if (k != j) + indexoffset = k; /* index position detected */ } } p1 = idxp; p2 = avgp; totalavg = 0; weakbits = 0; - for (i = 0; i < pulses; i++) { + for (int i = 0; i < pulses; i++) { uint32_t sum = p1[idx_off1] + p1[idx_off2]; if (sum >= maxidx) { totalavg += *p2; @@ -2056,8 +2064,10 @@ decode_lowlevel_track(FDI *fdi, int track, struct fdi_cache *cache) idxp[i] = sum; } len = totalavg / 100000; - /* fdi2raw_log("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n", - totalavg, indexoffset, maxidx, weakbits, len); */ +#if 0 + fdi2raw_log("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n", + totalavg, indexoffset, maxidx, weakbits, len); +#endif cache->avgp = avgp; cache->idxp = idxp; cache->minp = minp; @@ -2152,7 +2162,7 @@ fdi2raw_get_tpi(FDI *fdi) } FDI * -fdi2raw_header(FILE *f) +fdi2raw_header(FILE *fp) { long i; long offset; @@ -2164,7 +2174,7 @@ fdi2raw_header(FILE *f) fdi2raw_log("ALLOC: memory allocated %d\n", fdi_allocated); fdi = fdi_malloc(sizeof(FDI)); memset(fdi, 0, sizeof(FDI)); - fdi->file = f; + fdi->file = fp; oldseek = ftell(fdi->file); if (oldseek == -1) { fdi_free(fdi); @@ -2239,15 +2249,17 @@ fdi2raw_loadrevolution_2(FDI *fdi, uint16_t *mfmbuf, uint16_t *tracktiming, int fdi2_decode(fdi, cache->totalavg, cache->avgp, cache->minp, cache->maxp, cache->idxp, cache->maxidx, &idx, cache->pulses, mfm); - /* fdi2raw_log("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n", - track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset); */ +#if 0 + fdi2raw_log("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n", + track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset); +#endif len = fdi->out; if (cache->weakbits >= 10 && multirev) *multirev = 1; *tracklength = len; for (int i = 0; i < (len + 15) / (2 * 8); i++) { - uint8_t *data = fdi->track_dst_buffer + i * 2; + const uint8_t *data = fdi->track_dst_buffer + i * 2; *mfmbuf++ = 256 * *data + *(data + 1); } fdi2_celltiming(fdi, cache->totalavg, len, tracktiming); @@ -2266,7 +2278,7 @@ fdi2raw_loadrevolution(FDI *fdi, uint16_t *mfmbuf, uint16_t *tracktiming, int tr int fdi2raw_loadtrack(FDI *fdi, uint16_t *mfmbuf, uint16_t *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev, int mfm) { - uint8_t *p; + const uint8_t *p; int outlen; struct fdi_cache *cache = &fdi->cache[track]; @@ -2298,8 +2310,10 @@ fdi2raw_loadtrack(FDI *fdi, uint16_t *mfmbuf, uint16_t *tracktiming, int track, else fdi->bit_rate = 250; - /* fdi2raw_log("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n", - fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); */ +#if 0 + fdi2raw_log("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n", + fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); +#endif if ((fdi->track_type & 0xc0) == 0x80) { @@ -2338,8 +2352,8 @@ fdi2raw_loadtrack(FDI *fdi, uint16_t *mfmbuf, uint16_t *tracktiming, int track, return fdi2raw_loadrevolution_2(fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm); *tracklength = fdi->out; for (int i = 0; i < ((*tracklength) + 15) / (2 * 8); i++) { - uint8_t *data = fdi->track_dst_buffer + i * 2; - *mfmbuf++ = 256 * *data + *(data + 1); + const uint8_t *data = fdi->track_dst_buffer + i * 2; + *mfmbuf++ = 256 * *data + *(data + 1); } } return outlen; diff --git a/src/game/gameport.c b/src/game/gameport.c index 110b884ec6..58d9a446f5 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -31,12 +31,9 @@ #include <86box/timer.h> #include <86box/isapnp.h> #include <86box/gameport.h> -#include <86box/joystick_ch_flightstick_pro.h> -#include <86box/joystick_standard.h> -#include <86box/joystick_sw_pad.h> -#include <86box/joystick_tm_fcs.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct g_axis_t { pc_timer_t timer; int axis_nr; struct _joystick_instance_ *joystick; @@ -57,7 +54,7 @@ typedef struct _joystick_instance_ { void *dat; } joystick_instance_t; -int joystick_type = 0; +int joystick_type = JS_TYPE_NONE; static const joystick_if_t joystick_none = { .name = "None", @@ -115,9 +112,10 @@ static uint8_t gameport_pnp_rom[] = { }; static const isapnp_device_config_t gameport_pnp_defaults[] = { {.activate = 1, - .io = { - { .base = 0x200 }, - }} + .io = { + { .base = 0x200 }, + } + } }; const device_t *standalone_gameport_type; @@ -126,21 +124,21 @@ int gameport_instance_id = 0; or writes, and ports at the standard 200h location are prioritized. */ static gameport_t *active_gameports = NULL; -char * +const char * joystick_get_name(int js) { if (!joysticks[js].joystick) return NULL; - return (char *) joysticks[js].joystick->name; + return joysticks[js].joystick->name; } -char * +const char * joystick_get_internal_name(int js) { if (joysticks[js].joystick == NULL) return ""; - return (char *) joysticks[js].joystick->internal_name; + return joysticks[js].joystick->internal_name; } int @@ -149,7 +147,7 @@ joystick_get_from_internal_name(char *s) int c = 0; while (joysticks[c].joystick != NULL) { - if (!strcmp((char *) joysticks[c].joystick->internal_name, s)) + if (!strcmp(joysticks[c].joystick->internal_name, s)) return c; c++; } @@ -181,22 +179,22 @@ joystick_get_pov_count(int js) return joysticks[js].joystick->pov_count; } -char * +const char * joystick_get_axis_name(int js, int id) { - return (char *) joysticks[js].joystick->axis_names[id]; + return joysticks[js].joystick->axis_names[id]; } -char * +const char * joystick_get_button_name(int js, int id) { - return (char *) joysticks[js].joystick->button_names[id]; + return joysticks[js].joystick->button_names[id]; } -char * +const char * joystick_get_pov_name(int js, int id) { - return (char *) joysticks[js].joystick->pov_names[id]; + return joysticks[js].joystick->pov_names[id]; } static void @@ -214,7 +212,7 @@ gameport_time(joystick_instance_t *joystick, int nr, int axis) } static void -gameport_write(uint16_t addr, uint8_t val, void *priv) +gameport_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv) { gameport_t *dev = (gameport_t *) priv; joystick_instance_t *joystick = dev->joystick; @@ -238,7 +236,7 @@ gameport_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -gameport_read(uint16_t addr, void *priv) +gameport_read(UNUSED(uint16_t addr), void *priv) { gameport_t *dev = (gameport_t *) priv; joystick_instance_t *joystick = dev->joystick; @@ -400,7 +398,7 @@ gameport_init(const device_t *info) } static void * -tmacm_init(const device_t *info) +tmacm_init(UNUSED(const device_t *info)) { uint16_t port = 0x0000; gameport_t *dev = NULL; @@ -408,7 +406,7 @@ tmacm_init(const device_t *info) dev = malloc(sizeof(gameport_t)); memset(dev, 0x00, sizeof(gameport_t)); - port = device_get_config_hex16("port1_addr"); + port = (uint16_t) device_get_config_hex16("port1_addr"); switch (port) { case 0x201: dev = gameport_add(&gameport_201_device); @@ -426,7 +424,7 @@ tmacm_init(const device_t *info) break; } - port = device_get_config_hex16("port2_addr"); + port = (uint16_t) device_get_config_hex16("port2_addr"); switch (port) { case 0x209: dev = gameport_add(&gameport_209_device); diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index f5785d6f4c..8ca51d5313 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> +#include <86box/plat_unused.h> static void * ch_flightstick_pro_init(void) @@ -52,12 +52,13 @@ ch_flightstick_pro_init(void) } static void -ch_flightstick_pro_close(void *p) +ch_flightstick_pro_close(UNUSED(void *priv)) { + // } static uint8_t -ch_flightstick_pro_read(void *p) +ch_flightstick_pro_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; @@ -86,12 +87,13 @@ ch_flightstick_pro_read(void *p) } static void -ch_flightstick_pro_write(void *p) +ch_flightstick_pro_write(UNUSED(void *priv)) { + // } static int -ch_flightstick_pro_read_axis(void *p, int axis) +ch_flightstick_pro_read_axis(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -111,8 +113,9 @@ ch_flightstick_pro_read_axis(void *p, int axis) } static void -ch_flightstick_pro_a0_over(void *p) +ch_flightstick_pro_a0_over(UNUSED(void *priv)) { + // } const joystick_if_t joystick_ch_flightstick_pro = { diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index 55a28acee1..1d15687382 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> +#include <86box/plat_unused.h> static void * joystick_standard_init(void) @@ -52,12 +52,13 @@ joystick_standard_init(void) } static void -joystick_standard_close(void *p) +joystick_standard_close(UNUSED(void *priv)) { + // } static uint8_t -joystick_standard_read(void *p) +joystick_standard_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; @@ -78,7 +79,7 @@ joystick_standard_read(void *p) } static uint8_t -joystick_standard_read_4button(void *p) +joystick_standard_read_4button(UNUSED(void *priv)) { uint8_t ret = 0xf0; @@ -97,12 +98,13 @@ joystick_standard_read_4button(void *p) } static void -joystick_standard_write(void *p) +joystick_standard_write(UNUSED(void *priv)) { + // } static int -joystick_standard_read_axis(void *p, int axis) +joystick_standard_read_axis(UNUSED(void *priv), int axis) { switch (axis) { case 0: @@ -127,7 +129,7 @@ joystick_standard_read_axis(void *p, int axis) } static int -joystick_standard_read_axis_4button(void *p, int axis) +joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -147,7 +149,7 @@ joystick_standard_read_axis_4button(void *p, int axis) } static int -joystick_standard_read_axis_3axis(void *p, int axis) +joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -167,7 +169,7 @@ joystick_standard_read_axis_3axis(void *p, int axis) } static int -joystick_standard_read_axis_4axis(void *p, int axis) +joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -187,7 +189,7 @@ joystick_standard_read_axis_4axis(void *p, int axis) } static int -joystick_standard_read_axis_6button(void *p, int axis) +joystick_standard_read_axis_6button(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -206,7 +208,7 @@ joystick_standard_read_axis_6button(void *p, int axis) } } static int -joystick_standard_read_axis_8button(void *p, int axis) +joystick_standard_read_axis_8button(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -234,8 +236,9 @@ joystick_standard_read_axis_8button(void *p, int axis) } static void -joystick_standard_a0_over(void *p) +joystick_standard_a0_over(UNUSED(void *priv)) { + // } const joystick_if_t joystick_2axis_2button = { diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 9f3fd492c5..7962c38e3e 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -64,10 +64,9 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_sw_pad.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct sw_data { pc_timer_t poll_timer; int poll_left; int poll_clock; @@ -79,9 +78,9 @@ typedef struct } sw_data; static void -sw_timer_over(void *p) +sw_timer_over(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; sw->poll_clock = !sw->poll_clock; @@ -99,9 +98,9 @@ sw_timer_over(void *p) } static void -sw_trigger_timer_over(void *p) +sw_trigger_timer_over(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; timer_disable(&sw->trigger_timer); } @@ -132,17 +131,17 @@ sw_init(void) } static void -sw_close(void *p) +sw_close(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; free(sw); } static uint8_t -sw_read(void *p) +sw_read(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; uint8_t temp = 0; if (!JOYSTICK_PRESENT(0)) @@ -166,9 +165,9 @@ sw_read(void *p) } static void -sw_write(void *p) +sw_write(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; int64_t time_since_last = timer_get_remaining_us(&sw->trigger_timer); if (!JOYSTICK_PRESENT(0)) @@ -234,7 +233,7 @@ sw_write(void *p) } static int -sw_read_axis(void *p, int axis) +sw_read_axis(UNUSED(void *priv), UNUSED(int axis)) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -243,9 +242,9 @@ sw_read_axis(void *p, int axis) } static void -sw_a0_over(void *p) +sw_a0_over(void *priv) { - sw_data *sw = (sw_data *) p; + sw_data *sw = (sw_data *) priv; timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); } diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 7bcb157422..f5c1e64e6a 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/gameport.h> -#include <86box/joystick_standard.h> +#include <86box/plat_unused.h> static void * tm_fcs_init(void) @@ -52,12 +52,13 @@ tm_fcs_init(void) } static void -tm_fcs_close(void *p) +tm_fcs_close(UNUSED(void *priv)) { + // } static uint8_t -tm_fcs_read(void *p) +tm_fcs_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; @@ -76,12 +77,13 @@ tm_fcs_read(void *p) } static void -tm_fcs_write(void *p) +tm_fcs_write(UNUSED(void *priv)) { + // } static int -tm_fcs_read_axis(void *p, int axis) +tm_fcs_read_axis(UNUSED(void *priv), int axis) { if (!JOYSTICK_PRESENT(0)) return AXIS_NOT_PRESENT; @@ -111,8 +113,9 @@ tm_fcs_read_axis(void *p, int axis) } static void -tm_fcs_a0_over(void *p) +tm_fcs_a0_over(UNUSED(void *priv)) { + // } const joystick_if_t joystick_tm_fcs = { diff --git a/src/gdbstub.c b/src/gdbstub.c index 867ebe1d1d..7036374220 100644 --- a/src/gdbstub.c +++ b/src/gdbstub.c @@ -75,8 +75,10 @@ enum { GDB_REG_ES, GDB_REG_FS, GDB_REG_GS, +#if 0 GDB_REG_FS_BASE, GDB_REG_GS_BASE, +#endif GDB_REG_CR0, GDB_REG_CR2, GDB_REG_CR3, @@ -120,13 +122,20 @@ typedef struct _gdbstub_client_ { int socket; struct sockaddr_in addr; - char packet[16384], response[16384]; - int has_packet : 1, first_packet_received : 1, ida_mode : 1, waiting_stop : 1, - packet_pos, response_pos; + char packet[16384], response[16384]; + uint8_t has_packet : 1; + uint8_t first_packet_received : 1; + uint8_t ida_mode : 1; + uint8_t waiting_stop : 1; + int packet_pos; + int response_pos; - event_t *processed_event, *response_event; + event_t *processed_event; + event_t *response_event; - uint16_t last_io_base, last_io_len, last_io_value; + uint16_t last_io_base; + uint16_t last_io_len; + uint16_t last_io_value; struct _gdbstub_client_ *next; } gdbstub_client_t; @@ -213,8 +222,10 @@ static char target_xml[] = /* QEMU gdb-xml/i386-32bit.xml with modificati "" "" "" +#if 0 "" "" +#endif "" "" "" @@ -332,14 +343,15 @@ static gdbstub_client_t *first_client = NULL; static gdbstub_client_t *last_client = NULL; static mutex_t *client_list_mutex; -static void (*cpu_exec_shadow)(int cycs); +static void (*cpu_exec_shadow)(int32_t cycs); static gdbstub_breakpoint_t *first_swbreak = NULL; static gdbstub_breakpoint_t *first_hwbreak = NULL; static gdbstub_breakpoint_t *first_rwatch = NULL; static gdbstub_breakpoint_t *first_wwatch = NULL; static gdbstub_breakpoint_t *first_awatch = NULL; -int gdbstub_step = 0, gdbstub_next_asap = 0; +int gdbstub_step = 0; +int gdbstub_next_asap = 0; uint64_t gdbstub_watch_pages[(((uint32_t) -1) >> (MEM_GRANULARITY_BITS + 6)) + 1]; static void @@ -461,6 +473,9 @@ gdbstub_num_decode(char *p, int *dest, int mode) else return 0; break; + + default: + break; } p++; } @@ -476,8 +491,8 @@ gdbstub_num_decode(char *p, int *dest, int mode) static int gdbstub_client_read_word(gdbstub_client_t *client, int *dest) { - char *p = &client->packet[client->packet_pos]; - char *q = p; + const char *p = &client->packet[client->packet_pos]; + const char *q = p; while (((*p >= '0') && (*p <= '9')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= 'a') && (*p <= 'f'))) *dest = ((*dest) << 4) | gdbstub_hex_decode(*p++); return p - q; @@ -535,10 +550,12 @@ gdbstub_client_write_reg(int index, uint8_t *buf) flushmmucache(); break; +#if 0 case GDB_REG_FS_BASE ... GDB_REG_GS_BASE: /* Do what qemu does and just load the base. */ segment_regs[(index - 16) + (GDB_REG_FS - GDB_REG_CS)]->base = *((uint32_t *) buf); break; +#endif case GDB_REG_CR0 ... GDB_REG_CR4: *cr_regs[index - GDB_REG_CR0] = *((uint32_t *) buf); @@ -614,10 +631,10 @@ gdbstub_client_respond(gdbstub_client_t *client) /* Send response packet. */ client->response[client->response_pos] = '\0'; #ifdef ENABLE_GDBSTUB_LOG - i = client->response[995]; /* pclog_ex buffer too small */ - client->response[995] = '\0'; + i = client->response[994]; /* pclog_ex buffer too small */ + client->response[994] = '\0'; gdbstub_log("GDB Stub: Sending response: %s\n", client->response); - client->response[995] = i; + client->response[994] = i; #endif send(client->socket, "$", 1, 0); send(client->socket, client->response, client->response_pos, 0); @@ -667,9 +684,11 @@ gdbstub_client_read_reg(int index, uint8_t *buf) *((uint16_t *) buf) = segment_regs[index - GDB_REG_CS]->seg; break; +#if 0 case GDB_REG_FS_BASE ... GDB_REG_GS_BASE: *((uint32_t *) buf) = segment_regs[(index - 16) + (GDB_REG_FS - GDB_REG_CS)]->base; break; +#endif case GDB_REG_CR0 ... GDB_REG_CR4: *((uint32_t *) buf) = *cr_regs[index - GDB_REG_CR0]; @@ -1004,13 +1023,8 @@ gdbstub_client_packet(gdbstub_client_t *client) /* Add our supported features to the end. */ if (client->response_pos < (sizeof(client->response) - 1)) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - client->response_pos += snprintf(&client->response[client->response_pos], sizeof(client->response) - client->response_pos, - "PacketSize=%lX;swbreak+;hwbreak+;qXfer:features:read+", sizeof(client->packet) - 1); -#else client->response_pos += snprintf(&client->response[client->response_pos], sizeof(client->response) - client->response_pos, - "PacketSize=%X;swbreak+;hwbreak+;qXfer:features:read+", sizeof(client->packet) - 1); -#endif + "PacketSize=%X;swbreak+;hwbreak+;qXfer:features:read+", (int) (sizeof(client->packet) - 1)); break; } else if (!strcmp(client->response, "Xfer")) { /* Read the transfer object. */ @@ -1086,7 +1100,7 @@ gdbstub_client_packet(gdbstub_client_t *client) } else if (!strcmp(client->response, "C")) { FAST_RESPONSE("QC1"); } else if (!strcmp(client->response, "fThreadInfo")) { - FAST_RESPONSE("m 1"); + FAST_RESPONSE("m1"); } else if (!strcmp(client->response, "sThreadInfo")) { FAST_RESPONSE("l"); } else if (!strcmp(client->response, "Rcmd")) { @@ -1334,7 +1348,7 @@ gdbstub_client_packet(gdbstub_client_t *client) /* Flag this watchpoint's corresponding pages as having a watchpoint. */ k = (breakpoint->end - 1) >> MEM_GRANULARITY_BITS; for (i = breakpoint->addr >> MEM_GRANULARITY_BITS; i <= k; i++) - gdbstub_watch_pages[i >> 6] |= (1 << (i & 63)); + gdbstub_watch_pages[i >> 6] |= (1ULL << (i & 63)); breakpoint = breakpoint->next; } else { @@ -1359,7 +1373,7 @@ gdbstub_client_packet(gdbstub_client_t *client) } static void -gdbstub_cpu_exec(int cycs) +gdbstub_cpu_exec(int32_t cycs) { /* Flag that we're now in the debugger context to avoid triggering watchpoints. */ in_gdbstub = 1; @@ -1491,7 +1505,6 @@ gdbstub_client_thread(void *priv) gdbstub_client_t *client = (gdbstub_client_t *) priv; uint8_t buf[256]; ssize_t bytes_read; - int i; gdbstub_log("GDB Stub: New connection from %s:%d\n", inet_ntoa(client->addr.sin_addr), client->addr.sin_port); @@ -1500,7 +1513,7 @@ gdbstub_client_thread(void *priv) /* Read data from client. */ while ((bytes_read = recv(client->socket, (char *) buf, sizeof(buf), 0)) > 0) { - for (i = 0; i < bytes_read; i++) { + for (ssize_t i = 0; i < bytes_read; i++) { switch (buf[i]) { case '$': /* packet start */ /* Wait for any existing packets to be processed. */ @@ -1739,8 +1752,10 @@ gdbstub_mem_access(uint32_t *addrs, int access) if (watchpoint) { /* Check if any component of this address is within the breakpoint's range. */ for (i = 0; i < width; i++) { - if ((addrs[i] >= watchpoint->addr) && (addrs[i] < watchpoint->end)) + if ((addrs[i] >= watchpoint->addr) && (addrs[i] < watchpoint->end)) { + watch_addr = addrs[i]; break; + } } if (i < width) { gdbstub_log("GDB Stub: %s watchpoint at %08X\n", (access & GDBSTUB_MEM_AWATCH) ? "Access" : ((access & GDBSTUB_MEM_WRITE) ? "Write" : "Read"), watch_addr); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 977d3db63b..20f3fffccb 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -33,11 +33,14 @@ /* Recently used images */ #define MAX_PREV_IMAGES 4 -#define MAX_IMAGE_PATH_LEN 256 +#define MAX_IMAGE_PATH_LEN 2048 /* Default language 0xFFFF = from system, 0x409 = en-US */ #define DEFAULT_LANGUAGE 0x0409 +#define POSTCARDS_NUM 4 +#define POSTCARD_MASK (POSTCARDS_NUM - 1) + #ifdef MIN # undef MIN #endif @@ -47,10 +50,14 @@ #ifdef ABS # undef ABS #endif +#ifdef ABSD +# undef ABSD +#endif #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define ABS(x) ((x) > 0 ? (x) : -(x)) +#define ABSD(x) ((x) > 0.0 ? (x) : -(x)) #define BCD8(x) ((((x) / 10) << 4) | ((x) % 10)) #define BCD16(x) ((((x) / 1000) << 12) | (((x) / 100) << 8) | BCD8(x)) #define BCD32(x) ((((x) / 10000000) << 28) | (((x) / 1000000) << 24) | (((x) / 100000) << 20) | (((x) / 10000) << 16) | BCD16(x)) @@ -71,7 +78,6 @@ extern "C" { extern uint32_t lang_sys; /* (-) system language code */ extern int dump_on_exit; /* (O) dump regs on exit*/ -extern int do_dump_config; /* (O) dump cfg after load */ extern int start_in_fullscreen; /* (O) start in fullscreen */ #ifdef _WIN32 extern int force_debug; /* (O) force debug output */ @@ -98,56 +104,67 @@ extern uint64_t instru_run_ms; #define window_w monitor_settings[0].mon_window_w #define window_h monitor_settings[0].mon_window_h extern int window_remember; -extern int vid_resize; /* (C) allow resizing */ -extern int invert_display; /* (C) invert the display */ -extern int suppress_overscan; /* (C) suppress overscans */ -extern uint32_t lang_id; /* (C) language code identifier */ -extern char icon_set[256]; /* (C) iconset identifier */ -extern int scale; /* (C) screen scale factor */ -extern int dpi_scale; /* (C) DPI scaling of the emulated screen */ -extern int vid_api; /* (C) video renderer */ -extern int vid_cga_contrast; /* (C) video */ -extern int video_fullscreen; /* (C) video */ -extern int video_fullscreen_first; /* (C) video */ -extern int video_fullscreen_scale; /* (C) video */ -extern int enable_overscan; /* (C) video */ -extern int force_43; /* (C) video */ -extern int video_filter_method; /* (C) video */ -extern int video_vsync; /* (C) video */ -extern int video_framerate; /* (C) video */ -extern int gfxcard[2]; /* (C) graphics/video card */ -extern char video_shader[512]; /* (C) video */ -extern int bugger_enabled; /* (C) enable ISAbugger */ -extern int postcard_enabled; /* (C) enable POST card */ -extern int isamem_type[]; /* (C) enable ISA mem cards */ -extern int isartc_type; /* (C) enable ISA RTC card */ -extern int sound_is_float; /* (C) sound uses FP values */ -extern int voodoo_enabled; /* (C) video option */ -extern int ibm8514_enabled; /* (C) video option */ -extern int xga_enabled; /* (C) video option */ -extern uint32_t mem_size; /* (C) memory size (Installed on system board) */ -extern uint32_t isa_mem_size; /* (C) memory size (ISA Memory Cards) */ -extern int cpu; /* (C) cpu type */ -extern int cpu_use_dynarec; /* (C) cpu uses/needs Dyna */ -extern int fpu_type; /* (C) fpu type */ -extern int fpu_softfloat; /* (C) fpu uses softfloat */ -extern int time_sync; /* (C) enable time sync */ -extern int hdd_format_type; /* (C) hard disk file format */ -extern int confirm_reset; /* (C) enable reset confirmation */ -extern int confirm_exit; /* (C) enable exit confirmation */ -extern int confirm_save; /* (C) enable save confirmation */ -extern int enable_discord; /* (C) enable Discord integration */ - -extern int is_pentium; /* TODO: Move back to cpu/cpu.h when it's figured out, - how to remove that hack from the ET4000/W32p. */ +extern int vid_resize; /* (C) allow resizing */ +extern int invert_display; /* (C) invert the display */ +extern int suppress_overscan; /* (C) suppress overscans */ +extern uint32_t lang_id; /* (C) language code identifier */ +extern char icon_set[256]; /* (C) iconset identifier */ +extern int scale; /* (C) screen scale factor */ +extern int dpi_scale; /* (C) DPI scaling of the emulated screen */ +extern int vid_api; /* (C) video renderer */ +extern int vid_cga_contrast; /* (C) video */ +extern int video_fullscreen; /* (C) video */ +extern int video_fullscreen_first; /* (C) video */ +extern int video_fullscreen_scale; /* (C) video */ +extern int enable_overscan; /* (C) video */ +extern int force_43; /* (C) video */ +extern int video_filter_method; /* (C) video */ +extern int video_vsync; /* (C) video */ +extern int video_framerate; /* (C) video */ +extern int gfxcard[2]; /* (C) graphics/video card */ +extern char video_shader[512]; /* (C) video */ +extern int bugger_enabled; /* (C) enable ISAbugger */ +extern int postcard_enabled; /* (C) enable POST card */ +extern int unittester_enabled; /* (C) enable unit tester device */ +extern int isamem_type[]; /* (C) enable ISA mem cards */ +extern int isartc_type; /* (C) enable ISA RTC card */ +extern int sound_is_float; /* (C) sound uses FP values */ +extern int voodoo_enabled; /* (C) video option */ +extern int ibm8514_standalone_enabled; /* (C) video option */ +extern int xga_standalone_enabled; /* (C) video option */ +extern uint32_t mem_size; /* (C) memory size (Installed on system board) */ +extern uint32_t isa_mem_size; /* (C) memory size (ISA Memory Cards) */ +extern int cpu; /* (C) cpu type */ +extern int cpu_use_dynarec; /* (C) cpu uses/needs Dyna */ +extern int fpu_type; /* (C) fpu type */ +extern int fpu_softfloat; /* (C) fpu uses softfloat */ +extern int time_sync; /* (C) enable time sync */ +extern int hdd_format_type; /* (C) hard disk file format */ +extern int confirm_reset; /* (C) enable reset confirmation */ +extern int confirm_exit; /* (C) enable exit confirmation */ +extern int confirm_save; /* (C) enable save confirmation */ +extern int enable_discord; /* (C) enable Discord integration */ + extern int fixed_size_x; extern int fixed_size_y; +extern int do_auto_pause; /* (C) Auto-pause the emulator on focus loss */ +extern int auto_paused; extern double mouse_sensitivity; /* (C) Mouse sensitivity scale */ -extern double mouse_x_error; /* Mouse error accumulator - Y */ -extern double mouse_y_error; /* Mouse error accumulator - Y */ +#ifdef _Atomic +extern _Atomic double mouse_x_error; /* Mouse error accumulator - Y */ +extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ +#endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ +/* Keyboard variables for future key combination redefinition. */ +extern uint16_t key_prefix_1_1; +extern uint16_t key_prefix_1_2; +extern uint16_t key_prefix_2_1; +extern uint16_t key_prefix_2_2; +extern uint16_t key_uncapture_1; +extern uint16_t key_uncapture_2; + extern char exe_path[2048]; /* path (dir) of executable */ extern char usr_path[1024]; /* path (dir) of user data */ extern char cfg_path[1024]; /* full path of config file */ @@ -172,7 +189,7 @@ extern void reset_screen_size_monitor(int monitor_index); extern void set_screen_size_natural(void); extern void update_mouse_msg(void); #if 0 -extern void pc_reload(wchar_t *fn); +extern void pc_reload(wchar_t *fn); #endif extern int pc_init_modules(void); extern int pc_init(int argc, char *argv[]); @@ -193,15 +210,19 @@ extern uint16_t get_last_addr(void); /* This is for external subtraction of cycles; should be in cpu.c but I put it here to avoid - having to include cpu.c everywhere. */ + having to include cpu.h everywhere. */ extern void sub_cycles(int c); extern void resub_cycles(int old_cycles); +extern void ack_pause(void); +extern void do_pause(int p); + extern double isa_timing; extern int io_delay; extern int framecountx; -extern volatile int cpu_thread_run; +extern volatile int cpu_thread_run; +extern uint8_t postcard_codes[POSTCARDS_NUM]; #ifdef __cplusplus } diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 18f40d8747..5a3eb39ec0 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -52,53 +52,126 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -#define VEN_ALI 0x010b9 -#define VEN_INTEL 0x08086 -#define VEN_SIS 0x01039 -#define VEN_SMC 0x01055 -#define VEN_VIA 0x01106 -#define VEN_VIA_596B 0x11106 +#define VEN_ALI 0x010b9 +#define VEN_INTEL 0x08086 +#define VEN_SIS_5582 0x01039 +#define VEN_SIS_5595_1997 0x11039 +#define VEN_SIS_5595 0x21039 +#define VEN_SMC 0x01055 +#define VEN_VIA 0x01106 +#define VEN_VIA_596B 0x11106 -typedef struct -{ - uint8_t acpitst, auxen, auxsts, plvl2, plvl3, - smicmd, gpio_dir, - gpio_val, muxcntrl, ali_soft_smi, - timer32, smireg, - gpireg[3], gporeg[4], - extiotrapsts, extiotrapen; - uint16_t pmsts, pmen, - pmcntrl, gpsts, gpsts1, - gpen, gpen1, gpscien, - gpcntrl, gplvl, gpmux, - gpsel, gpsmien, pscntrl, - gpscists; - int smi_lock, smi_active; - uint32_t pcntrl, p2cntrl, glbsts, - devsts, glben, - glbctl, devctl, - padsts, paden, - gptren, gptimer, - gpo_val, gpi_val, - extsmi_val, pad0; +typedef struct acpi_regs_t { + uint8_t acpitst; + uint8_t auxen; + uint8_t auxsts; + uint8_t plvl2; + uint8_t plvl3; + uint8_t smicmd; + uint8_t gpio_dir; + uint8_t gpio_val; + uint8_t muxcntrl; + uint8_t ali_soft_smi; + uint8_t timer32; + uint8_t smireg; + uint8_t gpireg[3]; + uint8_t gporeg[4]; + uint8_t extiotrapsts; + uint8_t extiotrapen; + uint8_t enter_c2_ps; + uint8_t enter_c3_ps; + uint8_t reg_12; + uint8_t reg_13; + uint8_t smi_cmd; + uint8_t reg_24; + uint8_t reg_25; + uint8_t reg_26; + uint8_t smi_en_val; + uint8_t smi_dis_val; + uint8_t mail_box; + uint8_t reg_2b; + uint8_t gp_tmr; + uint8_t leg_sts; + uint8_t leg_en; + uint8_t tst_ctl; + uint8_t reg_34; + uint8_t index; + uint8_t reg_ff; + uint16_t pmsts; + uint16_t pmen; + uint16_t pmcntrl; + uint16_t gpsts; + uint16_t gpsts1; + uint16_t gpen; + uint16_t gpen1; + uint16_t gpscien; + uint16_t gpcntrl; + uint16_t gplvl; + uint16_t gpmux; + uint16_t gpsel; + uint16_t gpsmien; + uint16_t pscntrl; + uint16_t gpscists; + uint16_t reg_14; + uint16_t reg_16; + uint16_t reg_18; + uint16_t reg_1a; + uint16_t reg_1c; + uint16_t gpe_mul; + uint16_t gpe_ctl; + uint16_t gpe_smi; + uint16_t gpe_rl; + int smi_lock; + int smi_active; + uint32_t pcntrl; + uint32_t p2cntrl; + uint32_t glbsts; + uint32_t devsts; + uint32_t glben; + uint32_t glbctl; + uint32_t devctl; + uint32_t padsts; + uint32_t paden; + uint32_t gptren; + uint32_t gptimer; + uint32_t gpo_val; + uint32_t gpi_val; + uint32_t extsmi_val; + uint32_t reg_0c; + uint32_t gpe_sts; + uint32_t gpe_en; + uint32_t gpe_pin; + uint32_t gpe_io; + uint32_t gpe_pol; } acpi_regs_t; -typedef struct -{ +typedef struct acpi_t { acpi_regs_t regs; - uint8_t gpireg2_default, pad[3], - gporeg_default[4], - suspend_types[8]; - uint16_t io_base, aux_io_base; - int vendor, - slot, irq_mode, - irq_pin, irq_line, - mirq_is_level; - pc_timer_t timer, resume_timer, pwrbtn_timer; - nvr_t *nvr; - apm_t *apm; - void *i2c, - (*trap_update)(void *priv), *trap_priv; + uint8_t gpireg2_default; + uint8_t irq_state; + uint8_t pad[2]; + uint8_t gporeg_default[4]; + uint8_t suspend_types[8]; + uint16_t io_base; + uint16_t aux_io_base; + int vendor; + int slot; + int irq_mode; + int irq_pin; + int irq_line; + int mirq_is_level; + pc_timer_t timer; + pc_timer_t resume_timer; + pc_timer_t pwrbtn_timer; + pc_timer_t gp_timer; + pc_timer_t per_timer; + nvr_t *nvr; + apm_t *apm; + void *i2c; + void (*trap_update)(void *priv); + void *trap_priv; + void *smbus; + void *priv; } acpi_t; /* Global variables. */ @@ -111,6 +184,9 @@ extern const device_t acpi_intel_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; extern const device_t acpi_via_596b_device; +extern const device_t acpi_sis_5582_device; +extern const device_t acpi_sis_5595_1997_device; +extern const device_t acpi_sis_5595_device; /* Functions */ extern void acpi_update_irq(acpi_t *dev); @@ -129,6 +205,12 @@ extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr); extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv); extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev); extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi); +extern void * acpi_get_smbus(void *priv); +extern void acpi_sis5582_pmu_event(void *priv); +extern void acpi_sis5595_smi_raise(void *priv); +extern void acpi_sis5595_pmu_event(void *priv); +extern void acpi_sis5595_smbus_event(void *priv); +extern void acpi_sis5595_software_smi(void *priv); #ifdef __cplusplus } diff --git a/src/include/86box/agpgart.h b/src/include/86box/agpgart.h index d73e95e866..d3ed35c888 100644 --- a/src/include/86box/agpgart.h +++ b/src/include/86box/agpgart.h @@ -1,5 +1,5 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in + * 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. @@ -20,7 +20,10 @@ typedef struct agpgart_s { int aperture_enable; - uint32_t aperture_base, aperture_size, aperture_mask, gart_base; + uint32_t aperture_base; + uint32_t aperture_size; + uint32_t aperture_mask; + uint32_t gart_base; mem_mapping_t aperture_mapping; } agpgart_t; diff --git a/src/include/86box/apm.h b/src/include/86box/apm.h index 854969f3d0..2d5f0f1179 100644 --- a/src/include/86box/apm.h +++ b/src/include/86box/apm.h @@ -21,10 +21,10 @@ extern "C" { #endif -typedef struct -{ - uint8_t cmd, - stat, do_smi; +typedef struct apm_t { + uint8_t cmd; + uint8_t stat; + uint8_t do_smi; } apm_t; /* Global variables. */ diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index 9f3c519177..ac758b20a4 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -46,29 +46,29 @@ # define bswap_16(x) \ ( \ ((uint16_t)( \ - (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \ ) # define bswap_32(x) \ ( \ ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \ ) # define bswap_64(x) \ ( \ ((uint64_t)( \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \ ) #endif /*HAVE_BYTESWAP_H*/ diff --git a/src/include/86box/cassette.h b/src/include/86box/cassette.h index 85e510225c..3706ca632c 100644 --- a/src/include/86box/cassette.h +++ b/src/include/86box/cassette.h @@ -24,7 +24,7 @@ #include -typedef struct { +typedef struct pc_cassette_t { char save; char pcm; diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index a32177b055..15127b06e2 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -15,7 +15,7 @@ #ifndef EMU_CDROM_H #define EMU_CDROM_H -#define CDROM_NUM 4 +#define CDROM_NUM 8 #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 @@ -55,81 +55,147 @@ extern "C" { enum { CDROM_BUS_DISABLED = 0, CDROM_BUS_ATAPI = 5, - CDROM_BUS_SCSI, - CDROM_BUS_MITSUMI, - CDROM_BUS_USB + CDROM_BUS_SCSI = 6, + CDROM_BUS_MITSUMI = 7, + CDROM_BUS_USB = 8 }; -#define KNOWN_CDROM_DRIVE_TYPES 35 -#define BUS_TYPE_ALL 0 -#define BUS_TYPE_IDE 1 -#define BUS_TYPE_SCSI 2 +enum +{ + CDROM_TYPE_86BOX_100, + CDROM_TYPE_AZT_CDA46802I_115, + CDROM_TYPE_BTC_BCD36XH_U10, + CDROM_TYPE_GOLDSTAR_CRD_8160B_314, + CDROM_TYPE_HITACHI_CDR_8130_0020, + CDROM_TYPE_KENWOOD_UCR_421_208E, + CDROM_TYPE_MATSHITA_587_7S13, + CDROM_TYPE_MATSHITA_588_LS15, + CDROM_TYPE_MATSHITA_571_10e, + CDROM_TYPE_MATSHITA_572_10j, + CDROM_TYPE_MITSUMI_FX4820T_D02A, + CDROM_TYPE_NEC_260_100, + CDROM_TYPE_NEC_260_101, + CDROM_TYPE_NEC_273_420, + CDROM_TYPE_NEC_280_105, + CDROM_TYPE_NEC_280_308, + CDROM_TYPE_PHILIPS_PCA403CD_U31P, + CDROM_TYPE_SONY_CDU76_10i, + CDROM_TYPE_SONY_CDU311_30h, + CDROM_TYPE_TOSHIBA_5302TA_0305, + CDROM_TYPE_TOSHIBA_5702B_TA70, + CDROM_TYPE_CHINON_CDS431_H42, + CDROM_TYPE_DEC_RRD45_0436, + CDROM_TYPE_MATSHITA_501_10b, + CDROM_TYPE_NEC_25_10a, + CDROM_TYPE_NEC_38_103, + CDROM_TYPE_NEC_75_103, + CDROM_TYPE_NEC_77_106, + CDROM_TYPE_NEC_211_100, + CDROM_TYPE_NEC_464_105, + CDROM_TYPE_SONY_CDU541_10i, + CDROM_TYPE_SONY_CDU561_18k, + CDROM_TYPE_SONY_CDU76S_100, + CDROM_TYPE_PHILIPS_CDD2600_107, + CDROM_TYPE_PIONEER_DRM604X_2403, + CDROM_TYPE_PLEXTOR_PX32TS_103, + CDROM_TYPE_TEAC_CD50_100, + CDROM_TYPE_TEAC_R55S_10R, + CDROM_TYPE_TEXEL_DMXX24_100, + CDROM_TYPE_TOSHIBA_XM_3433, + CDROM_TYPE_TOSHIBA_XM3201B_3232, + CDROM_TYPE_TOSHIBA_XM3301TA_0272, + CDROM_TYPE_TOSHIBA_XM5701TA_3136, + CDROM_TYPE_TOSHIBA_SDM1401_1008, + CDROM_TYPES_NUM +}; + +#define KNOWN_CDROM_DRIVE_TYPES CDROM_TYPES_NUM +#define BUS_TYPE_IDE CDROM_BUS_ATAPI +#define BUS_TYPE_SCSI CDROM_BUS_SCSI +#define BUS_TYPE_BOTH -2 +#define BUS_TYPE_NONE -1 static const struct { - const char vendor[9]; - const char model[17]; - const char revision[5]; + const char vendor[9]; + const char model[17]; + const char revision[5]; const char *name; const char *internal_name; - const int bus_type; -} cdrom_drive_types[] = -{ - { "86BOX", "CD-ROM", "1.00", "(ATAPI/SCSI) 86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_ALL}, /*1*/ - { "AZT", "CDA46802I", "1.15", "(ATAPI) AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE}, /*2*/ - { "BTC", "CD-ROM BCD36XH", "U1.0", "(ATAPI) BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE}, /*3*/ - { "GOLDSTAR", "CRD-8160B", "3.14", "(ATAPI) GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE}, /*4*/ - { "HITACHI", "CDR-8130", "0020", "(ATAPI) HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE}, /*5*/ - { "KENWOOD", "CD-ROM UCR-421", "208E", "(ATAPI) KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE}, /*6*/ - { "MATSHITA", "CD-ROM CR-587", "7S13", "(ATAPI) MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE}, /*7*/ - { "MATSHITA", "CD-ROM CR-588", "LS15", "(ATAPI) MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE}, /*8*/ - { "MATSHITA", "CR-571", "1.0e", "(ATAPI) MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE}, /*9*/ - { "MATSHITA", "CR-572", "1.0j", "(ATAPI) MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE}, /*10*/ - { "MITSUMI", "CRMC-FX4820T", "D02A", "(ATAPI) MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE}, /*11*/ - { "NEC", "CD-ROM DRIVE:260", "1.00", "(ATAPI) NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE}, /*12*/ - { "NEC", "CD-ROM DRIVE:260", "1.01", "(ATAPI) NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE}, /*13*/ - { "NEC", "CD-ROM DRIVE:273", "4.20", "(ATAPI) NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE}, /*14*/ - { "NEC", "CD-ROM DRIVE:280", "1.05", "(ATAPI) NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE}, /*15*/ - { "NEC", "CD-ROM DRIVE:280", "3.08", "(ATAPI) NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE}, /*16*/ - { "PHILIPS", "CD-ROM PCA403CD", "U31P", "(ATAPI) PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE}, /*17*/ - { "SONY", "CD-ROM CDU76", "1.0i", "(ATAPI) SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE}, /*18*/ - { "SONY", "CD-ROM CDU311", "3.0h", "(ATAPI) SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE}, /*19*/ - { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "(ATAPI) TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE}, /*20*/ - { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "(ATAPI) TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE}, /*21*/ - { "CHINON", "CD-ROM CDS-431", "H42 ", "(SCSI) CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI}, /*22*/ - { "DEC", "RRD45 (C) DEC", "0436", "(SCSI) DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI}, /*23*/ - { "MATSHITA", "CD-ROM CR-501", "1.0b", "(SCSI) MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI}, /*24*/ - { "NEC", "CD-ROM DRIVE:74", "1.00", "(SCSI) NEC CD-ROM DRIVE:74 1.00", "NEC_CD-ROM_DRIVE74_1.00", BUS_TYPE_SCSI}, /*25*/ - { "NEC", "CD-ROM DRIVE:464", "1.05", "(SCSI) NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI}, /*26*/ - { "SONY", "CD-ROM CDU-541", "1.0i", "(SCSI) SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI}, /*27*/ - { "SONY", "CD-ROM CDU-76S", "1.00", "(SCSI) SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI}, /*28*/ - { "PHILIPS", "CDD2600", "1.07", "(SCSI) PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI}, /*29*/ - { "PIONEER", "CD-ROM DRM-604X", "2403", "(SCSI) PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI}, /*30*/ - { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "(SCSI) PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI}, /*31*/ - { "TEAC", "CD-R55S", "1.0R", "(SCSI) TEAC CD-R55S 1.0R", "TEAC_CD-R55S_1.0R", BUS_TYPE_SCSI}, /*32*/ - { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "(SCSI) TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI}, /*33*/ - { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "(SCSI) TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI}, /*34*/ - { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "(SCSI) TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI}, /*35*/ - { "", "", "", "", "", -1}, + const int bus_type; +} cdrom_drive_types[] = { + { "86BOX", "CD-ROM", "1.00", "86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_BOTH }, + { "AZT", "CDA46802I", "1.15", "AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE }, + { "BTC", "CD-ROM BCD36XH", "U1.0", "BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE }, + { "GOLDSTAR", "CRD-8160B", "3.14", "GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE }, + { "HITACHI", "CDR-8130", "0020", "HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE }, + { "KENWOOD", "CD-ROM UCR-421", "208E", "KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE }, + { "MATSHITA", "CD-ROM CR-587", "7S13", "MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE }, + { "MATSHITA", "CD-ROM CR-588", "LS15", "MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE }, + { "MATSHITA", "CR-571", "1.0e", "MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE }, + { "MATSHITA", "CR-572", "1.0j", "MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE }, + { "MITSUMI", "CRMC-FX4820T", "D02A", "MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE }, + { "NEC", "CD-ROM DRIVE:260", "1.00", "NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE }, + { "NEC", "CD-ROM DRIVE:260", "1.01", "NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE }, + { "NEC", "CD-ROM DRIVE:273", "4.20", "NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE }, + { "NEC", "CD-ROM DRIVE:280", "1.05", "NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE }, + { "NEC", "CD-ROM DRIVE:280", "3.08", "NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE }, + { "PHILIPS", "CD-ROM PCA403CD", "U31P", "PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE }, + { "SONY", "CD-ROM CDU76", "1.0i", "SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE }, + { "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE }, + { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE }, + { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE }, + { "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, + { "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, + { "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:25", "1.0a", "NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:38", "1.00", "NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:75", "1.03", "NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:77", "1.06", "NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, + { "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, + { "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, + { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, + { "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, + { "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, + { "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, + { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, + { "", "", "", "", "", BUS_TYPE_NONE }, }; /* To shut up the GCC compilers. */ struct cdrom; -typedef struct { - uint8_t attr, track, - index, - abs_m, abs_s, abs_f, - rel_m, rel_s, rel_f; +typedef struct subchannel_t { + uint8_t attr; + uint8_t track; + uint8_t index; + uint8_t abs_m; + uint8_t abs_s; + uint8_t abs_f; + uint8_t rel_m; + uint8_t rel_s; + uint8_t rel_f; } subchannel_t; -typedef struct { +typedef struct track_info_t { int number; - uint8_t attr, m, s, f; + uint8_t attr; + uint8_t m; + uint8_t s; + uint8_t f; } track_info_t; /* Define the various CD-ROM drive operations (ops). */ -typedef struct { +typedef struct cdrom_ops_t { void (*get_tracks)(struct cdrom *dev, int *first, int *last); void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); @@ -144,39 +210,49 @@ typedef struct cdrom { uint8_t id; union { - uint8_t res, res0, /* Reserved for other ID's. */ - res1, - ide_channel, scsi_device_id; + uint8_t res; + uint8_t res0; /* Reserved for other ID's. */ + uint8_t res1; + uint8_t ide_channel; + uint8_t scsi_device_id; }; - uint8_t bus_type, /* 0 = ATAPI, 1 = SCSI */ - bus_mode, /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - cd_status, /* Struct variable reserved for - media status. */ - speed, cur_speed; + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + uint8_t cd_status; /* Struct variable reserved for + media status. */ + uint8_t speed; + uint8_t cur_speed; int is_dir; void *priv; - char image_path[1024], - prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; char *image_history[CD_IMAGE_HISTORY]; - uint32_t sound_on, cdrom_capacity, - seek_pos, - seek_diff, cd_end, type; + uint32_t sound_on; + uint32_t cdrom_capacity; + uint32_t seek_pos; + uint32_t seek_diff; + uint32_t cd_end; + uint32_t type; - int host_drive, prev_host_drive, - cd_buflen, audio_op; + int host_drive; + int prev_host_drive; + int cd_buflen; + int audio_op; + int audio_muted_soft; + int sony_msf; const cdrom_ops_t *ops; void *image; - void (*insert)(void *p); - void (*close)(void *p); + void (*insert)(void *priv); + void (*close)(void *priv); uint32_t (*get_volume)(void *p, int channel); uint32_t (*get_channel)(void *p, int channel); @@ -199,12 +275,16 @@ extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba); extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len); extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf); extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit); +extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit); +extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos); extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type); extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume); extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type); +extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf); extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf); +extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len); @@ -227,6 +307,10 @@ extern int cdrom_image_open(cdrom_t *dev, const char *fn); extern void cdrom_image_close(cdrom_t *dev); extern void cdrom_image_reset(cdrom_t *dev); +extern void cdrom_ioctl_eject(void); +extern void cdrom_ioctl_load(void); +extern int cdrom_ioctl_open(cdrom_t *dev, const char d); + extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index 511ca68eb3..39faf9f33d 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -45,25 +45,32 @@ typedef struct SMSF { } TMSF; /* Track file struct. */ -typedef struct { - int (*read)(void *p, uint8_t *buffer, uint64_t seek, size_t count); - uint64_t (*get_length)(void *p); - void (*close)(void *p); +typedef struct track_file_t { + int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count); + uint64_t (*get_length)(void *priv); + void (*close)(void *priv); char fn[260]; - FILE *file; + FILE *fp; void *priv; } track_file_t; -typedef struct { - int number, track_number, attr, sector_size, - mode2, form, pre, pad; - uint64_t start, length, - skip; +typedef struct track_t { + int number; + int track_number; + int attr; + int sector_size; + int mode2; + int form; + int pre; + int pad; + uint64_t start; + uint64_t length; + uint64_t skip; track_file_t *file; } track_t; -typedef struct { +typedef struct cd_img_t { int tracks_num; track_t *tracks; } cd_img_t; @@ -90,9 +97,9 @@ extern int cdi_has_data_track(cd_img_t *cdi); extern int cdi_has_audio_track(cd_img_t *cdi); /* Virtual ISO functions. */ -extern int viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count); -extern uint64_t viso_get_length(void *p); -extern void viso_close(void *p); +extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count); +extern uint64_t viso_get_length(void *priv); +extern void viso_close(void *priv); extern track_file_t *viso_init(const char *dirname, int *error); #endif /*CDROM_IMAGE_BACKEND_H*/ diff --git a/src/include/86box/cdrom_interface.h b/src/include/86box/cdrom_interface.h index 860a436e00..081f758f6c 100644 --- a/src/include/86box/cdrom_interface.h +++ b/src/include/86box/cdrom_interface.h @@ -1,18 +1,18 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * Definitions for the common CD-ROM interface controller handler. + * Definitions for the common CD-ROM interface controller handler. * * * - * Authors: TheCollector1995 + * Authors: TheCollector1995 * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #ifndef EMU_CDROM_INTERFACE_H #define EMU_CDROM_INTERFACE_H @@ -21,7 +21,7 @@ extern int cdrom_interface_current; extern void cdrom_interface_reset(void); -extern char *cdrom_interface_get_internal_name(int cdinterface); +extern const char *cdrom_interface_get_internal_name(int cdinterface); extern int cdrom_interface_get_from_internal_name(char *s); extern int cdrom_interface_has_config(int cdinterface); extern const device_t *cdrom_interface_get_device(int cdinterface); diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 9d6bd64cfb..d5a96baf94 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -36,6 +36,9 @@ extern const device_t ali6117d_device; /* AMD */ extern const device_t amd640_device; +/* Compaq */ +extern const device_t compaq_386_device; + /* Contaq/Cypress */ extern const device_t contaq_82c596a_device; extern const device_t contaq_82c597_device; @@ -108,6 +111,8 @@ extern const device_t opti283_device; extern const device_t opti291_device; extern const device_t opti493_device; extern const device_t opti495_device; +extern const device_t opti601_device; +extern const device_t opti602_device; extern const device_t opti802g_device; extern const device_t opti802g_pci_device; extern const device_t opti822_device; @@ -125,8 +130,16 @@ extern const device_t sis_85c471_device; extern const device_t sis_85c496_device; extern const device_t sis_85c496_ls486e_device; extern const device_t sis_85c50x_device; +extern const device_t sis_550x_85c503_device; +extern const device_t sis_85c50x_5503_device; +extern const device_t sis_550x_device; extern const device_t sis_5511_device; extern const device_t sis_5571_device; +extern const device_t sis_5581_device; +extern const device_t sis_5591_1997_device; +extern const device_t sis_5591_device; +extern const device_t sis_5600_1997_device; +extern const device_t sis_5600_device; /* ST */ extern const device_t stpc_client_device; @@ -139,6 +152,8 @@ extern const device_t stpc_lpt_device; /* UMC */ extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; +extern const device_t umc_8886bf_device; +extern const device_t umc_8890_device; extern const device_t umc_hb4_device; /* VIA */ @@ -169,6 +184,8 @@ extern const device_t vlsi_scamp_device; extern const device_t wd76c10_device; /* Miscellaneous Hardware */ +extern const device_t nec_mate_unk_device; + extern const device_t phoenix_486_jumper_device; extern const device_t phoenix_486_jumper_pci_device; diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 9738b049b6..80c987162e 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -27,110 +27,110 @@ extern "C" { #endif #if 0 -typedef struct { - uint8_t id, - uint8_t bus_type, /* Bus type: IDE, SCSI, etc. */ - bus, : 4, /* ID of the bus (for example, for IDE, - 0 = primary, 1 = secondary, etc. */ - bus_id, : 4, /* ID of the device on the bus */ - uint8_t type, /* Type flags, interpretation depends - on the device */ - uint8_t is_image; /* This is only used for CD-ROM: - 0 = Image; - 1 = Host drive */ +typedef struct storage_cfg_t { + uint8_t id; + uint8_t bus_type; /* Bus type: IDE, SCSI, etc. */ + uint8_t bus : 4; /* ID of the bus (for example, for IDE, + 0 = primary, 1 = secondary, etc. */ + uint8_t bus_id : 4; /* ID of the device on the bus */ + uint8_t type; /* Type flags, interpretation depends + on the device */ + uint8_t is_image; /* This is only used for CD-ROM: + 0 = Image; + 1 = Host drive */ wchar_t path[1024]; /* Name of current image file or - host drive */ + host drive */ - uint32_t spt, /* Physical geometry parameters */ - hpc, - tracks; + uint32_t spt; /* Physical geometry parameters */ + uint32_t hpc; + uint32_t tracks; } storage_cfg_t; -typedef struct { +typedef struct config_t { /* General configuration */ - int vid_resize, /* Window is resizable or not */ - vid_renderer, /* Renderer */ - vid_fullscreen_scale, /* Full screen scale type */ - vid_fullscreen_start, /* Start emulator in full screen */ - vid_force_43, /* Force 4:3 display ratio in windowed mode */ - vid_scale, /* Windowed mode scale */ - vid_overscan, /* EGA/(S)VGA overscan enabled */ - vid_cga_contrast, /* CGA alternate contrast enabled */ - vid_grayscale, /* Video is grayscale */ - vid_grayscale_type, /* Video grayscale type */ - vid_invert_display, /* Invert display */ - rctrl_is_lalt, /* Right CTRL is left ALT */ - update_icons, /* Update status bar icons */ - window_remember, /* Remember window position and size */ - window_w, /* Window coordinates */ - window_h, - window_x, - window_y, - sound_gain; /* Sound gain */ + int vid_resize; /* Window is resizable or not */ + int vid_renderer; /* Renderer */ + int vid_fullscreen_scale; /* Full screen scale type */ + int vid_fullscreen_start; /* Start emulator in full screen */ + int vid_force_43; /* Force 4:3 display ratio in windowed mode */ + int vid_scale; /* Windowed mode scale */ + int vid_overscan; /* EGA/(S)VGA overscan enabled */ + int vid_cga_contrast; /* CGA alternate contrast enabled */ + int vid_grayscale; /* Video is grayscale */ + int vid_grayscale_type; /* Video grayscale type */ + int vid_invert_display; /* Invert display */ + int rctrl_is_lalt; /* Right CTRL is left ALT */ + int update_icons; /* Update status bar icons */ + int window_remember; /* Remember window position and size */ + int window_w; /* Window coordinates */ + int window_h; + int window_x; + int window_y; + int sound_gain; /* Sound gain */ # ifdef USE_LANGUAGE - uint16_t language_id; /* Language ID (0x0409 = English (US)) */ + uint16_t language_id; /* Language ID (0x0409 = English (US)) */ # endif /* Machine cateogory */ - int machine, /* Machine */ - cpu, /* CPU */ + int machine; /* Machine */ + int cpu; /* CPU */ # ifdef USE_DYNAREC - cpu_use_dynarec, /* CPU recompiler enabled */ + int cpu_use_dynarec; /* CPU recompiler enabled */ # endif - wait_states, /* CPU wait states */ - enable_external_fpu, /* FPU enabled */ - time_sync; /* Time sync enabled */ - uint32_t mem_size; /* Memory size */ + int wait_states; /* CPU wait states */ + int enable_external_fpu; /* FPU enabled */ + int time_sync; /* Time sync enabled */ + uint32_t mem_size; /* Memory size */ /* Video category */ - int video_card, /* Video card */ - voodoo_enabled; /* Voodoo enabled */ + int video_card; /* Video card */ + int voodoo_enabled; /* Voodoo enabled */ /* Input devices category */ - int mouse_type, /* Mouse type */ - joystick_type; /* Joystick type */ + int mouse_type; /* Mouse type */ + int joystick_type; /* Joystick type */ /* Sound category */ - int sound_card, /* Sound card */ - midi_device, /* Midi device */ - mpu_401, /* Standalone MPU-401 enabled */ - ssi_2001_enabled, /* SSI-2001 enabled */ - game_blaster_enabled, /* Game blaster enabled */ - gus_enabled, /* Gravis Ultrasound enabled */ - opl_type, /* OPL emulation type */ - sound_is_float; /* Sound is 32-bit float or 16-bit integer */ + int sound_card; /* Sound card */ + int midi_device; /* Midi device */ + int mpu_401; /* Standalone MPU-401 enabled */ + int ssi_2001_enabled; /* SSI-2001 enabled */ + int game_blaster_enabled; /* Game blaster enabled */ + int gus_enabled; /* Gravis Ultrasound enabled */ + int opl_type; /* OPL emulation type */ + int sound_is_float; /* Sound is 32-bit float or 16-bit integer */ /* Network category */ - int network_type, /* Network type (SLiRP or PCap) */ - network_card; /* Network card */ - char network_host[520]; /* PCap device */ + int network_type; /* Network type (SLiRP or PCap) */ + int network_card; /* Network card */ + char network_host[520]; /* PCap device */ /* Ports category */ char parallel_devices[PARALLEL_MAX][32]; /* LPT device names */ # ifdef USE_SERIAL_DEVICES - char serial_devices[SERIAL_MAX][32]; /* Serial device names */ + char serial_devices[SERIAL_MAX][32]; /* Serial device names */ # endif /* Other peripherals category */ - int fdc_type, /* Floppy disk controller type */ - hdc, /* Hard disk controller */ - scsi_card, /* SCSI controller */ - ide_ter_enabled, /* Tertiary IDE controller enabled */ - ide_qua_enabled, /* Quaternary IDE controller enabled */ - bugger_enabled, /* ISA bugger device enabled */ - isa_rtc_type, /* ISA RTC card */ - isa_mem_type[ISAMEM_MAX]; /* ISA memory boards */ + int fdc_type; /* Floppy disk controller type */ + int hdc; /* Hard disk controller */ + int scsi_card; /* SCSI controller */ + int ide_ter_enabled; /* Tertiary IDE controller enabled */ + int ide_qua_enabled; /* Quaternary IDE controller enabled */ + int bugger_enabled; /* ISA bugger device enabled */ + int isa_rtc_type; /* ISA RTC card */ + int isa_mem_type[ISAMEM_MAX]; /* ISA memory boards */ /* Hard disks category */ - storage_cfg_t hdd[HDD_NUM]; /* Hard disk drives */ + storage_cfg_t hdd[HDD_NUM]; /* Hard disk drives */ /* Floppy drives category */ - storage_cfg_t fdd[FDD_NUM]; /* Floppy drives */ + storage_cfg_t fdd[FDD_NUM]; /* Floppy drives */ /* Other removable devices category */ - storage_cfg_t cdrom[CDROM_NUM], /* CD-ROM drives */ - storage_cfg_t rdisk[ZIP_NUM]; /* Removable disk drives */ + storage_cfg_t cdrom[CDROM_NUM]; /* CD-ROM drives */ + storage_cfg_t rdisk[ZIP_NUM]; /* Removable disk drives */ } config_t; #endif diff --git a/src/include/86box/ddma.h b/src/include/86box/ddma.h index ccc423d278..01c2e980d3 100644 --- a/src/include/86box/ddma.h +++ b/src/include/86box/ddma.h @@ -21,14 +21,13 @@ extern "C" { #endif -typedef struct -{ +typedef struct ddma_channel_t { uint16_t io_base; - int channel, enable; + int channel; + int enable; } ddma_channel_t; -typedef struct -{ +typedef struct ddma_t { ddma_channel_t channels[8]; } ddma_t; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 2390e51280..bd39a02e4a 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -41,39 +41,71 @@ #ifndef EMU_DEVICE_H #define EMU_DEVICE_H -#define CONFIG_END -1 -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_MIDI_OUT 4 -#define CONFIG_FNAME 5 -#define CONFIG_SPINNER 6 -#define CONFIG_HEX16 7 -#define CONFIG_HEX20 8 -#define CONFIG_MAC 9 -#define CONFIG_MIDI_IN 10 -#define CONFIG_BIOS 11 -#define CONFIG_SERPORT 12 +#define CONFIG_END -1 /* N/A */ + +#define CONFIG_SHIFT 4 + +#define CONFIG_TYPE_INT (0 << CONFIG_SHIFT) +#define CONFIG_TYPE_STRING (1 << CONFIG_SHIFT) +#define CONFIG_TYPE_HEX16 (2 << CONFIG_SHIFT) +#define CONFIG_TYPE_HEX20 (3 << CONFIG_SHIFT) +#define CONFIG_TYPE_MAC (4 << CONFIG_SHIFT) + +#define CONFIG_INT (0 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_BINARY (1 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_SELECTION (2 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MIDI_OUT (3 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_SPINNER (4 | CONFIG_TYPE_INT) /* config_get_int() */ +#define CONFIG_MIDI_IN (5 | CONFIG_TYPE_INT) /* config_get_int() */ + +#define CONFIG_STRING (0 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_FNAME (1 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_SERPORT (2 | CONFIG_TYPE_STRING) /* config_get_string() */ +#define CONFIG_BIOS (3 | CONFIG_TYPE_STRING) /* config_get_string() */ + +#define CONFIG_HEX16 (0 | CONFIG_TYPE_HEX16) /* config_get_hex16() */ + +#define CONFIG_HEX20 (0 | CONFIG_TYPE_HEX20) /* config_get_hex20() */ + +#define CONFIG_MAC (0 | CONFIG_TYPE_MAC) /* N/A */ + +#define CONFIG_SUBTYPE_MASK (CONFIG_IS_STRING - 1) + +#define CONFIG_DEP (16 << CONFIG_SHIFT) +#define CONFIG_TYPE_MASK (CONFIG_DEP - 1) + +// #define CONFIG_ONBOARD 256 /* only avaialble on the on-board variant */ +// #define CONFIG_STANDALONE 257 /* not available on the on-board variant */ enum { DEVICE_PCJR = 2, /* requires an IBM PCjr */ - DEVICE_AT = 4, /* requires an AT-compatible system */ - DEVICE_PS2 = 8, /* requires a PS/1 or PS/2 system */ - DEVICE_ISA = 0x10, /* requires the ISA bus */ - DEVICE_CBUS = 0x20, /* requires the C-BUS bus */ - DEVICE_MCA = 0x40, /* requires the MCA bus */ - DEVICE_EISA = 0x80, /* requires the EISA bus */ - DEVICE_VLB = 0x100, /* requires the PCI bus */ - DEVICE_PCI = 0x200, /* requires the VLB bus */ - DEVICE_AGP = 0x400, /* requires the AGP bus */ - DEVICE_AC97 = 0x800, /* requires the AC'97 bus */ - DEVICE_COM = 0x1000, /* requires a serial port */ - DEVICE_LPT = 0x2000, /* requires a parallel port */ - DEVICE_KBC = 0x4000, /* is a keyboard controller */ + DEVICE_XTKBC = 4, /* requires an XT-compatible keyboard controller */ + DEVICE_AT = 8, /* requires an AT-compatible system */ + DEVICE_ATKBC = 0x10, /* requires an AT-compatible keyboard controller */ + DEVICE_PS2 = 0x20, /* requires a PS/1 or PS/2 system */ + DEVICE_ISA = 0x40, /* requires the ISA bus */ + DEVICE_CBUS = 0x80, /* requires the C-BUS bus */ + DEVICE_PCMCIA = 0x100, /* requires the PCMCIA bus */ + DEVICE_MCA = 0x200, /* requires the MCA bus */ + DEVICE_HIL = 0x400, /* requires the HP HIL bus */ + DEVICE_EISA = 0x800, /* requires the EISA bus */ + DEVICE_AT32 = 0x1000, /* requires the Mylex AT/32 local bus */ + DEVICE_OLB = 0x2000, /* requires the OPTi local bus */ + DEVICE_VLB = 0x4000, /* requires the VLB bus */ + DEVICE_PCI = 0x8000, /* requires the PCI bus */ + DEVICE_CARDBUS = 0x10000, /* requires the CardBus bus */ + DEVICE_USB = 0x20000, /* requires the USB bus */ + DEVICE_AGP = 0x40000, /* requires the AGP bus */ + DEVICE_AC97 = 0x80000, /* requires the AC'97 bus */ + DEVICE_COM = 0x100000, /* requires a serial port */ + DEVICE_LPT = 0x200000, /* requires a parallel port */ + DEVICE_KBC = 0x400000, /* is a keyboard controller */ + DEVICE_ONBOARD = 0x20000000, /* is on-board */ DEVICE_EXTPARAMS = 0x40000000, /* accepts extended parameters */ + DEVICE_PIT = 0x80000000, /* device is a PIT */ + DEVICE_ALL = 0xffffffff /* match all devices */ }; @@ -86,36 +118,49 @@ enum { #define BIOS_INTERLEAVED_INVERT 8 #define BIOS_HIGH_BIT_INVERT 16 -typedef struct { +#define device_common_config_t \ + const char *name; \ + const char *description; \ + int type; \ + const char *default_string; \ + int default_int; \ + const char *file_filter; \ + const device_config_spinner_t spinner; \ + const device_config_selection_t selection[32] + +typedef struct device_config_selection_t { const char *description; int value; } device_config_selection_t; -typedef struct { - const char *name; - const char *internal_name; - int bios_type; - int files_no; - uint32_t local, size; - void *dev1, *dev2; - const char *files[9]; -} device_config_bios_t; - -typedef struct { +typedef struct device_config_spinner_t { int16_t min; int16_t max; int16_t step; } device_config_spinner_t; -typedef struct { - const char *name; - const char *description; - int type; - const char *default_string; - int default_int; - const char *file_filter; - const device_config_spinner_t spinner; - const device_config_selection_t selection[32]; +typedef struct _device_dep_config_ { + device_common_config_t; +} device_dep_config_t; + +typedef struct device_config_bios_t { + const char *name; + const char *internal_name; + int bios_type; + int files_no; + uint32_t local; + uint32_t size; + void *dev1; + void *dev2; + const char *files[9]; + /* Configuration options that depend on the device variant. + To prevent excessive nesting, there is no CONFIG_BIOS + option a dep_config struct */ + const device_dep_config_t *dep_config; +} device_config_bios_t; + +typedef struct _device_config_ { + device_common_config_t; const device_config_bios_t bios[32]; } device_config_t; @@ -133,8 +178,7 @@ typedef struct _device_ { void (*reset)(void *priv); union { int (*available)(void); - int (*poll)(int x, int y, int z, int b, double abs_x, double abs_y, void *priv); - void (*register_pci_slot)(int device, int type, int inta, int intb, int intc, int intd, void *priv); + int (*poll)(void *priv); }; void (*speed_changed)(void *priv); void (*force_redraw)(void *priv); @@ -142,7 +186,7 @@ typedef struct _device_ { const device_config_t *config; } device_t; -typedef struct { +typedef struct device_context_t { const device_t *dev; char name[2048]; int instance; @@ -153,40 +197,44 @@ extern "C" { #endif extern void device_init(void); -extern void device_set_context(device_context_t *c, const device_t *d, int inst); -extern void device_context(const device_t *d); -extern void device_context_inst(const device_t *d, int inst); +extern void device_set_context(device_context_t *c, const device_t *dev, int inst); +extern void device_context(const device_t *dev); +extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); extern void *device_add(const device_t *d); -extern void *device_add_parameters(const device_t *d, void *params); -extern void device_add_ex(const device_t *d, void *priv); -extern void device_add_ex_parameters(const device_t *d, void *priv, void *params); -extern void *device_add_inst(const device_t *d, int inst); -extern void *device_add_inst_parameters(const device_t *d, int inst, void *params); -extern void device_add_inst_ex(const device_t *d, void *priv, int inst); -extern void device_add_inst_ex_parameters(const device_t *d, void *priv, int inst, void *params); -extern void *device_cadd(const device_t *d, const device_t *cd); -extern void *device_cadd_parameters(const device_t *d, const device_t *cd, void *params); -extern void device_cadd_ex(const device_t *d, const device_t *cd, void *priv); -extern void device_cadd_ex_parameters(const device_t *d, const device_t *cd, void *priv, void *params); -extern void *device_cadd_inst(const device_t *d, const device_t *cd, int inst); -extern void *device_cadd_inst_parameters(const device_t *d, const device_t *cd, int inst, void *params); -extern void device_cadd_inst_ex(const device_t *d, const device_t *cd, void *priv, int inst); -extern void device_cadd_inst_ex_parameters(const device_t *d, const device_t *cd, void *priv, int inst, void *params); +extern void *device_add_linked(const device_t *d, void *priv); +extern void *device_add_parameters(const device_t *dev, void *params); +extern void device_add_ex(const device_t *dev, void *priv); +extern void device_add_ex_parameters(const device_t *dev, void *priv, void *params); +extern void *device_add_inst(const device_t *dev, int inst); +extern void *device_add_inst_parameters(const device_t *dev, int inst, void *params); +extern void device_add_inst_ex(const device_t *dev, void *priv, int inst); +extern void device_add_inst_ex_parameters(const device_t *dev, void *priv, int inst, void *params); +extern void *device_cadd(const device_t *dev, const device_t *cd); +extern void *device_cadd_parameters(const device_t *dev, const device_t *cd, void *params); +extern void device_cadd_ex(const device_t *dev, const device_t *cd, void *priv); +extern void device_cadd_ex_parameters(const device_t *dev, const device_t *cd, void *priv, void *params); +extern void *device_cadd_inst(const device_t *dev, const device_t *cd, int inst); +extern void *device_cadd_inst_parameters(const device_t *dev, const device_t *cd, int inst, void *params); +extern void device_cadd_inst_ex(const device_t *dev, const device_t *cd, void *priv, int inst); +extern void device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params); +extern void *device_get_common_priv(void); extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); -extern void *device_get_priv(const device_t *d); -extern int device_available(const device_t *d); -extern int device_poll(const device_t *d, int x, int y, int z, int b); -extern void device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd); +extern void *device_find_first_priv(uint32_t match_flags); +extern void *device_get_priv(const device_t *dev); +extern int device_available(const device_t *dev); +extern int device_poll(const device_t *dev); extern void device_speed_changed(void); extern void device_force_redraw(void); -extern void device_get_name(const device_t *d, int bus, char *name); -extern int device_has_config(const device_t *d); -extern const char *device_get_bios_file(const device_t *d, const char *internal_name, int file_no); +extern void device_get_name(const device_t *dev, int bus, char *name); +extern int device_has_config(const device_t *dev); +extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, int file_no); extern int device_is_valid(const device_t *, int m); +extern const device_t* device_context_get_device(void); + extern int device_get_config_int(const char *name); extern int device_get_config_int_ex(const char *s, int dflt_int); extern int device_get_config_hex16(const char *name); @@ -200,7 +248,7 @@ extern const char *device_get_config_string(const char *name); extern const int device_get_instance(void); #define device_get_config_bios device_get_config_string -extern char *device_get_internal_name(const device_t *d); +extern const char *device_get_internal_name(const device_t *dev); extern int machine_get_config_int(char *s); extern char *machine_get_config_string(char *s); diff --git a/src/include/86box/disksizes.h b/src/include/86box/disksizes.h index e47b82943a..b5cd1bc302 100644 --- a/src/include/86box/disksizes.h +++ b/src/include/86box/disksizes.h @@ -22,7 +22,7 @@ extern "C" { #endif -typedef struct { +typedef struct disk_size_t { int hole; int sides; int data_rate; @@ -40,10 +40,12 @@ typedef struct { static const disk_size_t disk_sizes[14] = { // clang-format off -// { 1, 1, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 250k 8" */ -// { 1, 2, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 500k 8" */ -// { 1, 1, 2, 1, 1, 77, 8, 3, 0, 1, 2, 2, 192 }, /* 616k 8" */ -// { 1, 2, 0, 1, 1, 77, 8, 3, 0, 1, 2, 2, 192 }, /* 1232k 8" */ +#if 0 + { 1, 1, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 250k 8" */ + { 1, 2, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 500k 8" */ + { 1, 1, 2, 1, 1, 77, 8, 3, 0, 1, 2, 2, 192 }, /* 616k 8" */ + { 1, 2, 0, 1, 1, 77, 8, 3, 0, 1, 2, 2, 192 }, /* 1232k 8" */ +#endif { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */ @@ -58,8 +60,10 @@ static const disk_size_t disk_sizes[14] = { { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */ { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 250 */ -// { 0, 8, 0, 0, 0, 963, 32, 2, 0, 0, 0, 0, 0 }, /* LS-120 */ -// { 0, 32, 0, 0, 0, 262, 56, 2, 0, 0, 0, 0, 0 } /* LS-240 */ +#if 0 + { 0, 8, 0, 0, 0, 963, 32, 2, 0, 0, 0, 0, 0 }, /* LS-120 */ + { 0, 32, 0, 0, 0, 262, 56, 2, 0, 0, 0, 0, 0 } /* LS-240 */ +#endif // clang-format on }; diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index 904d0b13bd..7ead53ba00 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -43,22 +43,37 @@ #define DMA_OVER 0x10000 #define DMA_VERIFY 0x20000 -typedef struct { - uint8_t m, mode, page, stat, - stat_rq, command, - ps2_mode, arb_level, - sg_command, sg_status, - ptr0, enabled, - ext_mode, page_l, - page_h, pad; - uint16_t cb, io_addr, - base, transfer_mode; - uint32_t ptr, ptr_cur, - addr, - ab, ac; - int cc, wp, - size, count, - eot; +typedef struct dma_t { + uint8_t m; + uint8_t mode; + uint8_t page; + uint8_t stat; + uint8_t stat_rq; + uint8_t command; + uint8_t ps2_mode; + uint8_t arb_level; + uint8_t sg_command; + uint8_t sg_status; + uint8_t ptr0; + uint8_t enabled; + uint8_t ext_mode; + uint8_t page_l; + uint8_t page_h; + uint8_t pad; + uint16_t cb; + uint16_t io_addr; + uint16_t base; + uint16_t transfer_mode; + uint32_t ptr; + uint32_t ptr_cur; + uint32_t addr; + uint32_t ab; + uint32_t ac; + int cc; + int wp; + int size; + int count; + int eot; } dma_t; extern dma_t dma[8]; diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 09678b2e52..09c9c45789 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -56,54 +56,102 @@ extern int fdc_type; #define FDC_FLAG_TER 0x2000 /* Is Tertiary */ #define FDC_FLAG_QUA 0x3000 /* Is Quaternary */ -typedef struct { - uint8_t dor, stat, command, processed_cmd, dat, st0, swap, dtl; - uint8_t swwp, disable_write, st5, st6, error; - uint8_t params[8], res[11]; +typedef struct fdc_t { + uint8_t dor; + uint8_t stat; + uint8_t command; + uint8_t processed_cmd; + uint8_t dat; + uint8_t st0; + uint8_t swap; + uint8_t dtl; + + uint8_t swwp; + uint8_t disable_write; + uint8_t st5; + uint8_t st6; + uint8_t error; + uint8_t config; + uint8_t pretrk; + uint8_t power_down; + + uint8_t head; + uint8_t lastdrive; + uint8_t sector; + uint8_t drive; + uint8_t rate; + uint8_t tc; + uint8_t pnum; + uint8_t ptot; + + uint8_t reset_stat; + uint8_t seek_dir; + uint8_t perp; + uint8_t format_state; + uint8_t format_n; + uint8_t step; + uint8_t noprec; + uint8_t data_ready; + + uint8_t paramstogo; + uint8_t enh_mode; + uint8_t dma; + uint8_t densel_polarity; + uint8_t densel_force; + uint8_t fifo; + uint8_t tfifo; + uint8_t fifobufpos; + + uint8_t drv2en; + uint8_t gap; + uint8_t enable_3f1; + uint8_t format_sectors; + uint8_t mfm; + uint8_t deleted; + uint8_t wrong_am; + uint8_t sc; + + uint8_t fintr; + uint8_t rw_drive; + + uint8_t lock; uint8_t specify[2]; - uint8_t config, pretrk; + + uint8_t res[11]; + + uint8_t eot[4]; + uint8_t rwc[4]; + uint8_t params[8]; uint8_t fifobuf[16]; + uint16_t pcn[4]; + uint16_t base_address; + uint16_t rw_track; + + int bit_rate; /* Should be 250 at start. */ + + int bitcell_period; + int boot_drive; + + int max_track; + int satisfying_sectors; + + int flags; + int interrupt; + + int irq; /* Should be 6 by default. */ + int dma_ch; /* Should be 2 by default. */ + + int drvrate[4]; - int head, sector, drive, lastdrive; - int pcn[4], eot[4]; - int rw_track, pos; - int pnum, ptot; - int rate, reset_stat; - int lock, perp; - int format_state, format_n; - int step, seek_dir; - int tc, noprec; - - int data_ready, inread; - int bitcell_period, enh_mode; - int rwc[4], drvrate[4]; - int boot_drive, dma; - int densel_polarity, densel_force; - int fifo, tfifo; - int fifobufpos, drv2en; - - int gap; - int enable_3f1, format_sectors; - int max_track, mfm; - int deleted, wrong_am; - int sc, satisfying_sectors; - int fintr, rw_drive; - - int flags, interrupt; - - int irq; /* Should be 6 by default. */ - int dma_ch; /* Should be 2 by default. */ - - int bit_rate; /* Should be 250 at start. */ - int paramstogo; - - sector_id_t read_track_sector, format_sector_id; + sector_id_t read_track_sector; + sector_id_t format_sector_id; uint64_t watchdog_count; - pc_timer_t timer, watchdog_timer; + pc_timer_t timer; + pc_timer_t watchdog_timer; } fdc_t; extern void fdc_remove(fdc_t *fdc); @@ -144,6 +192,7 @@ extern int fdc_get_compare_condition(fdc_t *fdc); extern int fdc_is_deleted(fdc_t *fdc); extern int fdc_is_sk(fdc_t *fdc); extern void fdc_set_wrong_am(fdc_t *fdc); +extern void fdc_set_power_down(fdc_t *fdc, uint8_t power_down); extern int fdc_get_drive(fdc_t *fdc); extern int fdc_get_perp(fdc_t *fdc); extern int fdc_get_format_n(fdc_t *fdc); diff --git a/src/include/86box/fdc_ext.h b/src/include/86box/fdc_ext.h index 106235658c..0d821ac119 100644 --- a/src/include/86box/fdc_ext.h +++ b/src/include/86box/fdc_ext.h @@ -35,7 +35,7 @@ extern const device_t fdc_monster_device; extern void fdc_card_init(void); -extern char *fdc_card_get_internal_name(int card); +extern const char *fdc_card_get_internal_name(int card); extern int fdc_card_get_from_internal_name(char *s); extern const device_t *fdc_card_getdevice(int card); extern int fdc_card_has_config(int card); diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index 7e9edd6245..0331f4fcc5 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -65,7 +65,7 @@ extern int fdd_get_from_internal_name(char *s); extern int fdd_current_track(int drive); -typedef struct { +typedef struct DRIVE { int id; void (*seek)(int drive, int track); @@ -136,7 +136,7 @@ typedef union { void fdd_calccrc(uint8_t byte, crc_t *crc_var); -typedef struct { +typedef struct d86f_handler_t { uint16_t (*disk_flags)(int drive); uint16_t (*side_flags)(int drive); void (*writeback)(int drive); @@ -162,7 +162,7 @@ extern const uint8_t xdf_physical_sectors[2][2]; extern const uint8_t xdf_gap3_sizes[2][2]; extern const uint16_t xdf_trackx_spos[2][8]; -typedef struct { +typedef struct xdf_id_t { uint8_t h; uint8_t r; } xdf_id_t; @@ -175,14 +175,14 @@ typedef union { extern const xdf_sector_t xdf_img_layout[2][2][46]; extern const xdf_sector_t xdf_disk_layout[2][2][38]; -typedef struct { +typedef struct sector_id_fields_t { uint8_t c; uint8_t h; uint8_t r; uint8_t n; } sector_id_fields_t; -typedef union { +typedef union sector_id_t { uint32_t dword; uint8_t byte_array[4]; sector_id_fields_t id; diff --git a/src/include/86box/fifo.h b/src/include/86box/fifo.h new file mode 100644 index 0000000000..e76189d8a0 --- /dev/null +++ b/src/include/86box/fifo.h @@ -0,0 +1,73 @@ +/* + * 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. + * + * FIFO infrastructure header. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#define FIFO(size) \ + typedef struct { \ + int start; \ + int end; \ + int trigger_len; \ + int len; \ + int empty; \ + int overrun; \ + int full; \ + int ready; \ + int d_empty; \ + int d_overrun; \ + int d_full; \ + int d_ready; \ + \ + void *priv; \ + \ + void (*d_empty_evt)(void *); \ + void (*d_overrun_evt)(void *); \ + void (*d_full_evt)(void *); \ + void (*d_ready_evt)(void *); \ + \ + uint8_t buf[size]; \ + } fifo## size ##_t; + +FIFO() + +FIFO(16) +#define fifo16_init() fifo_init(16) + +FIFO(64) +#define fifo64_init() fifo_init(64) + +extern int fifo_get_count(void *priv); +extern void fifo_write(uint8_t val, void *priv); +extern void fifo_write_evt(uint8_t val, void *priv); +extern uint8_t fifo_read(void *priv); +extern uint8_t fifo_read_evt(void *priv); +extern void fifo_clear_overrun(void *priv); +extern int fifo_get_full(void *priv); +extern int fifo_get_d_full(void *priv); +extern int fifo_get_empty(void *priv); +extern int fifo_get_d_empty(void *priv); +extern int fifo_get_overrun(void *priv); +extern int fifo_get_d_overrun(void *priv); +extern int fifo_get_ready(void *priv); +extern int fifo_get_d_ready(void *priv); +extern int fifo_get_trigger_len(void *priv); +extern void fifo_set_trigger_len(void *priv, int trigger_len); +extern void fifo_set_len(void *priv, int len); +extern void fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *)); +extern void fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *)); +extern void fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *)); +extern void fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *)); +extern void fifo_set_priv(void *priv, void *sub_priv); +extern void fifo_reset(void *priv); +extern void fifo_reset_evt(void *priv); +extern void fifo_close(void *priv); +extern void *fifo_init(int len); diff --git a/src/include/86box/fifo8.h b/src/include/86box/fifo8.h index 811f0522fe..9f88ec408f 100644 --- a/src/include/86box/fifo8.h +++ b/src/include/86box/fifo8.h @@ -1,7 +1,7 @@ #ifndef EMU_FIFO8_H #define EMU_FIFO8_H -typedef struct { +typedef struct Fifo8 { /* All fields are private */ uint8_t *data; uint32_t capacity; diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index f936954336..dfe19c654d 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[2][NCoef + 1]; /* output samples */ - static double x[2][NCoef + 1]; /* input samples */ + static double y[3][NCoef + 1]; /* output samples */ + static double x[3][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[2][SB16_NCoef]; +extern double low_fir_sb16_coef[3][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) { - static double x[2][2][SB16_NCoef + 1]; // input samples - static int pos[2] = { 0, 0 }; + static double x[3][2][SB16_NCoef + 1]; // input samples + static int pos[3] = { 0, 0 }; double out = 0.0; int n; diff --git a/src/include/86box/flash.h b/src/include/86box/flash.h index d161d416ba..6f0e1ff15c 100644 --- a/src/include/86box/flash.h +++ b/src/include/86box/flash.h @@ -60,4 +60,6 @@ extern const device_t sst_flash_49lf080_device; extern const device_t sst_flash_49lf016_device; extern const device_t sst_flash_49lf160_device; +extern const device_t amd_flash_29f020a_device; + #endif /*EMU_FLASH_H*/ diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 905130da03..d9c702394f 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,9 +24,22 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 +#define MAX_JOY_AXES 16 +#define MAX_JOY_BUTTONS 32 +#define MAX_JOY_POVS 4 + +#define JS_TYPE_NONE 0 +#define JS_TYPE_2AXIS_4BUTTON 1 +#define JS_TYPE_2AXIS_6BUTTON 2 +#define JS_TYPE_2AXIS_8BUTTON 3 +#define JS_TYPE_4AXIS_4BUTTON 4 +#define JS_TYPE_CH_FLIGHTSTICK_PRO 5 +#define JS_TYPE_SIDEWINDER_PAD 6 +#define JS_TYPE_THRUSTMASTER_FCS 7 + + #define POV_X 0x80000000 #define POV_Y 0x40000000 -#define SLIDER 0x20000000 #define AXIS_NOT_PRESENT -99999 @@ -34,70 +47,62 @@ #define GAMEPORT_SIO 0x1000000 -typedef struct { +typedef struct plat_joystick_t { char name[260]; - int a[8]; - int b[32]; - int p[4]; - int s[2]; + int a[MAX_JOY_AXES]; + int b[MAX_JOY_BUTTONS]; + int p[MAX_JOY_POVS]; struct { char name[260]; int id; - } axis[8]; + } axis[MAX_JOY_AXES]; struct { char name[260]; int id; - } button[32]; + } button[MAX_JOY_BUTTONS]; struct { char name[260]; int id; - } pov[4]; - - struct - { - char name[260]; - int id; - } slider[2]; + } pov[MAX_JOY_POVS]; int nr_axes; int nr_buttons; int nr_povs; - int nr_sliders; } plat_joystick_t; -typedef struct { - int axis[8]; - int button[32]; - int pov[4]; +typedef struct joystick_t { + int axis[MAX_JOY_AXES]; + int button[MAX_JOY_BUTTONS]; + int pov[MAX_JOY_POVS]; int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; + int axis_mapping[MAX_JOY_AXES]; + int button_mapping[MAX_JOY_BUTTONS]; + int pov_mapping[MAX_JOY_POVS][2]; } joystick_t; -typedef struct { +typedef struct joystick_if_t { const char *name; const char *internal_name; - void *(*init)(void); - void (*close)(void *p); - uint8_t (*read)(void *p); - void (*write)(void *p); - int (*read_axis)(void *p, int axis); - void (*a0_over)(void *p); + void *(*init)(void); + void (*close)(void *priv); + uint8_t (*read)(void *priv); + void (*write)(void *priv); + int (*read_axis)(void *priv, int axis); + void (*a0_over)(void *priv); - int axis_count, - button_count, - pov_count; + int axis_count; + int button_count; + int pov_count; int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; + const char *axis_names[MAX_JOY_AXES]; + const char *button_names[MAX_JOY_BUTTONS]; + const char *pov_names[MAX_JOY_POVS]; } joystick_if_t; #ifdef __cplusplus @@ -134,21 +139,34 @@ extern void joystick_init(void); extern void joystick_close(void); extern void joystick_process(void); -extern char *joystick_get_name(int js); -extern char *joystick_get_internal_name(int js); -extern int joystick_get_from_internal_name(char *s); -extern int joystick_get_max_joysticks(int js); -extern int joystick_get_axis_count(int js); -extern int joystick_get_button_count(int js); -extern int joystick_get_pov_count(int js); -extern char *joystick_get_axis_name(int js, int id); -extern char *joystick_get_button_name(int js, int id); -extern char *joystick_get_pov_name(int js, int id); +extern const char *joystick_get_name(int js); +extern const char *joystick_get_internal_name(int js); +extern int joystick_get_from_internal_name(char *s); +extern int joystick_get_max_joysticks(int js); +extern int joystick_get_axis_count(int js); +extern int joystick_get_button_count(int js); +extern int joystick_get_pov_count(int js); +extern const char *joystick_get_axis_name(int js, int id); +extern const char *joystick_get_button_name(int js, int id); +extern const char *joystick_get_pov_name(int js, int id); extern void gameport_update_joystick_type(void); extern void gameport_remap(void *priv, uint16_t address); extern void *gameport_add(const device_t *gameport_type); +extern const joystick_if_t joystick_2axis_2button; +extern const joystick_if_t joystick_2axis_4button; +extern const joystick_if_t joystick_3axis_2button; +extern const joystick_if_t joystick_3axis_4button; +extern const joystick_if_t joystick_4axis_4button; +extern const joystick_if_t joystick_2axis_6button; +extern const joystick_if_t joystick_2axis_8button; + +extern const joystick_if_t joystick_ch_flightstick_pro; + +extern const joystick_if_t joystick_sw_pad; + +extern const joystick_if_t joystick_tm_fcs; #ifdef __cplusplus } #endif diff --git a/src/include/86box/gdbstub.h b/src/include/86box/gdbstub.h index 8ac83f625f..c58a58bf51 100644 --- a/src/include/86box/gdbstub.h +++ b/src/include/86box/gdbstub.h @@ -24,31 +24,31 @@ #define GDBSTUB_MEM_AWATCH 32 enum { - GDBSTUB_EXEC = 0, - GDBSTUB_SSTEP, - GDBSTUB_BREAK, - GDBSTUB_BREAK_SW, - GDBSTUB_BREAK_HW, - GDBSTUB_BREAK_RWATCH, - GDBSTUB_BREAK_WWATCH, - GDBSTUB_BREAK_AWATCH + GDBSTUB_EXEC = 0, + GDBSTUB_SSTEP = 1, + GDBSTUB_BREAK = 2, + GDBSTUB_BREAK_SW = 3, + GDBSTUB_BREAK_HW = 4, + GDBSTUB_BREAK_RWATCH = 5, + GDBSTUB_BREAK_WWATCH = 6, + GDBSTUB_BREAK_AWATCH = 7 }; #ifdef USE_GDBSTUB -# define GDBSTUB_MEM_ACCESS(addr, access, width) \ - uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \ - if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63))) { \ - uint32_t gdbstub_addrs[width]; \ - for (int gdbstub_i = 0; gdbstub_i < width; gdbstub_i++) \ - gdbstub_addrs[gdbstub_i] = addr + gdbstub_i; \ - gdbstub_mem_access(gdbstub_addrs, access | width); \ +# define GDBSTUB_MEM_ACCESS(addr, access, width) \ + uint32_t gdbstub_page = (addr) >> MEM_GRANULARITY_BITS; \ + if (gdbstub_watch_pages[gdbstub_page >> 6] & (1ULL << (gdbstub_page & 63))) { \ + uint32_t gdbstub_addrs[(width)]; \ + for (int gdbstub_i = 0; gdbstub_i < (width); gdbstub_i++) \ + gdbstub_addrs[gdbstub_i] = (addr) + gdbstub_i; \ + gdbstub_mem_access(gdbstub_addrs, (access) | (width)); \ } -# define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) \ - uint32_t gdbstub_page = addr >> MEM_GRANULARITY_BITS; \ - if (gdbstub_watch_pages[gdbstub_page >> 6] & (1 << (gdbstub_page & 63))) \ - gdbstub_mem_access(addrs, access | width); +# define GDBSTUB_MEM_ACCESS_FAST(addrs, access, width) \ + uint32_t gdbstub_page = (addrs)[0] >> MEM_GRANULARITY_BITS; \ + if (gdbstub_watch_pages[gdbstub_page >> 6] & (1ULL << (gdbstub_page & 63))) \ + gdbstub_mem_access((addrs), (access) | (width)); extern int gdbstub_step, gdbstub_next_asap; extern uint64_t gdbstub_watch_pages[(((uint32_t) -1) >> (MEM_GRANULARITY_BITS + 6)) + 1]; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 4320d86e23..a3d562b628 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -60,16 +60,33 @@ extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ extern const device_t ide_pci_device; /* pci_ide */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ -extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ -extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ -extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ -extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ -extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ -extern const device_t ide_cmd646_device; /* CMD PCI-646 */ -extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ -extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ +extern const device_t ide_ali1489_device; /* ALi M1489 */ +extern const device_t ide_ali5213_device; /* ALi M5213 */ -extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ +extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ +extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ +extern const device_t ide_cmd640_vlb_pri_device; /* CMD PCI-640B VLB (Only primary channel) */ +extern const device_t ide_cmd640_vlb_pri_178_device; /* CMD PCI-640B VLB (Only primary channel) (Port 178h) */ +extern const device_t ide_cmd640_vlb_sec_device; /* CMD PCI-640B VLB (Only secondary channel) */ +extern const device_t ide_cmd640_vlb_sec_178_device; /* CMD PCI-640B VLB (Only secondary channel) (Port 178h) */ +extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ +extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ +extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ +extern const device_t ide_cmd640_pci_single_channel_sec_device; /* CMD PCI-640B PCI (Only secondary channel) */ +extern const device_t ide_cmd646_device; /* CMD PCI-646 */ +extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ +extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ + +extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ +extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ + +extern const device_t ide_um8673f_device; /* UMC UM8673F */ +extern const device_t ide_um8886af_device; /* UMC UM8886AF */ + +extern const device_t ide_w83769f_vlb_device; /* Winbond W83769F VLB */ +extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */ +extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */ +extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */ extern const device_t ide_ter_device; extern const device_t ide_ter_pnp_device; @@ -80,16 +97,14 @@ extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ extern const device_t xta_hd20_device; /* EuroPC internal */ extern const device_t xtide_device; /* xtide_xt */ -extern const device_t xtide_plus_device; /* xtide_xt_plus */ extern const device_t xtide_at_device; /* xtide_at */ -extern const device_t xtide_at_386_device; /* xtide_at_386 */ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ extern void hdc_init(void); extern void hdc_reset(void); -extern char *hdc_get_internal_name(int hdc); +extern const char *hdc_get_internal_name(int hdc); extern int hdc_get_from_internal_name(char *s); extern int hdc_has_config(int hdc); extern const device_t *hdc_get_device(int hdc); diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 5a3251a3fb..1f7a78c9f7 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -28,62 +28,124 @@ #define HDC_SECONDARY_BASE 0x0170 #define HDC_SECONDARY_SIDE 0x0376 #define HDC_SECONDARY_IRQ 15 -#define HDC_TERTIARY_BASE 0x0168 -#define HDC_TERTIARY_SIDE 0x036E -#define HDC_TERTIARY_IRQ 10 -#define HDC_QUATERNARY_BASE 0x01E8 -#define HDC_QUATERNARY_SIDE 0x03EE -#define HDC_QUATERNARY_IRQ 11 +#define HDC_TERTIARY_BASE 0x01E8 +#define HDC_TERTIARY_SIDE 0x03EE +#define HDC_TERTIARY_IRQ 11 +#define HDC_QUATERNARY_BASE 0x0168 +#define HDC_QUATERNARY_SIDE 0x036E +#define HDC_QUATERNARY_IRQ 10 enum { - IDE_NONE = 0, - IDE_HDD, - IDE_ATAPI + IDE_NONE = 0, /* Absent master or both. */ + IDE_HDD, /* Hard disk. */ + IDE_ATAPI, /* ATAPI device. */ + IDE_RESERVED, /* Reserved, do not use. */ + IDE_SHADOW, /* Shadow flag, do not assign on is own. */ + IDE_HDD_SHADOW, /* Shadow of a hard disk. */ + IDE_ATAPI_SHADOW /* Shadow of an ATAPI device. */ }; -#ifdef SCSI_DEVICE_H +typedef struct ide_tf_s { + union { + uint8_t cylprecomp; + uint8_t features; + }; + union { + uint8_t secount; + uint8_t phase; + }; + union { + uint16_t cylinder; + uint16_t request_length; + }; + union { + uint8_t atastat; + uint8_t status; + }; + uint8_t error; + uint8_t sector; + union { + uint8_t drvsel; + struct { + uint8_t head :4; + uint8_t pad :2; + uint8_t lba :1; + uint8_t pad0 :1; + }; + }; + uint32_t pos; +} ide_tf_t; + +#ifdef _TIMER_H_ typedef struct ide_s { - uint8_t selected, - atastat, error, - command, fdisk; - int type, board, - irqstat, service, - blocksize, blockcount, - hdd_num, channel, - pos, sector_pos, - lba, - reset, mdma_mode, - do_initial_read; - uint32_t secount, sector, - cylinder, head, - drive, cylprecomp, - cfg_spt, cfg_hpc, - lba_addr, tracks, - spt, hpc; + /* The rest. */ + uint8_t selected; + uint8_t command; + uint8_t head; + uint8_t pad; + int type; + int board; + int irqstat; + int service; + int blocksize; + int blockcount; + int hdd_num; + int channel; + int sector_pos; + int reset; + int mdma_mode; + int do_initial_read; + uint32_t drive; + uint32_t cfg_spt; + uint32_t cfg_hpc; + uint32_t lba_addr; + uint32_t tracks; + uint32_t spt; + uint32_t hpc; uint16_t *buffer; uint8_t *sector_buffer; pc_timer_t timer; + /* Task file. */ + ide_tf_t * tf; + /* Stuff mostly used by ATAPI */ +#ifdef SCSI_DEVICE_H scsi_common_t *sc; +#else + void * sc; +#endif int interrupt_drq; double pending_delay; - int (*get_max)(int ide_has_dma, int type); - int (*get_timings)(int ide_has_dma, int type); - void (*identify)(struct ide_s *ide, int ide_has_dma); - void (*stop)(scsi_common_t *sc); - void (*packet_command)(scsi_common_t *sc, uint8_t *cdb); - void (*device_reset)(scsi_common_t *sc); +#ifdef SCSI_DEVICE_H + int (*get_max)(int ide_has_dma, int type); + int (*get_timings)(int ide_has_dma, int type); + void (*identify)(struct ide_s *ide, int ide_has_dma); + void (*stop)(scsi_common_t *sc); + void (*packet_command)(scsi_common_t *sc, uint8_t *cdb); + void (*device_reset)(scsi_common_t *sc); uint8_t (*phase_data_out)(scsi_common_t *sc); - void (*command_stop)(scsi_common_t *sc); - void (*bus_master_error)(scsi_common_t *sc); + void (*command_stop)(scsi_common_t *sc); + void (*bus_master_error)(scsi_common_t *sc); +#else + void * get_max; + void * get_timings; + void * identify; + void * stop; + void * device_reset; + void * phase_data_out; + void * command_stop; + void * bus_master_error; +#endif } ide_t; +#ifdef EMU_HDC_H extern ide_t *ide_drives[IDE_NUM]; #endif +#endif /* Type: 0 = PIO, @@ -96,10 +158,10 @@ extern ide_t *ide_drives[IDE_NUM]; This will eventually be hookable. */ enum { - TYPE_PIO = 0, - TYPE_SDMA, - TYPE_MDMA, - TYPE_UDMA + TYPE_PIO = 0, + TYPE_SDMA = 1, + TYPE_MDMA = 2, + TYPE_UDMA = 3 }; /* Return: @@ -108,9 +170,9 @@ enum { This will eventually be hookable. */ enum { - TIMINGS_DMA = 0, - TIMINGS_PIO, - TIMINGS_PIO_FC + TIMINGS_DMA = 0, + TIMINGS_PIO = 1, + TIMINGS_PIO_FC = 2 }; extern int ide_ter_enabled; @@ -118,8 +180,7 @@ extern int ide_qua_enabled; #ifdef SCSI_DEVICE_H extern ide_t *ide_get_drive(int ch); -extern void ide_irq_raise(ide_t *ide); -extern void ide_irq_lower(ide_t *ide); +extern void ide_irq(ide_t *ide, int set, int log); extern void ide_allocate_buffer(ide_t *dev); extern void ide_atapi_attach(ide_t *dev); #endif @@ -127,6 +188,8 @@ extern void ide_atapi_attach(ide_t *dev); extern void *ide_xtide_init(void); extern void ide_xtide_close(void); +extern void ide_drives_set_shadow(void); + extern void ide_writew(uint16_t addr, uint16_t val, void *priv); extern void ide_write_devctl(uint16_t addr, uint8_t val, void *priv); extern void ide_writeb(uint16_t addr, uint8_t val, void *priv); @@ -135,22 +198,15 @@ extern uint8_t ide_read_alt_status(uint16_t addr, void *priv); extern uint16_t ide_readw(uint16_t addr, void *priv); extern void ide_set_bus_master(int board, - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), - void (*set_irq)(int channel, void *priv), void *priv); + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv), + void (*set_irq)(uint8_t status, void *priv), void *priv); extern void win_cdrom_eject(uint8_t id); extern void win_cdrom_reload(uint8_t id); -extern void ide_set_base(int board, uint16_t port); -extern void ide_set_side(int board, uint16_t port); - -extern void ide_set_handlers(uint8_t board); -extern void ide_remove_handlers(uint8_t board); +extern void ide_set_base_addr(int board, int base, uint16_t port); -extern void ide_pri_enable(void); -extern void ide_pri_disable(void); -extern void ide_sec_enable(void); -extern void ide_sec_disable(void); +extern void ide_handlers(uint8_t board, int set); extern void ide_board_set_force_ata3(int board, int force_ata3); #ifdef EMU_ISAPNP_H @@ -166,11 +222,22 @@ extern void ide_set_board_callback(uint8_t board, double callback); extern void ide_padstr(char *str, const char *src, int len); extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); -extern int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; - extern uint8_t ide_read_ali_75(void); extern uint8_t ide_read_ali_76(void); +/* Legacy #define's. */ +#define ide_irq_raise(ide) ide_irq(ide, 1, 1) +#define ide_irq_lower(ide) ide_irq(ide, 0, 1) + +#define ide_set_base(board, port) ide_set_base_addr(board, 0, port) +#define ide_set_side(board, port) ide_set_base_addr(board, 1, port) + +#define ide_pri_enable() ide_handlers(0, 1) +#define ide_pri_disable() ide_handlers(0, 0) +#define ide_sec_enable() ide_handlers(1, 1) +#define ide_sec_disable() ide_handlers(1, 0) + +#define ide_set_handlers(board) ide_handlers(board, 1) +#define ide_remove_handlers(board) ide_handlers(board, 0) + #endif /*EMU_IDE_H*/ diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index b411ecf5d6..3a69fdfac1 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -20,44 +20,62 @@ #ifndef EMU_HDC_IDE_SFF8038I_H #define EMU_HDC_IDE_SFF8038I_H -typedef struct +enum { - uint8_t command, status, - ptr0, enabled, - dma_mode, pad, - pad0, pad1; - uint16_t base, pad2; - uint32_t ptr, ptr_cur, - addr; - int count, eot, - slot, - irq_mode[2], irq_level[2], - irq_pin, irq_line; + IRQ_MODE_LEGACY = 0, + IRQ_MODE_PCI_IRQ_PIN, + IRQ_MODE_PCI_IRQ_LINE, + IRQ_MODE_ALI_ALADDIN, + IRQ_MODE_MIRQ_0, + IRQ_MODE_MIRQ_1, + IRQ_MODE_MIRQ_2, + IRQ_MODE_MIRQ_3, + IRQ_MODE_SIS_551X +}; + +typedef struct sff8038i_t +{ + uint8_t command; + uint8_t status; + uint8_t ptr0; + uint8_t enabled; + uint8_t dma_mode; + uint8_t irq_state; + uint8_t channel; + uint8_t irq_line; + uint8_t mirq; + uint16_t base; + uint16_t pad; + uint32_t ptr; + uint32_t ptr_cur; + uint32_t addr; + int count; + int eot; + int slot; + int irq_mode; + int irq_level; + int irq_pin; + int pci_irq_line; } sff8038i_t; extern const device_t sff8038i_device; extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base); -extern int sff_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); -extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); - -extern void sff_bus_master_set_irq(int channel, void *priv); - -extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv); +extern void sff_bus_master_set_irq(uint8_t status, void *priv); +extern int sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv); extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); extern uint8_t sff_bus_master_read(uint16_t port, void *priv); -extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base); +extern void sff_bus_master_reset(sff8038i_t *dev); extern void sff_set_slot(sff8038i_t *dev, int slot); extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); - -extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode); +extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); - -extern void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level); +extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); +extern void sff_set_mirq(sff8038i_t *dev, uint8_t mirq); #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 1508939bac..89a6cf1ffb 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -34,60 +34,60 @@ Bit 5 = Removable (0 = no, 1 yes). */ enum { - BUS_DISABLED = 0x00, + BUS_DISABLED = 0x00, - BUS_MFM = 0x01, /* These four are for hard disk only. */ - BUS_XIDE = 0x02, - BUS_XTA = 0x03, - BUS_ESDI = 0x04, + BUS_MFM = 0x01, /* These four are for hard disk only. */ + BUS_XIDE = 0x02, + BUS_XTA = 0x03, + BUS_ESDI = 0x04, - BUS_PANASONIC = 0x21, / These four are for CD-ROM only. */ - BUS_PHILIPS = 0x22, - BUS_SONY = 0x23, - BUS_MITSUMI = 0x24, + BUS_PANASONIC = 0x21, / These four are for CD-ROM only. */ + BUS_PHILIPS = 0x22, + BUS_SONY = 0x23, + BUS_MITSUMI = 0x24, - BUS_IDE_PIO_ONLY = 0x05, - BUS_IDE_PIO_AND_DMA = 0x15, - BUS_IDE_R_PIO_ONLY = 0x25, - BUS_IDE_R_PIO_AND_DMA = 0x35, + BUS_IDE_PIO_ONLY = 0x05, + BUS_IDE_PIO_AND_DMA = 0x15, + BUS_IDE_R_PIO_ONLY = 0x25, + BUS_IDE_R_PIO_AND_DMA = 0x35, - BUS_ATAPI_PIO_ONLY = 0x06, - BUS_ATAPI_PIO_AND_DMA = 0x16, - BUS_ATAPI_R_PIO_ONLY = 0x26, - BUS_ATAPI_R_PIO_AND_DMA = 0x36, + BUS_ATAPI_PIO_ONLY = 0x06, + BUS_ATAPI_PIO_AND_DMA = 0x16, + BUS_ATAPI_R_PIO_ONLY = 0x26, + BUS_ATAPI_R_PIO_AND_DMA = 0x36, - BUS_SASI = 0x07, - BUS_SASI_R = 0x27, + BUS_SASI = 0x07, + BUS_SASI_R = 0x27, - BUS_SCSI = 0x08, - BUS_SCSI_R = 0x28, + BUS_SCSI = 0x08, + BUS_SCSI_R = 0x28, - BUS_USB = 0x09, - BUS_USB_R = 0x29 + BUS_USB = 0x09, + BUS_USB_R = 0x29 }; #else enum { HDD_BUS_DISABLED = 0, - HDD_BUS_MFM, - HDD_BUS_XTA, - HDD_BUS_ESDI, - HDD_BUS_IDE, - HDD_BUS_ATAPI, - HDD_BUS_SCSI, - HDD_BUS_USB + HDD_BUS_MFM = 1, + HDD_BUS_XTA = 2, + HDD_BUS_ESDI = 3, + HDD_BUS_IDE = 4, + HDD_BUS_ATAPI = 5, + HDD_BUS_SCSI = 6, + HDD_BUS_USB = 7 }; #endif enum { - HDD_OP_SEEK = 0, - HDD_OP_READ, - HDD_OP_WRITE + HDD_OP_SEEK = 0, + HDD_OP_READ = 2, + HDD_OP_WRITE = 3 }; #define HDD_MAX_ZONES 16 #define HDD_MAX_CACHE_SEG 16 -typedef struct { +typedef struct hdd_preset_t { const char *name; const char *internal_name; uint32_t zones; @@ -101,7 +101,7 @@ typedef struct { double track_seek_ms; } hdd_preset_t; -typedef struct { +typedef struct hdd_cache_seg_t { uint32_t id; uint32_t lba_addr; uint32_t ra_addr; @@ -110,7 +110,7 @@ typedef struct { uint8_t valid; } hdd_cache_seg_t; -typedef struct { +typedef struct hdd_cache_t { // Read cache hdd_cache_seg_t segments[HDD_MAX_CACHE_SEG]; uint32_t num_segments; @@ -126,7 +126,7 @@ typedef struct { uint64_t write_start_time; } hdd_cache_t; -typedef struct { +typedef struct hdd_zone_t { uint32_t cylinders; uint32_t sectors_per_track; double sector_time_usec; @@ -136,7 +136,7 @@ typedef struct { } hdd_zone_t; /* Define the virtual Hard Disk. */ -typedef struct { +typedef struct hard_disk_t { uint8_t id; union { uint8_t channel; /* Needed for Settings to reduce the number of if's */ @@ -147,21 +147,24 @@ typedef struct { uint8_t ide_channel; uint8_t scsi_id; }; - uint8_t bus, - res; /* Reserved for bus mode */ + uint8_t bus; + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ uint8_t wp; /* Disk has been mounted READ-ONLY */ - uint8_t pad, pad0; + uint8_t pad; + uint8_t pad0; void *priv; char fn[1024]; /* Name of current image file */ char vhd_parent[1041]; /* Differential VHD parent file */ - uint32_t res0, pad1, - base, - spt, - hpc, /* Physical geometry parameters */ - tracks; + uint32_t seek_pos; + uint32_t seek_len; + uint32_t base; + uint32_t spt; + uint32_t hpc; /* Physical geometry parameters */ + uint32_t tracks; hdd_zone_t zones[HDD_MAX_ZONES]; uint32_t num_zones; diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index e0410b3a08..4ad5e6917d 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -20,20 +20,21 @@ #define RESISTOR_DIVIDER(v, r1, r2) (((v) * (r2)) / ((r1) + (r2))) -typedef struct { +typedef struct hwm_values_t { uint16_t fans[4]; uint8_t temperatures[4]; uint16_t voltages[13]; } hwm_values_t; -typedef struct { +typedef struct lm75_t { uint32_t local; hwm_values_t *values; void *as99127f; uint8_t regs[8]; uint8_t addr_register; - uint8_t i2c_addr : 7, i2c_state : 2; + uint8_t i2c_addr : 7; + uint8_t i2c_state : 2; uint8_t i2c_enabled : 1; } lm75_t; @@ -67,6 +68,8 @@ extern const device_t w83782d_device; extern const device_t gl518sm_2c_device; extern const device_t gl518sm_2d_device; +extern const device_t gl520sm_2c_device; +extern const device_t gl520sm_2d_device; extern const device_t via_vt82c686_hwm_device; diff --git a/src/include/86box/i8080.h b/src/include/86box/i8080.h index b5ba3c7a43..9a25b5d1bc 100644 --- a/src/include/86box/i8080.h +++ b/src/include/86box/i8080.h @@ -51,14 +51,14 @@ typedef struct i8080 { uint16_t oldpc; uint16_t ei; uint32_t pmembase; - uint32_t dmembase; /* Base from where i8080 starts. */ + uint32_t dmembase; /* Base from where i8080 starts. */ uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */ uint16_t *cpu_flags; - void (*writemembyte)(uint32_t, uint8_t); + void (*writemembyte)(uint32_t, uint8_t); uint8_t (*readmembyte)(uint32_t); - void (*startclock)(void); - void (*endclock)(void); - void (*checkinterrupts)(void); + void (*startclock)(void); + void (*endclock)(void); + void (*checkinterrupts)(void); uint8_t (*fetchinstruction)(void *); } i8080; diff --git a/src/include/86box/ini.h b/src/include/86box/ini.h index 866787352d..d52620f69f 100644 --- a/src/include/86box/ini.h +++ b/src/include/86box/ini.h @@ -37,6 +37,10 @@ extern void ini_close(ini_t ini); extern void ini_section_delete_var(ini_section_t section, const char *name); extern int ini_section_get_int(ini_section_t section, const char *name, int def); +extern uint32_t ini_section_get_uint(ini_section_t section, const char *name, uint32_t def); +#if 0 +extern float ini_section_get_float(ini_section_t section, const char *name, float def); +#endif extern double ini_section_get_double(ini_section_t section, const char *name, double def); extern int ini_section_get_hex16(ini_section_t section, const char *name, int def); extern int ini_section_get_hex20(ini_section_t section, const char *name, int def); @@ -44,6 +48,10 @@ extern int ini_section_get_mac(ini_section_t section, const char *name, int extern char *ini_section_get_string(ini_section_t section, const char *name, char *def); extern wchar_t *ini_section_get_wstring(ini_section_t section, const char *name, wchar_t *def); extern void ini_section_set_int(ini_section_t section, const char *name, int val); +extern void ini_section_set_uint(ini_section_t section, const char *name, uint32_t val); +#if 0 +extern void ini_section_set_float(ini_section_t section, const char *name, float val); +#endif extern void ini_section_set_double(ini_section_t section, const char *name, double val); extern void ini_section_set_hex16(ini_section_t section, const char *name, int val); extern void ini_section_set_hex20(ini_section_t section, const char *name, int val); @@ -54,6 +62,10 @@ extern void ini_section_set_wstring(ini_section_t section, const char *name, #define ini_delete_var(ini, head, name) ini_section_delete_var(ini_find_section(ini, head), name) #define ini_get_int(ini, head, name, def) ini_section_get_int(ini_find_section(ini, head), name, def) +#define ini_get_uint(ini, head, name, def) ini_section_get_uint(ini_find_section(ini, head), name, def) +#if 0 +#define ini_get_float(ini, head, name, def) ini_section_get_float(ini_find_section(ini, head), name, def) +#endif #define ini_get_double(ini, head, name, def) ini_section_get_double(ini_find_section(ini, head), name, def) #define ini_get_hex16(ini, head, name, def) ini_section_get_hex16(ini_find_section(ini, head), name, def) #define ini_get_hex20(ini, head, name, def) ini_section_get_hex20(ini_find_section(ini, head), name, def) @@ -62,6 +74,10 @@ extern void ini_section_set_wstring(ini_section_t section, const char *name, #define ini_get_wstring(ini, head, name, def) ini_section_get_wstring(ini_find_section(ini, head), name, def) #define ini_set_int(ini, head, name, val) ini_section_set_int(ini_find_or_create_section(ini, head), name, val) +#define ini_set_uint(ini, head, name, val) ini_section_set_uint(ini_find_or_create_section(ini, head), name, val) +#if 0 +#define ini_set_float(ini, head, name, val) ini_section_set_float(ini_find_or_create_section(ini, head), name, val) +#endif #define ini_set_double(ini, head, name, val) ini_section_set_double(ini_find_or_create_section(ini, head), name, val) #define ini_set_hex16(ini, head, name, val) ini_section_set_hex16(ini_find_or_create_section(ini, head), name, val) #define ini_set_hex20(ini, head, name, val) ini_section_set_hex20(ini_find_or_create_section(ini, head), name, val) diff --git a/src/include/86box/isapnp.h b/src/include/86box/isapnp.h index 9fff876dc2..5e48b7c186 100644 --- a/src/include/86box/isapnp.h +++ b/src/include/86box/isapnp.h @@ -25,42 +25,50 @@ #define ISAPNP_DMA_DISABLED 4 enum { - ISAPNP_CARD_DISABLE = 0, - ISAPNP_CARD_ENABLE = 1, - ISAPNP_CARD_FORCE_CONFIG, /* cheat code for UMC UM8669F */ - ISAPNP_CARD_NO_KEY /* cheat code for Crystal CS423x */ + ISAPNP_CARD_DISABLE = 0, + ISAPNP_CARD_ENABLE = 1, + ISAPNP_CARD_FORCE_CONFIG = 2, /* cheat code for UMC UM8669F */ + ISAPNP_CARD_NO_KEY = 3 /* cheat code for Crystal CS423x */ }; -typedef struct { +typedef struct isapnp_device_config_t { uint8_t activate; - struct { - uint32_t base : 24, size : 24; + struct pnp_mem_t { + uint32_t base : 24; + uint32_t size : 24; } mem[4]; - struct { - uint32_t base, size; + struct pnp_mem32_t { + uint32_t base; + uint32_t size; } mem32[4]; - struct { + struct pnp_io_t { uint16_t base; } io[8]; - struct { - uint8_t irq : 4, level : 1, type : 1; + struct pnp_irq_t { + uint8_t irq : 4; + uint8_t level : 1; + uint8_t type : 1; } irq[2]; - struct { + struct pnp_dma_t { uint8_t dma : 3; } dma[2]; } isapnp_device_config_t; -void *isapnp_add_card(uint8_t *rom, uint16_t rom_size, - void (*config_changed)(uint8_t ld, isapnp_device_config_t *config, void *priv), - void (*csn_changed)(uint8_t csn, void *priv), - uint8_t (*read_vendor_reg)(uint8_t ld, uint8_t reg, void *priv), - void (*write_vendor_reg)(uint8_t ld, uint8_t reg, uint8_t val, void *priv), - void *priv); -void isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size); -void isapnp_enable_card(void *priv, uint8_t enable); -void isapnp_set_csn(void *priv, uint8_t csn); -void isapnp_set_device_defaults(void *priv, uint8_t ldn, const isapnp_device_config_t *config); -void isapnp_reset_card(void *priv); -void isapnp_reset_device(void *priv, uint8_t ld); +extern const uint8_t isapnp_init_key[32]; + +void *isapnp_add_card(uint8_t *rom, uint16_t rom_size, + void (*config_changed)(uint8_t ld, isapnp_device_config_t *config, void *priv), + void (*csn_changed)(uint8_t csn, void *priv), + uint8_t (*read_vendor_reg)(uint8_t ld, uint8_t reg, void *priv), + void (*write_vendor_reg)(uint8_t ld, uint8_t reg, uint8_t val, void *priv), + void *priv); +void isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size); +void isapnp_enable_card(void *priv, uint8_t enable); +void isapnp_set_csn(void *priv, uint8_t csn); +uint8_t isapnp_read_reg(void *priv, uint8_t ldn, uint8_t reg); +void isapnp_write_reg(void *priv, uint8_t ldn, uint8_t reg, uint8_t val); +void isapnp_set_device_defaults(void *priv, uint8_t ldn, const isapnp_device_config_t *config); +void isapnp_reset_card(void *priv); +void isapnp_reset_device(void *priv, uint8_t ld); #endif /*EMU_ISAPNP_H*/ diff --git a/src/include/86box/isartc.h b/src/include/86box/isartc.h index d619d3052f..92c58e3506 100644 --- a/src/include/86box/isartc.h +++ b/src/include/86box/isartc.h @@ -55,7 +55,7 @@ extern "C" { /* Functions. */ extern void isartc_reset(void); -extern char *isartc_get_internal_name(int t); +extern const char *isartc_get_internal_name(int t); extern int isartc_get_from_internal_name(char *s); extern const device_t *isartc_get_device(int t); diff --git a/src/include/86box/joystick_ch_flightstick_pro.h b/src/include/86box/joystick_ch_flightstick_pro.h deleted file mode 100644 index b49800ecb1..0000000000 --- a/src/include/86box/joystick_ch_flightstick_pro.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Flight Stick Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H -#define EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H - -extern const joystick_if_t joystick_ch_flightstick_pro; - -#endif /*EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H*/ diff --git a/src/include/86box/joystick_standard.h b/src/include/86box/joystick_standard.h deleted file mode 100644 index c874677ea2..0000000000 --- a/src/include/86box/joystick_standard.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Definitions for the joystick driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_STANDARD_H -#define EMU_JOYSTICK_STANDARD_H - -extern const joystick_if_t joystick_2axis_2button; -extern const joystick_if_t joystick_2axis_4button; -extern const joystick_if_t joystick_3axis_2button; -extern const joystick_if_t joystick_3axis_4button; -extern const joystick_if_t joystick_4axis_4button; -extern const joystick_if_t joystick_2axis_6button; -extern const joystick_if_t joystick_2axis_8button; - -#endif /*EMU_JOYSTICK_STANDARD_H*/ diff --git a/src/include/86box/joystick_sw_pad.h b/src/include/86box/joystick_sw_pad.h deleted file mode 100644 index a75d802deb..0000000000 --- a/src/include/86box/joystick_sw_pad.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Sidewinder Pro driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_SW_PAD_H -#define EMU_JOYSTICK_SW_PAD_H - -extern const joystick_if_t joystick_sw_pad; - -#endif /*EMU_JOYSTICK_SW_PAD_H*/ diff --git a/src/include/86box/joystick_tm_fcs.h b/src/include/86box/joystick_tm_fcs.h deleted file mode 100644 index 65e734a407..0000000000 --- a/src/include/86box/joystick_tm_fcs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - * - * Definitions for the Flight Control System driver. - * - * - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -#ifndef EMU_JOYSTICK_TM_FCS_H -#define EMU_JOYSTICK_TM_FCS_H - -extern const joystick_if_t joystick_tm_fcs; - -#endif /*EMU_JOYSTICK_TM_FCS_H*/ diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 4a1c04892b..759fad714d 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -24,38 +24,46 @@ enum { DEV_KBD = 0, - DEV_AUX + DEV_AUX = 1 }; enum { - DEV_STATE_MAIN_1 = 0, - DEV_STATE_MAIN_OUT, - DEV_STATE_MAIN_2, - DEV_STATE_MAIN_CMD, - DEV_STATE_MAIN_WANT_IN, - DEV_STATE_MAIN_IN, - DEV_STATE_EXECUTE_BAT, - DEV_STATE_MAIN_WANT_EXECUTE_BAT + DEV_STATE_MAIN_1 = 0, + DEV_STATE_MAIN_OUT = 1, + DEV_STATE_MAIN_2 = 2, + DEV_STATE_MAIN_CMD = 3, + DEV_STATE_MAIN_WANT_IN = 4, + DEV_STATE_MAIN_IN = 5, + DEV_STATE_EXECUTE_BAT = 6, + DEV_STATE_MAIN_WANT_EXECUTE_BAT = 7 }; /* Used by the AT / PS/2 keyboard controller, common device, keyboard, and mouse. */ -typedef struct { - uint8_t wantcmd, dat; +typedef struct kbc_at_port_t { + uint8_t wantcmd; + uint8_t dat; int16_t out_new; void *priv; - void (*poll)(void *priv); + void (*poll)(void *priv); } kbc_at_port_t; /* Used by the AT / PS/2 common device, keyboard, and mouse. */ -typedef struct { +typedef struct atkbc_dev_t { const char *name; /* name of this device */ - uint8_t type, command, last_scan_code, state, - resolution, rate, cmd_queue_start, cmd_queue_end, - queue_start, queue_end; + uint8_t type; + uint8_t command; + uint8_t last_scan_code; + uint8_t state; + uint8_t resolution; + uint8_t rate; + uint8_t cmd_queue_start; + uint8_t cmd_queue_end; + uint8_t queue_start; + uint8_t queue_end; uint16_t flags; @@ -65,8 +73,13 @@ typedef struct { uint8_t queue[64]; - int fifo_mask, mode, - x, y, z, b; + int fifo_mask; + int mode; + int x; + int y; + int z; + int b; + int ignore; int *scan; @@ -76,7 +89,7 @@ typedef struct { kbc_at_port_t *port; } atkbc_dev_t; -typedef struct { +typedef struct scancode { const uint8_t mk[4]; const uint8_t brk[4]; } scancode; @@ -214,13 +227,16 @@ extern const device_t keyboard_xt_lxt3_device; # endif /*defined(DEV_BRANCH) && defined(USE_LASERXT) */ extern const device_t keyboard_xt_olivetti_device; extern const device_t keyboard_xt_zenith_device; +extern const device_t keyboard_xt_hyundai_device; extern const device_t keyboard_xtclone_device; extern const device_t keyboard_at_device; +extern const device_t keyboard_at_siemens_device; extern const device_t keyboard_at_ami_device; extern const device_t keyboard_at_tg_ami_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; +extern const device_t keyboard_at_compaq_device; extern const device_t keyboard_ps2_device; extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; @@ -254,9 +270,9 @@ extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl); extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl); extern int keyboard_recv(uint16_t key); extern int keyboard_isfsenter(void); -extern int keyboard_isfsenter_down(void); +extern int keyboard_isfsenter_up(void); extern int keyboard_isfsexit(void); -extern int keyboard_isfsexit_down(void); +extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); diff --git a/src/include/86box/language.h b/src/include/86box/language.h index c9b807a997..3c96e711f1 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -52,7 +52,6 @@ #define IDS_2077 2077 // "Click to capture mouse" #define IDS_2078 2078 // "Press F12-F8 to release mouse" #define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2080 2080 // "Unable to initialize Flui.." #define IDS_2081 2081 // "Bus" #define IDS_BUS IDS_2081 // "Bus" #define IDS_2082 2082 // "File" @@ -98,8 +97,6 @@ #define IDS_2108 2108 // "%u MB (CHS: %i, %i, %i)" #define IDS_2109 2109 // "Floppy %i (%s): %ls" #define IDS_2110 2110 // "All floppy images (*.0??;*.." -#define IDS_2111 2111 // "Unable to initialize Free.." -#define IDS_2112 2112 // "Unable to initialize SDL..." #define IDS_2113 2113 // "Are you sure you want to..." #define IDS_2114 2114 // "Are you sure you want to..." #define IDS_2115 2115 // "Unable to initialize Ghostscript..." @@ -119,9 +116,7 @@ #define IDS_2129 2129 // "Hardware not available" #define IDS_2130 2130 // "Make sure " LIB_NAME_PCAP "..." #define IDS_2131 2131 // "Invalid configuration" -#define IDS_2132 2132 // LIB_NAME_FREETYPE " is required..." #define IDS_2133 2133 // LIB_NAME_GS " is required for... -#define IDS_2134 2134 // LIB_NAME_FLUIDSYNTH " is required..." #define IDS_2135 2135 // "Entering fullscreen mode" #define IDS_2136 2136 // "Don't show this message again" #define IDS_2137 2137 // "Don't exit" diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index cb8fc7cc6d..4e95b64c33 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -10,25 +10,24 @@ #define LPT_MDA_IRQ 7 #define LPT4_ADDR 0x0268 #define LPT4_IRQ 5 -/* +#if 0 #define LPT5_ADDR 0x027c #define LPT5_IRQ 7 #define LPT6_ADDR 0x026c #define LPT6_IRQ 5 -*/ +#endif -typedef struct -{ +typedef struct lpt_device_t { const char *name; const char *internal_name; - void *(*init)(void *lpt); - void (*close)(void *p); - void (*write_data)(uint8_t val, void *p); - void (*write_ctrl)(uint8_t val, void *p); - uint8_t (*read_data)(void *p); - uint8_t (*read_status)(void *p); - uint8_t (*read_ctrl)(void *p); + void *(*init)(void *lpt); + void (*close)(void *priv); + void (*write_data)(uint8_t val, void *priv); + void (*write_ctrl)(uint8_t val, void *priv); + uint8_t (*read_data)(void *priv); + uint8_t (*read_status)(void *priv); + uint8_t (*read_ctrl)(void *priv); } lpt_device_t; extern void lpt_init(void); @@ -53,24 +52,28 @@ extern void lpt1_remove_ams(void); #define lpt4_irq(a) lpt_port_irq(3, a) #define lpt4_remove() lpt_port_remove(3) -/* -#define lpt5_init(a) lpt_port_init(4, a) -#define lpt5_irq(a) lpt_port_irq(4, a) -#define lpt5_remove() lpt_port_remove(4) +#if 0 +#define lpt5_init(a) lpt_port_init(4, a) +#define lpt5_irq(a) lpt_port_irq(4, a) +#define lpt5_remove() lpt_port_remove(4) -#define lpt6_init(a) lpt_port_init(5, a) -#define lpt6_irq(a) lpt_port_irq(5, a) -#define lpt6_remove() lpt_port_remove(5) -*/ +#define lpt6_init(a) lpt_port_init(5, a) +#define lpt6_irq(a) lpt_port_irq(5, a) +#define lpt6_remove() lpt_port_remove(5) +#endif void lpt_devices_init(void); void lpt_devices_close(void); -typedef struct { - uint8_t enabled, irq, - dat, ctrl; - uint16_t addr, pad0; - int device, enable_irq; +typedef struct lpt_port_t { + uint8_t enabled; + uint8_t irq; + uint8_t dat; + uint8_t ctrl; + uint16_t addr; + uint16_t pad0; + int device; + int enable_irq; lpt_device_t *dt; void *priv; } lpt_port_t; @@ -80,10 +83,13 @@ extern lpt_port_t lpt_ports[PARALLEL_MAX]; extern void lpt_write(uint16_t port, uint8_t val, void *priv); extern uint8_t lpt_read(uint16_t port, void *priv); -extern void lpt_irq(void *priv, int raise); +extern uint8_t lpt_read_port(int port, uint16_t reg); -extern char *lpt_device_get_name(int id); -extern char *lpt_device_get_internal_name(int id); +extern uint8_t lpt_read_status(int port); +extern void lpt_irq(void *priv, int raise); + +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(char *s); diff --git a/src/include/86box/m_at_t3100e.h b/src/include/86box/m_at_t3100e.h index c25d171b9a..b9c2e24df9 100644 --- a/src/include/86box/m_at_t3100e.h +++ b/src/include/86box/m_at_t3100e.h @@ -12,11 +12,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2017-2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. + * Copyright 2008-2018 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/include/86box/m_xt_t1000.h b/src/include/86box/m_xt_t1000.h index d8e8cd56be..90916444c8 100644 --- a/src/include/86box/m_xt_t1000.h +++ b/src/include/86box/m_xt_t1000.h @@ -12,11 +12,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2017-2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. + * Copyright 2008-2018 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6b0b1976aa..e27a70d794 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -26,102 +26,121 @@ #define MACHINE_BUS_NONE 0x00000000 /* sys has no bus */ /* Feature flags for BUS'es. */ #define MACHINE_BUS_ISA 0x00000001 /* sys has ISA bus */ -#define MACHINE_BUS_CARTRIDGE 0x00000002 /* sys has two cartridge bays */ -#define MACHINE_BUS_ISA16 0x00000004 /* sys has ISA16 bus - PC/AT architecture */ -#define MACHINE_BUS_CBUS 0x00000008 /* sys has C-BUS bus */ -#define MACHINE_BUS_PS2 0x00000010 /* system has PS/2 keyboard and mouse ports */ -#define MACHINE_BUS_EISA 0x00000020 /* sys has EISA bus */ -#define MACHINE_BUS_VLB 0x00000040 /* sys has VL bus */ -#define MACHINE_BUS_MCA 0x00000080 /* sys has MCA bus */ -#define MACHINE_BUS_PCI 0x00000100 /* sys has PCI bus */ -#define MACHINE_BUS_PCMCIA 0x00000200 /* sys has PCMCIA bus */ -#define MACHINE_BUS_AGP 0x00000400 /* sys has AGP bus */ -#define MACHINE_BUS_AC97 0x00000800 /* sys has AC97 bus (ACR/AMR/CNR slot) */ +#define MACHINE_BUS_CASSETTE 0x00000002 /* sys has cassette port */ +#define MACHINE_BUS_CARTRIDGE 0x00000004 /* sys has two cartridge bays */ +#define MACHINE_BUS_PCJR 0x00000008 /* sys has PCjr sidecar bus */ +#define MACHINE_BUS_DM_KBC 0x00000010 /* system has keyboard controller that supports + both XT and AT keyboards */ +#define MACHINE_BUS_ISA16 0x00000020 /* sys has ISA16 bus - PC/AT architecture */ +#define MACHINE_BUS_CBUS 0x00000040 /* sys has C-BUS bus */ +#define MACHINE_BUS_PCMCIA 0x00000080 /* sys has PCMCIA bus */ +#define MACHINE_BUS_PS2_LATCH 0x00000100 /* system has PS/2 keyboard controller IRQ latch */ +#define MACHINE_BUS_PS2_PORTS 0x00000200 /* system has PS/2 keyboard and mouse ports */ +#define MACHINE_BUS_PS2 (MACHINE_BUS_PS2_LATCH | MACHINE_BUS_PS2_PORTS) +#define MACHINE_BUS_HIL 0x00000400 /* system has HP HIL keyboard and mouse ports */ +#define MACHINE_BUS_EISA 0x00000800 /* sys has EISA bus */ +#define MACHINE_BUS_AT32 0x00001000 /* sys has Mylex AT/32 local bus */ +#define MACHINE_BUS_OLB 0x00002000 /* sys has OPTi local bus */ +#define MACHINE_BUS_VLB 0x00004000 /* sys has VL bus */ +#define MACHINE_BUS_MCA 0x00008000 /* sys has MCA bus */ +#define MACHINE_BUS_PCI 0x00010000 /* sys has PCI bus */ +#define MACHINE_BUS_CARDBUS 0x00020000 /* sys has CardBus bus */ +#define MACHINE_BUS_USB 0x00040000 /* sys has USB bus */ +#define MACHINE_BUS_AGP 0x00080000 /* sys has AGP bus */ +#define MACHINE_BUS_AC97 0x00100000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ /* Aliases. */ -#define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ +#define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ +#define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ /* Combined flags. */ -#define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */ -#define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */ -#define MACHINE_PC98 (MACHINE_BUS_CBUS) /* sys is NEC PC-98x1 series */ -#define MACHINE_EISA (MACHINE_BUS_EISA | MACHINE_AT) /* sys is AT-compatible with EISA */ -#define MACHINE_VLB (MACHINE_BUS_VLB | MACHINE_AT) /* sys is AT-compatible with VLB */ -#define MACHINE_VLB98 (MACHINE_BUS_VLB | MACHINE_PC98) /* sys is NEC PC-98x1 series with VLB (did that even exist?) */ -#define MACHINE_VLBE (MACHINE_BUS_VLB | MACHINE_EISA) /* sys is AT-compatible with EISA and VLB */ -#define MACHINE_MCA (MACHINE_BUS_MCA) /* sys is MCA */ -#define MACHINE_PCI (MACHINE_BUS_PCI | MACHINE_AT) /* sys is AT-compatible with PCI */ -#define MACHINE_PCI98 (MACHINE_BUS_PCI | MACHINE_PC98) /* sys is NEC PC-98x1 series with PCI */ -#define MACHINE_PCIE (MACHINE_BUS_PCI | MACHINE_EISA) /* sys is AT-compatible with PCI, and EISA */ -#define MACHINE_PCIV (MACHINE_BUS_PCI | MACHINE_VLB) /* sys is AT-compatible with PCI and VLB */ -#define MACHINE_PCIVE (MACHINE_BUS_PCI | MACHINE_VLBE) /* sys is AT-compatible with PCI, VLB, and EISA */ -#define MACHINE_PCMCIA (MACHINE_BUS_PCMCIA | MACHINE_AT) /* sys is AT-compatible laptop with PCMCIA */ -#define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */ -#define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ - -#define MACHINE_PCJR (MACHINE_PC | MACHINE_CARTRIDGE) /* sys is PCjr */ -#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ -#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ -#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ -#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ -#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ -#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ -#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ -#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ -#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ +#define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */ +#define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */ +#define MACHINE_PC98 (MACHINE_BUS_CBUS) /* sys is NEC PC-98x1 series */ +#define MACHINE_EISA (MACHINE_BUS_EISA | MACHINE_AT) /* sys is AT-compatible with EISA */ +#define MACHINE_VLB (MACHINE_BUS_VLB | MACHINE_AT) /* sys is AT-compatible with VLB */ +#define MACHINE_VLB98 (MACHINE_BUS_VLB | MACHINE_PC98) /* sys is NEC PC-98x1 series with VLB (did that even exist?) */ +#define MACHINE_VLBE (MACHINE_BUS_VLB | MACHINE_EISA) /* sys is AT-compatible with EISA and VLB */ +#define MACHINE_MCA (MACHINE_BUS_MCA) /* sys is MCA */ +#define MACHINE_PCI (MACHINE_BUS_PCI | MACHINE_AT) /* sys is AT-compatible with PCI */ +#define MACHINE_PCI98 (MACHINE_BUS_PCI | MACHINE_PC98) /* sys is NEC PC-98x1 series with PCI */ +#define MACHINE_PCIE (MACHINE_BUS_PCI | MACHINE_EISA) /* sys is AT-compatible with PCI, and EISA */ +#define MACHINE_PCIV (MACHINE_BUS_PCI | MACHINE_VLB) /* sys is AT-compatible with PCI and VLB */ +#define MACHINE_PCIVE (MACHINE_BUS_PCI | MACHINE_VLBE) /* sys is AT-compatible with PCI, VLB, and EISA */ +#define MACHINE_PCMCIA (MACHINE_BUS_PCMCIA | MACHINE_AT) /* sys is AT-compatible laptop with PCMCIA */ +#define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */ +#define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ + +#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */ +#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_CARTRIDGE) /* sys is PCjr */ +#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ +#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ +#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ +#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ +#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ +#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ +#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ +#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ +#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */ +#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ /* Feature flags for miscellaneous internal devices. */ -#define MACHINE_FLAGS_NONE 0x00000000 /* sys has no int devices */ -#define MACHINE_VIDEO 0x00000001 /* sys has int video */ -#define MACHINE_VIDEO_ONLY 0x00000002 /* sys has fixed video */ -#define MACHINE_MOUSE 0x00000004 /* sys has int mouse */ -#define MACHINE_FDC 0x00000008 /* sys has int FDC */ -#define MACHINE_LPT_PRI 0x00000010 /* sys has int pri LPT */ -#define MACHINE_LPT_SEC 0x00000020 /* sys has int sec LPT */ -#define MACHINE_UART_PRI 0x00000040 /* sys has int pri UART */ -#define MACHINE_UART_SEC 0x00000080 /* sys has int sec UART */ -#define MACHINE_UART_TER 0x00000100 /* sys has int ter UART */ -#define MACHINE_UART_QUA 0x00000200 /* sys has int qua UART */ -#define MACHINE_GAMEPORT 0x00000400 /* sys has int game port */ -#define MACHINE_SOUND 0x00000800 /* sys has int sound */ -#define MACHINE_NIC 0x00001000 /* sys has int NIC */ -#define MACHINE_MODEM 0x00002000 /* sys has int modem */ +#define MACHINE_FLAGS_NONE 0x00000000 /* sys has no int devices */ +#define MACHINE_SOFTFLOAT_ONLY 0x00000001 /* sys requires SoftFloat FPU */ +#define MACHINE_VIDEO 0x00000002 /* sys has int video */ +#define MACHINE_VIDEO_8514A 0x00000004 /* sys has int video */ +#define MACHINE_VIDEO_XGA 0x00000008 /* sys has int video */ +#define MACHINE_VIDEO_ONLY 0x00000010 /* sys has fixed video */ +#define MACHINE_MOUSE 0x00000020 /* sys has int mouse */ +#define MACHINE_FDC 0x00000040 /* sys has int FDC */ +#define MACHINE_LPT_PRI 0x00000080 /* sys has int pri LPT */ +#define MACHINE_LPT_SEC 0x00000100 /* sys has int sec LPT */ +#define MACHINE_LPT_TER 0x00000200 /* sys has int ter LPT */ +#define MACHINE_LPT_QUA 0x00000400 /* sys has int qua LPT */ +#define MACHINE_UART_PRI 0x00000800 /* sys has int pri UART */ +#define MACHINE_UART_SEC 0x00001000 /* sys has int sec UART */ +#define MACHINE_UART_TER 0x00002000 /* sys has int ter UART */ +#define MACHINE_UART_QUA 0x00004000 /* sys has int qua UART */ +#define MACHINE_GAMEPORT 0x00008000 /* sys has int game port */ +#define MACHINE_SOUND 0x00010000 /* sys has int sound */ +#define MACHINE_NIC 0x00020000 /* sys has int NIC */ +#define MACHINE_MODEM 0x00040000 /* sys has int modem */ /* Feature flags for advanced devices. */ -#define MACHINE_APM 0x00004000 /* sys has APM */ -#define MACHINE_ACPI 0x00008000 /* sys has ACPI */ -#define MACHINE_HWM 0x00010000 /* sys has hw monitor */ -/* Combined flags. */ -#define MACHINE_VIDEO_FIXED (MACHINE_VIDEO | MACHINE_VIDEO_ONLY) /* sys has fixed int video */ -#define MACHINE_SUPER_IO (MACHINE_FDC | MACHINE_LPT_PRI | MACHINE_UART_PRI | MACHINE_UART_SEC) -#define MACHINE_SUPER_IO_GAME (MACHINE_SUPER_IO | MACHINE_GAMEPORT) -#define MACHINE_SUPER_IO_DUAL (MACHINE_SUPER_IO | MACHINE_LPT_SEC | MACHINE_UART_TER | MACHINE_UART_QUA) -#define MACHINE_AV (MACHINE_VIDEO | MACHINE_SOUND) /* sys has video and sound */ -#define MACHINE_AG (MACHINE_SOUND | MACHINE_GAMEPORT) /* sys has sound and game port */ +#define MACHINE_APM 0x00080000 /* sys has APM */ +#define MACHINE_ACPI 0x00100000 /* sys has ACPI */ +#define MACHINE_HWM 0x00200000 /* sys has hw monitor */ +#define MACHINE_COREBOOT 0x00400000 /* sys has coreboot BIOS */ /* Feature flags for internal storage controllers. */ -#define MACHINE_HDC 0x03FE0000 /* sys has int HDC */ -#define MACHINE_MFM 0x00020000 /* sys has int MFM/RLL */ -#define MACHINE_XTA 0x00040000 /* sys has int XTA */ -#define MACHINE_ESDI 0x00080000 /* sys has int ESDI */ -#define MACHINE_IDE_PRI 0x00100000 /* sys has int pri IDE/ATAPI */ -#define MACHINE_IDE_SEC 0x00200000 /* sys has int sec IDE/ATAPI */ -#define MACHINE_IDE_TER 0x00400000 /* sys has int ter IDE/ATAPI */ -#define MACHINE_IDE_QUA 0x00800000 /* sys has int qua IDE/ATAPI */ -#define MACHINE_SCSI_PRI 0x01000000 /* sys has int pri SCSI */ -#define MACHINE_SCSI_SEC 0x02000000 /* sys has int sec SCSI */ -#define MACHINE_USB_PRI 0x04000000 /* sys has int pri USB */ -#define MACHINE_USB_SEC 0x08000000 /* sys has int sec USB */ -#define MACHINE_COREBOOT 0x10000000 /* sys has coreboot BIOS */ +#define MACHINE_MFM 0x00800000 /* sys has int MFM/RLL */ +#define MACHINE_XTA 0x01000000 /* sys has int XTA */ +#define MACHINE_ESDI 0x02000000 /* sys has int ESDI */ +#define MACHINE_IDE_PRI 0x04000000 /* sys has int pri IDE/ATAPI */ +#define MACHINE_IDE_SEC 0x08000000 /* sys has int sec IDE/ATAPI */ +#define MACHINE_IDE_TER 0x10000000 /* sys has int ter IDE/ATAPI */ +#define MACHINE_IDE_QUA 0x20000000 /* sys has int qua IDE/ATAPI */ +#define MACHINE_SCSI 0x40000000 /* sys has int SCSI */ +#define MACHINE_USB 0x80000000 /* sys has int USB */ /* Combined flags. */ -#define MACHINE_IDE (MACHINE_IDE_PRI) /* sys has int single IDE/ATAPI - mark as pri IDE/ATAPI */ -#define MACHINE_IDE_DUAL (MACHINE_IDE_PRI | MACHINE_IDE_SEC) /* sys has int dual IDE/ATAPI - mark as both pri and sec IDE/ATAPI */ -#define MACHINE_IDE_DUALTQ (MACHINE_IDE_TER | MACHINE_IDE_QUA) -#define MACHINE_IDE_QUAD (MACHINE_IDE_DUAL | MACHINE_IDE_DUALTQ) /* sys has int quad IDE/ATAPI - mark as dual + both ter and and qua IDE/ATAPI */ -#define MACHINE_SCSI (MACHINE_SCSI_PRI) /* sys has int single SCSI - mark as pri SCSI */ -#define MACHINE_SCSI_DUAL (MACHINE_SCSI_PRI | MACHINE_SCSI_SEC) /* sys has int dual SCSI - mark as both pri and sec SCSI */ -#define MACHINE_USB (MACHINE_USB_PRI) -#define MACHINE_USB_DUAL (MACHINE_USB_PRI | MACHINE_USB_SEC) +#define MACHINE_LPT (MACHINE_LPT-PRI | MACHINE_LPT_SEC | \ + MACHINE_LPT_TER | MACHINE_LPT_QUA) +#define MACHINE_UART (MACHINE_UART_PRI | MACHINE_UART_SEC | \ + MACHINE_UART_TER | MACHINE_UART_QUA) +#define MACHINE_VIDEO_FIXED (MACHINE_VIDEO | MACHINE_VIDEO_ONLY) /* sys has fixed int video */ +#define MACHINE_SUPER_IO (MACHINE_FDC | MACHINE_LPT_PRI | MACHINE_UART_PRI | MACHINE_UART_SEC) +#define MACHINE_SUPER_IO_GAME (MACHINE_SUPER_IO | MACHINE_GAMEPORT) +#define MACHINE_SUPER_IO_DUAL (MACHINE_SUPER_IO | MACHINE_LPT_SEC | \ + MACHINE_UART_TER | MACHINE_UART_QUA) +#define MACHINE_AV (MACHINE_VIDEO | MACHINE_SOUND) /* sys has video and sound */ +#define MACHINE_AG (MACHINE_SOUND | MACHINE_GAMEPORT) /* sys has sound and game port */ +/* Combined flag for internal storage controllerss. */ +#define MACHINE_IDE (MACHINE_IDE_PRI) /* sys has int single IDE/ATAPI - mark as pri IDE/ATAPI */ +#define MACHINE_IDE_DUAL (MACHINE_IDE_PRI | MACHINE_IDE_SEC) /* sys has int dual IDE/ATAPI - mark as both pri and sec IDE/ATAPI */ +#define MACHINE_IDE_DUALTQ (MACHINE_IDE_TER | MACHINE_IDE_QUA) +#define MACHINE_IDE_QUAD (MACHINE_IDE_DUAL | MACHINE_IDE_DUALTQ) /* sys has int quad IDE/ATAPI - mark as dual + both ter and and qua IDE/ATAPI */ +#define MACHINE_HDC (MACHINE_MFM | MACHINE_XTA | \ + MACHINE_ESDI | MACHINE_IDE_QUAD | \ + MACHINE_SCSI | MACHINE_USB) /* Special combined flags. */ -#define MACHINE_PIIX (MACHINE_IDE_DUAL) -#define MACHINE_PIIX3 (MACHINE_PIIX | MACHINE_USB) -/* TODO: ACPI flag. */ -#define MACHINE_PIIX4 (MACHINE_PIIX3 | MACHINE_ACPI) +#define MACHINE_PIIX (MACHINE_IDE_DUAL) +#define MACHINE_PIIX3 (MACHINE_PIIX | MACHINE_USB) +#define MACHINE_PIIX4 (MACHINE_PIIX3 | MACHINE_ACPI) #define IS_ARCH(m, a) ((machines[m].bus_flags & (a)) ? 1 : 0) #define IS_AT(m) (((machines[m].bus_flags & (MACHINE_BUS_ISA16 | MACHINE_BUS_EISA | MACHINE_BUS_VLB | MACHINE_BUS_MCA | MACHINE_BUS_PCI | MACHINE_BUS_PCMCIA | MACHINE_BUS_AGP | MACHINE_BUS_AC97)) && !(machines[m].bus_flags & MACHINE_PC98)) ? 1 : 0) @@ -143,31 +162,31 @@ #endif enum { - MACHINE_TYPE_NONE = 0, - MACHINE_TYPE_8088, - MACHINE_TYPE_8086, - MACHINE_TYPE_286, - MACHINE_TYPE_386SX, - MACHINE_TYPE_486SLC, - MACHINE_TYPE_386DX, - MACHINE_TYPE_386DX_486, - MACHINE_TYPE_486, - MACHINE_TYPE_486_S2, - MACHINE_TYPE_486_S3, - MACHINE_TYPE_486_MISC, - MACHINE_TYPE_SOCKET4, - MACHINE_TYPE_SOCKET5, - MACHINE_TYPE_SOCKET7_3V, - MACHINE_TYPE_SOCKET7, - MACHINE_TYPE_SOCKETS7, - MACHINE_TYPE_SOCKET8, - MACHINE_TYPE_SLOT1, - MACHINE_TYPE_SLOT1_2, - MACHINE_TYPE_SLOT1_370, - MACHINE_TYPE_SLOT2, - MACHINE_TYPE_SOCKET370, - MACHINE_TYPE_MISC, - MACHINE_TYPE_MAX + MACHINE_TYPE_NONE = 0, + MACHINE_TYPE_8088 = 1, + MACHINE_TYPE_8086 = 2, + MACHINE_TYPE_286 = 3, + MACHINE_TYPE_386SX = 4, + MACHINE_TYPE_486SLC = 5, + MACHINE_TYPE_386DX = 6, + MACHINE_TYPE_386DX_486 = 7, + MACHINE_TYPE_486 = 8, + MACHINE_TYPE_486_S2 = 9, + MACHINE_TYPE_486_S3 = 10, + MACHINE_TYPE_486_MISC = 11, + MACHINE_TYPE_SOCKET4 = 12, + MACHINE_TYPE_SOCKET5 = 13, + MACHINE_TYPE_SOCKET7_3V = 14, + MACHINE_TYPE_SOCKET7 = 15, + MACHINE_TYPE_SOCKETS7 = 16, + MACHINE_TYPE_SOCKET8 = 17, + MACHINE_TYPE_SLOT1 = 18, + MACHINE_TYPE_SLOT1_2 = 19, + MACHINE_TYPE_SLOT1_370 = 20, + MACHINE_TYPE_SLOT2 = 21, + MACHINE_TYPE_SOCKET370 = 22, + MACHINE_TYPE_MISC = 23, + MACHINE_TYPE_MAX = 24 }; enum { @@ -226,8 +245,12 @@ enum { MACHINE_CHIPSET_SIS_471, MACHINE_CHIPSET_SIS_496, MACHINE_CHIPSET_SIS_501, + MACHINE_CHIPSET_SIS_5501, MACHINE_CHIPSET_SIS_5511, MACHINE_CHIPSET_SIS_5571, + MACHINE_CHIPSET_SIS_5581, + MACHINE_CHIPSET_SIS_5591, + MACHINE_CHIPSET_SIS_5600, MACHINE_CHIPSET_SMSC_VICTORYBX_66, MACHINE_CHIPSET_STPC_CLIENT, MACHINE_CHIPSET_STPC_CONSUMER_II, @@ -271,17 +294,21 @@ typedef struct _machine_cpu_ { } machine_cpu_t; typedef struct _machine_memory_ { - uint32_t min, max; + uint32_t min; + uint32_t max; int step; } machine_memory_t; typedef struct _machine_ { - const char *name; - const char *internal_name; - uint32_t type; - uintptr_t chipset; - int (*init)(const struct _machine_ *); - uintptr_t pad, pad0, pad1, pad2; + const char *name; + const char *internal_name; + uint32_t type; + uintptr_t chipset; + int (*init)(const struct _machine_ *); + uint8_t (*p1_handler)(uint8_t write, uint8_t val); + uint32_t (*gpio_handler)(uint8_t write, uint32_t val); + uintptr_t available_flag; + uint32_t (*gpio_acpi_handler)(uint8_t write, uint32_t val); const machine_cpu_t cpu; uintptr_t bus_flags; uintptr_t flags; @@ -293,10 +320,7 @@ typedef struct _machine_ { #else void *kbc_device; #endif /* EMU_DEVICE_H */ - /* Bits: - 7-0 Set bits are forced set on P1 (no forced set = 0x00); - 15-8 Clear bits are forced clear on P1 (no foced clear = 0xff). */ - uint16_t kbc_p1; + uint8_t kbc_p1; uint32_t gpio; uint32_t gpio_acpi; #ifdef EMU_DEVICE_H @@ -319,18 +343,19 @@ typedef struct _machine_ { /* Global variables. */ extern const machine_filter_t machine_types[]; extern const machine_filter_t machine_chipsets[]; -extern const machine_t machines[]; -extern int bios_only; -extern int machine; +extern const machine_t machines[]; +extern int bios_only; +extern int machine; +extern void * machine_snd; /* Core functions. */ -extern int machine_count(void); -extern int machine_available(int m); -extern char *machine_getname(void); -extern char *machine_getname_ex(int m); -extern char *machine_get_internal_name(void); -extern int machine_get_machine_from_internal_name(char *s); -extern void machine_init(void); +extern int machine_count(void); +extern int machine_available(int m); +extern const char *machine_getname(void); +extern const char *machine_getname_ex(int m); +extern const char *machine_get_internal_name(void); +extern int machine_get_machine_from_internal_name(const char *s); +extern void machine_init(void); #ifdef EMU_DEVICE_H extern const device_t *machine_get_kbc_device(int m); extern const device_t *machine_get_device(int m); @@ -340,24 +365,40 @@ extern const device_t *machine_get_vid_device(int m); extern const device_t *machine_get_snd_device(int m); extern const device_t *machine_get_net_device(int m); #endif -extern char *machine_get_internal_name_ex(int m); -extern int machine_get_nvrmask(int m); -extern int machine_has_flags(int m, int flags); -extern int machine_has_bus(int m, int bus_flags); -extern int machine_has_cartridge(int m); -extern int machine_get_min_ram(int m); -extern int machine_get_max_ram(int m); -extern int machine_get_ram_granularity(int m); -extern int machine_get_type(int m); -extern void machine_close(void); -extern int machine_has_mouse(void); -extern int machine_is_sony(void); - +extern const char *machine_get_internal_name_ex(int m); +extern int machine_get_nvrmask(int m); +extern int machine_has_flags(int m, int flags); +extern int machine_has_bus(int m, int bus_flags); +extern int machine_has_cartridge(int m); +extern int machine_get_min_ram(int m); +extern int machine_get_max_ram(int m); +extern int machine_get_ram_granularity(int m); +extern int machine_get_type(int m); +extern void machine_close(void); +extern int machine_has_mouse(void); +extern int machine_is_sony(void); + +extern uint8_t machine_get_p1_default(void); extern uint8_t machine_get_p1(void); -extern void machine_load_p1(int m); -extern uint32_t machine_get_gpi(void); -extern void machine_load_gpi(int m); -extern void machine_set_gpi(uint32_t gpi); +extern void machine_set_p1_default(uint8_t val); +extern void machine_set_p1(uint8_t val); +extern void machine_and_p1(uint8_t val); +extern void machine_init_p1(void); +extern uint8_t machine_handle_p1(uint8_t write, uint8_t val); +extern uint32_t machine_get_gpio_default(void); +extern uint32_t machine_get_gpio(void); +extern void machine_set_gpio_default(uint32_t val); +extern void machine_set_gpio(uint32_t val); +extern void machine_and_gpio(uint32_t val); +extern void machine_init_gpio(void); +extern uint32_t machine_handle_gpio(uint8_t write, uint32_t val); +extern uint32_t machine_get_gpio_acpi_default(void); +extern uint32_t machine_get_gpio_acpi(void); +extern void machine_set_gpio_acpi_default(uint32_t val); +extern void machine_set_gpio_acpi(uint32_t val); +extern void machine_and_gpio_acpi(uint32_t val); +extern void machine_init_gpio_acpi(void); +extern uint32_t machine_handle_gpio_acpi(uint8_t write, uint32_t val); /* Initialization functions for boards and systems. */ extern void machine_common_init(const machine_t *); @@ -410,6 +451,7 @@ extern int machine_at_quadt386sx_init(const machine_t *); extern int machine_at_award286_init(const machine_t *); extern int machine_at_gdc212m_init(const machine_t *); extern int machine_at_gw286ct_init(const machine_t *); +extern int machine_at_super286c_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); extern int machine_at_spc4216p_init(const machine_t *); @@ -434,6 +476,7 @@ extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_arb1374_init(const machine_t *); extern int machine_at_sbc350a_init(const machine_t *); extern int machine_at_flytech386_init(const machine_t *); +extern int machine_at_325ax_init(const machine_t *); extern int machine_at_mr1217_init(const machine_t *); extern int machine_at_pja511m_init(const machine_t *); extern int machine_at_prox1332_init(const machine_t *); @@ -448,6 +491,7 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_ecs386v_init(const machine_t *); extern int machine_at_rycleopardlx_init(const machine_t *); @@ -467,6 +511,7 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_exp4349_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); @@ -474,6 +519,8 @@ extern int machine_at_d824_init(const machine_t *); extern int machine_at_403tg_init(const machine_t *); extern int machine_at_403tg_d_init(const machine_t *); extern int machine_at_403tg_d_mr_init(const machine_t *); +extern int machine_at_pb450_init(const machine_t *); +extern int machine_at_pb450_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); @@ -487,16 +534,23 @@ extern int machine_at_ami471_init(const machine_t *); extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); +extern int machine_at_pci400ca_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); extern int machine_at_greenb_init(const machine_t *); +extern int machine_at_4gpv5_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); +extern int machine_at_ms4144_init(const machine_t *); extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); +extern int machine_at_amis76_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); +extern int machine_at_bat4ip3e_init(const machine_t *); +extern int machine_at_486pi_init(const machine_t *); +extern int machine_at_sb486p_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); @@ -508,6 +562,7 @@ extern int machine_at_win486pci_init(const machine_t *); extern int machine_at_ms4145_init(const machine_t *); extern int machine_at_sbc490_init(const machine_t *); extern int machine_at_tf486_init(const machine_t *); +extern int machine_at_arb1476_init(const machine_t *); extern int machine_at_pci400cb_init(const machine_t *); extern int machine_at_g486ip_init(const machine_t *); @@ -515,18 +570,24 @@ extern int machine_at_g486ip_init(const machine_t *); extern int machine_at_itoxstar_init(const machine_t *); extern int machine_at_arb1423c_init(const machine_t *); extern int machine_at_arb1479_init(const machine_t *); +extern int machine_at_iach488_init(const machine_t *); extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); extern int machine_at_ecs486_init(const machine_t *); -extern int machine_at_hot433_init(const machine_t *); +extern int machine_at_hot433a_init(const machine_t *); extern int machine_at_atc1415_init(const machine_t *); extern int machine_at_actionpc2600_init(const machine_t *); +extern int machine_at_actiontower8400_init(const machine_t *); extern int machine_at_m919_init(const machine_t *); extern int machine_at_spc7700plw_init(const machine_t *); extern int machine_at_ms4134_init(const machine_t *); extern int machine_at_tg486gp_init(const machine_t *); extern int machine_at_tg486g_init(const machine_t *); +extern int machine_at_dvent4xx_init(const machine_t *); +extern int machine_at_ecsal486_init(const machine_t *); +extern int machine_at_ap4100aa_init(const machine_t *); +extern int machine_at_atc1762_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); @@ -535,9 +596,8 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_portableiii386_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) extern int machine_at_deskpro386_init(const machine_t *); -#endif +extern int machine_at_deskpro386_05_1988_init(const machine_t *); /* m_at_socket4.c */ extern void machine_at_premiere_common_init(const machine_t *, int); @@ -552,7 +612,7 @@ extern int machine_at_opti560l_init(const machine_t *); extern int machine_at_ambradp60_init(const machine_t *); extern int machine_at_valuepointp60_init(const machine_t *); extern int machine_at_revenge_init(const machine_t *); -extern int machine_at_586mc1_init(const machine_t *); +extern int machine_at_586is_init(const machine_t *); extern int machine_at_pb520r_init(const machine_t *); extern int machine_at_excalibur_init(const machine_t *); @@ -564,23 +624,32 @@ extern int machine_at_p5sp4_init(const machine_t *); /* m_at_socket5.c */ extern int machine_at_plato_init(const machine_t *); +extern int machine_at_dellplato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); -extern int machine_at_430nx_init(const machine_t *); +extern int machine_at_586ip_init(const machine_t *); +extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_hawk_init(const machine_t *); +extern int machine_at_pt2000_init(const machine_t *); extern int machine_at_pat54pv_init(const machine_t *); extern int machine_at_hot543_init(const machine_t *); +extern int machine_at_ncselp90_init(const machine_t *); extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); extern int machine_at_p54sps_init(const machine_t *); +extern int machine_at_ms5109_init(const machine_t *); +extern int machine_at_torino_init(const machine_t *); + +extern int machine_at_hot539_init(const machine_t *); + /* m_at_socket7_3v.c */ extern int machine_at_p54tp4xe_init(const machine_t *); extern int machine_at_p54tp4xe_mr_init(const machine_t *); @@ -588,6 +657,7 @@ extern int machine_at_exp8551_init(const machine_t *); extern int machine_at_gw2katx_init(const machine_t *); extern int machine_at_thor_init(const machine_t *); extern int machine_at_mrthor_init(const machine_t *); +extern uint32_t machine_at_endeavor_gpio_handler(uint8_t write, uint32_t val); extern int machine_at_endeavor_init(const machine_t *); extern int machine_at_ms5119_init(const machine_t *); extern int machine_at_pb640_init(const machine_t *); @@ -600,21 +670,27 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); +extern int machine_at_dellhannibalp_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); extern int machine_at_ms5124_init(const machine_t *); +extern int machine_at_amis727_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); +extern int machine_at_5sbm2_init(const machine_t *); + /* m_at_socket7.c */ extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); extern int machine_at_m7shi_init(const machine_t *); extern int machine_at_tc430hx_init(const machine_t *); extern int machine_at_infinia7200_init(const machine_t *); +extern int machine_at_cu430hx_init(const machine_t *); extern int machine_at_equium5200_init(const machine_t *); extern int machine_at_pcv90_init(const machine_t *); extern int machine_at_p65up5_cp55t2d_init(const machine_t *); +extern int machine_at_epc2102_init(const machine_t *); extern int machine_at_ap5vm_init(const machine_t *); extern int machine_at_p55tvp4_init(const machine_t *); @@ -635,9 +711,12 @@ extern int machine_at_tx97_init(const machine_t *); extern int machine_at_an430tx_init(const machine_t *); #endif extern int machine_at_ym430tx_init(const machine_t *); +extern int machine_at_thunderbolt_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); +extern int machine_at_richmond_init(const machine_t *); +extern int machine_at_tomahawk_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); @@ -645,13 +724,20 @@ extern int machine_at_ficpa2012_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); +extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); +extern int machine_at_sp97xv_init(const machine_t *); +extern int machine_at_sq578_init(const machine_t *); + +extern int machine_at_ms5172_init(const machine_t *); + /* m_at_sockets7.c */ extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); +extern int machine_at_gwlucas_init(const machine_t *); extern int machine_at_5aa_init(const machine_t *); extern int machine_at_5ax_init(const machine_t *); @@ -660,13 +746,17 @@ extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); +extern int machine_at_5sg100_init(const machine_t *); + /* m_at_socket8.c */ +extern int machine_at_ap61_init(const machine_t *); extern int machine_at_p6rp4_init(const machine_t *); -extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); +extern int machine_at_lgibmx61_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); +extern int machine_at_gw2kvenus_init(const machine_t *); extern int machine_at_ap440fx_init(const machine_t *); extern int machine_at_mb600n_init(const machine_t *); extern int machine_at_8600ttc_init(const machine_t *); @@ -685,9 +775,12 @@ extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); +extern int machine_at_ma30d_init(const machine_t *); + extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); +extern int machine_at_lgibmx7g_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); @@ -705,6 +798,8 @@ extern int machine_at_vei8_init(const machine_t *); extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); +extern int machine_at_p6f99_init(const machine_t *); + /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); extern int machine_at_s2dge_init(const machine_t *); @@ -715,6 +810,7 @@ extern int machine_at_s370slm_init(const machine_t *); extern int machine_at_cubx_init(const machine_t *); extern int machine_at_atc7020bxii_init(const machine_t *); +extern int machine_at_m773_init(const machine_t *); extern int machine_at_ambx133_init(const machine_t *); extern int machine_at_awo671r_init(const machine_t *); extern int machine_at_63a1_init(const machine_t *); @@ -804,6 +900,7 @@ extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_vendex_init(const machine_t *); extern int machine_xt_znic_init(const machine_t *); +extern int machine_xt_glabios_init(const machine_t *); extern int machine_xt_super16t_init(const machine_t *); extern int machine_xt_super16te_init(const machine_t *); extern int machine_xt_top88_init(const machine_t *); diff --git a/src/include/86box/machine_status.h b/src/include/86box/machine_status.h index 6948dc556f..e7c57881bc 100644 --- a/src/include/86box/machine_status.h +++ b/src/include/86box/machine_status.h @@ -1,20 +1,20 @@ #ifndef EMU_MACHINE_STATUS_H #define EMU_MACHINE_STATUS_H -typedef struct { +typedef struct dev_status_empty_active_t { atomic_bool_t empty; atomic_bool_t active; } dev_status_empty_active_t; -typedef struct { +typedef struct dev_status_active_t { atomic_bool_t active; } dev_status_active_t; -typedef struct { +typedef struct dev_status_empty_t { atomic_bool_t empty; } dev_status_empty_t; -typedef struct { +typedef struct machine_status_t { dev_status_empty_active_t fdd[FDD_NUM]; dev_status_empty_active_t cdrom[CDROM_NUM]; dev_status_empty_active_t zip[ZIP_NUM]; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 45520f709f..bc949834fb 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -158,20 +158,21 @@ #define mem_set_access_smram_bus(smm, base, size, is_smram) \ mem_set_access((smm ? ACCESS_BUS_SMM : ACCESS_BUS), 1, base, size, is_smram) -typedef struct { - uint16_t x : 5, - w : 5, - r : 5, - pad : 1; +typedef struct state_t { + uint16_t x : 5; + uint16_t w : 5; + uint16_t r : 5; + uint16_t pad : 1; } state_t; -typedef union { +typedef union mem_state_t { uint16_t vals[4]; state_t states[4]; } mem_state_t; typedef struct _mem_mapping_ { - struct _mem_mapping_ *prev, *next; + struct _mem_mapping_ *prev; + struct _mem_mapping_ *next; int enable; @@ -193,7 +194,7 @@ typedef struct _mem_mapping_ { /* There is never a needed to pass a pointer to the mapping itself, it is much preferable to prepare a structure with the requires data (usually, the base address and mask) instead. */ - void *p; /* backpointer to device */ + void *priv; /* backpointer to device */ } mem_mapping_t; #ifdef USE_NEW_DYNAREC @@ -206,9 +207,9 @@ extern uint64_t *byte_code_present_mask; # define EVICT_NOT_IN_LIST ((uint32_t) -1) typedef struct page_t { - void (*write_b)(uint32_t addr, uint8_t val, struct page_t *p); - void (*write_w)(uint32_t addr, uint16_t val, struct page_t *p); - void (*write_l)(uint32_t addr, uint32_t val, struct page_t *p); + void (*write_b)(uint32_t addr, uint8_t val, struct page_t *page); + void (*write_w)(uint32_t addr, uint16_t val, struct page_t *page); + void (*write_l)(uint32_t addr, uint32_t val, struct page_t *page); uint8_t *mem; @@ -217,9 +218,11 @@ typedef struct page_t { /*Head of codeblock tree associated with this page*/ uint16_t head; - uint64_t code_present_mask, dirty_mask; + uint64_t code_present_mask; + uint64_t dirty_mask; - uint32_t evict_prev, evict_next; + uint32_t evict_prev; + uint32_t evict_next; uint64_t *byte_dirty_mask; uint64_t *byte_code_present_mask; @@ -227,35 +230,38 @@ typedef struct page_t { extern uint32_t purgable_page_list_head; __attribute__((always_inline)) static inline int -page_in_evict_list(page_t *p) +page_in_evict_list(page_t *page) { - return (p->evict_prev != EVICT_NOT_IN_LIST); + return (page->evict_prev != EVICT_NOT_IN_LIST); } -void page_remove_from_evict_list(page_t *p); -void page_add_to_evict_list(page_t *p); +void page_remove_from_evict_list(page_t *page); +void page_add_to_evict_list(page_t *page); #else typedef struct _page_ { - void (*write_b)(uint32_t addr, uint8_t val, struct _page_ *p); - void (*write_w)(uint32_t addr, uint16_t val, struct _page_ *p); - void (*write_l)(uint32_t addr, uint32_t val, struct _page_ *p); + void (*write_b)(uint32_t addr, uint8_t val, struct _page_ *page); + void (*write_w)(uint32_t addr, uint16_t val, struct _page_ *page); + void (*write_l)(uint32_t addr, uint32_t val, struct _page_ *page); uint8_t *mem; - uint64_t code_present_mask[4], - dirty_mask[4]; + uint64_t code_present_mask[4]; + uint64_t dirty_mask[4]; - struct codeblock_t *block[4], *block_2[4]; + struct codeblock_t *block[4]; + struct codeblock_t *block_2[4]; /*Head of codeblock tree associated with this page*/ struct codeblock_t *head; } page_t; #endif -extern uint8_t *ram, *ram2; +extern uint8_t *ram; +extern uint8_t *ram2; extern uint32_t rammask; extern uint8_t *rom; -extern uint32_t biosmask, biosaddr; +extern uint32_t biosmask; +extern uint32_t biosaddr; extern int readlookup[256]; extern uintptr_t *readlookup2; @@ -283,7 +289,8 @@ extern uint32_t mem_logical_addr; extern page_t *pages; extern page_t **page_lookup; -extern uint32_t get_phys_virt, get_phys_phys; +extern uint32_t get_phys_virt; +extern uint32_t get_phys_phys; extern int shadowbios; extern int shadowbios_write; @@ -296,6 +303,7 @@ extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint32_t pages_sz; /* #pages in table */ +extern int read_type; extern int mem_a20_state; extern int mem_a20_alt; @@ -324,6 +332,24 @@ extern void writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val); extern void do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write); +extern uint8_t readmembl_2386(uint32_t addr); +extern void writemembl_2386(uint32_t addr, uint8_t val); +extern uint16_t readmemwl_2386(uint32_t addr); +extern void writememwl_2386(uint32_t addr, uint16_t val); +extern uint32_t readmemll_2386(uint32_t addr); +extern void writememll_2386(uint32_t addr, uint32_t val); +extern uint64_t readmemql_2386(uint32_t addr); +extern void writememql_2386(uint32_t addr, uint64_t val); + +extern uint8_t readmembl_no_mmut_2386(uint32_t addr, uint32_t a64); +extern void writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val); +extern uint16_t readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64); +extern void writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val); +extern uint32_t readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64); +extern void writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val); + +extern void do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write); + extern uint8_t *getpccache(uint32_t a); extern uint64_t mmutranslatereal(uint32_t addr, int rw); extern uint32_t mmutranslatereal32(uint32_t addr, int rw); @@ -333,37 +359,37 @@ extern void addwritelookup(uint32_t virt, uint32_t phys); extern void mem_mapping_set(mem_mapping_t *, uint32_t base, uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv), uint8_t *exec, uint32_t flags, - void *p); + void *priv); extern void mem_mapping_add(mem_mapping_t *, uint32_t base, uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv), uint8_t *exec, uint32_t flags, - void *p); + void *priv); extern void mem_mapping_set_handler(mem_mapping_t *, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)); + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv)); -extern void mem_mapping_set_p(mem_mapping_t *, void *p); +extern void mem_mapping_set_p(mem_mapping_t *, void *priv); extern void mem_mapping_set_addr(mem_mapping_t *, uint32_t base, uint32_t size); @@ -373,6 +399,7 @@ extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); extern void mem_mapping_recalc(uint64_t base, uint64_t size); +extern void mem_set_wp(uint64_t base, uint64_t size, uint8_t flags, uint8_t wp); extern void mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t access); extern uint8_t mem_readb_phys(uint32_t addr); @@ -404,9 +431,9 @@ extern uint64_t mmutranslate_noabrt(uint32_t addr, int rw); extern void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr); -extern void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p); -extern void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p); -extern void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); +extern void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *page); +extern void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *page); +extern void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *page); extern void mem_flush_write_page(uint32_t addr, uint32_t virt); extern void mem_reset_page_blocks(void); @@ -414,6 +441,8 @@ extern void mem_reset_page_blocks(void); extern void flushmmucache(void); extern void flushmmucache_nopc(void); +extern void mem_debug_check_addr(uint32_t addr, int write); + extern void mem_a20_init(void); extern void mem_a20_recalc(void); @@ -422,6 +451,11 @@ extern void mem_close(void); extern void mem_reset(void); extern void mem_remap_top(int kb); +extern void umc_smram_recalc(uint32_t start, int set); + +extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; +extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; + #ifdef EMU_CPU_H static __inline uint32_t get_phys(uint32_t addr) diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index f965e6c986..7f7ad89ae5 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -9,8 +9,8 @@ extern uint8_t MIDI_evt_len[256]; extern int midi_output_device_current; extern int midi_input_device_current; -extern void (*input_msg)(void *p, uint8_t *msg, uint32_t len); -extern int (*input_sysex)(void *p, uint8_t *buf, uint32_t len, int abort); +extern void (*input_msg)(void *priv, uint8_t *msg, uint32_t len); +extern int (*input_sysex)(void *priv, uint8_t *buf, uint32_t len, int abort); extern void *midi_in_p; extern int midi_out_device_available(int card); @@ -19,14 +19,14 @@ extern int midi_in_device_available(int card); const device_t *midi_out_device_getdevice(int card); const device_t *midi_in_device_getdevice(int card); #endif -extern int midi_out_device_has_config(int card); -extern int midi_in_device_has_config(int card); -extern char *midi_out_device_get_internal_name(int card); -extern char *midi_in_device_get_internal_name(int card); -extern int midi_out_device_get_from_internal_name(char *s); -extern int midi_in_device_get_from_internal_name(char *s); -extern void midi_out_device_init(void); -extern void midi_in_device_init(void); +extern int midi_out_device_has_config(int card); +extern int midi_in_device_has_config(int card); +extern const char *midi_out_device_get_internal_name(int card); +extern const char *midi_in_device_get_internal_name(int card); +extern int midi_out_device_get_from_internal_name(char *s); +extern int midi_in_device_get_from_internal_name(char *s); +extern void midi_out_device_init(void); +extern void midi_in_device_init(void); typedef struct midi_device_t { void (*play_sysex)(uint8_t *sysex, unsigned int len); @@ -40,20 +40,29 @@ typedef struct midi_in_handler_t { int cnt; uint32_t len; - void (*msg)(void *p, uint8_t *msg, uint32_t len); - int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort); - struct midi_in_handler_t *p; - struct midi_in_handler_t *prev, *next; + void (*msg)(void *priv, uint8_t *msg, uint32_t len); + int (*sysex)(void *priv, uint8_t *buffer, uint32_t len, int abort); + struct midi_in_handler_t *priv; + struct midi_in_handler_t *prev; + struct midi_in_handler_t *next; } midi_in_handler_t; typedef struct midi_t { - uint8_t midi_rt_buf[8], midi_cmd_buf[8], - midi_status, midi_sysex_data[SYSEX_SIZE]; - int midi_cmd_pos, midi_cmd_len, midi_cmd_r, - midi_realtime, thruchan, midi_clockout; - unsigned int midi_sysex_start, midi_sysex_delay, - midi_pos; - midi_device_t *m_out_device, *m_in_device; + uint8_t midi_rt_buf[8]; + uint8_t midi_cmd_buf[8]; + uint8_t midi_status; + uint8_t midi_sysex_data[SYSEX_SIZE]; + int midi_cmd_pos; + int midi_cmd_len; + int midi_cmd_r; + int midi_realtime; + int thruchan; + int midi_clockout; + unsigned int midi_sysex_start; + unsigned int midi_sysex_delay; + unsigned int midi_pos; + midi_device_t *m_out_device; + midi_device_t *m_in_device; } midi_t; extern midi_t *midi_out; @@ -69,7 +78,7 @@ extern void midi_raw_out_byte(uint8_t val); extern void midi_clear_buffer(void); extern void midi_poll(void); -extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); +extern void midi_in_handler(int set, void (*msg)(void *priv, uint8_t *msg, uint32_t len), int (*sysex)(void *priv, uint8_t *buffer, uint32_t len, int abort), void *priv); extern void midi_in_handlers_clear(void); extern void midi_in_msg(uint8_t *msg, uint32_t len); extern void midi_in_sysex(uint8_t *buffer, uint32_t len); @@ -93,6 +102,9 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; +# if defined(DEV_BRANCH) && defined(USE_OPL4ML) +extern const device_t opl4_midi_device; +# endif # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; # endif diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 19c999ee3f..5d4b723f33 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -27,7 +27,9 @@ #define MO_TIME 10.0 -typedef struct { +#define MO_IMAGE_HISTORY 4 + +typedef struct mo_type_t { uint32_t sectors; uint16_t bytes_per_sector; } mo_type_t; @@ -35,21 +37,20 @@ typedef struct { #define KNOWN_MO_TYPES 10 static const mo_type_t mo_types[KNOWN_MO_TYPES] = { // 3.5" standard M.O. disks - {248826, 512 }, - { 446325, 512 }, - { 1041500, 512 }, - { 310352, 2048}, - { 605846, 2048}, - { 1063146, 2048}, + { 248826, 512 }, + { 446325, 512 }, + { 1041500, 512 }, + { 310352, 2048 }, + { 605846, 2048 }, + { 1063146, 2048 }, // 5.25" M.O. disks - { 573624, 512 }, - { 314568, 1024}, - { 904995, 512 }, - { 637041, 1024}, + { 573624, 512 }, + { 314568, 1024 }, + { 904995, 512 }, + { 637041, 1024 }, }; -typedef struct -{ +typedef struct mo_drive_type_t { const char vendor[9]; const char model[16]; const char revision[5]; @@ -59,7 +60,7 @@ typedef struct #define KNOWN_MO_DRIVE_TYPES 22 static const mo_drive_type_t mo_drive_types[KNOWN_MO_DRIVE_TYPES] = { {"86BOX", "MAGNETO OPTICAL", "1.00", { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }}, - { "FUJITSU", "M2512A", "1314", { 1, 1, 0, 0, 0, 0, 0, 0, 0 } }, + { "FUJITSU", "M2512A", "1314", { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }}, { "FUJITSU", "M2513-MCC3064SS", "1.00", { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }}, { "FUJITSU", "MCE3130SS", "0070", { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }}, { "FUJITSU", "MCF3064SS", "0030", { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }}, @@ -85,70 +86,100 @@ static const mo_drive_type_t mo_drive_types[KNOWN_MO_DRIVE_TYPES] = { enum { MO_BUS_DISABLED = 0, MO_BUS_ATAPI = 5, - MO_BUS_SCSI, - MO_BUS_USB + MO_BUS_SCSI = 6, + MO_BUS_USB = 7 }; -typedef struct { +typedef struct mo_drive_t { uint8_t id; union { - uint8_t res, res0, /* Reserved for other ID's. */ - res1, - ide_channel, scsi_device_id; + uint8_t res; + uint8_t res0; /* Reserved for other ID's. */ + uint8_t res1; + uint8_t ide_channel; + uint8_t scsi_device_id; }; - uint8_t bus_type, /* 0 = ATAPI, 1 = SCSI */ - bus_mode, /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - read_only, /* Struct variable reserved for - media status. */ - pad, pad0; + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + uint8_t read_only; /* Struct variable reserved for + media status. */ + uint8_t pad; + uint8_t pad0; - FILE *f; + FILE *fp; void *priv; - char image_path[1024], - prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; + + char *image_history[MO_IMAGE_HISTORY]; - uint32_t type, medium_size, - base; + uint32_t type; + uint32_t medium_size; + uint32_t base; uint16_t sector_size; } mo_drive_t; -typedef struct { +typedef struct mo_t { mode_sense_pages_t ms_pages_saved; mo_drive_t *drv; +#ifdef EMU_IDE_H + ide_tf_t * tf; +#else + void * tf; +#endif - uint8_t *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; - - uint8_t status, phase, - error, id, - features, cur_lun, - pad0, pad1; - - uint16_t request_length, max_transfer_len; - - int requested_blocks, packet_status, - total_length, do_page_save, - unit_attention, request_pos, - old_len, pad3; + uint8_t *buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; + +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; + uint8_t phase; + uint16_t request_length; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif - uint32_t sector_pos, sector_len, - packet_len, pos; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; + + uint16_t max_transfer_len; + uint16_t pad2; + + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int pad3; + + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; double callback; } mo_t; extern mo_t *mo[MO_NUM]; extern mo_drive_t mo_drives[MO_NUM]; +#if 0 extern uint8_t atapi_mo_drives[8]; extern uint8_t scsi_mo_drives[16]; +#endif #define mo_sense_error dev->sense[0] #define mo_sense_key dev->sense[2] diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 874bf30def..786b86f410 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -20,8 +20,13 @@ #ifndef EMU_MOUSE_H #define EMU_MOUSE_H +#ifndef __cplusplus +/* Yes, a big no-no, but I'm saving myself time here. */ +#include +#endif + #define MOUSE_TYPE_NONE 0 /* no mouse configured */ -#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */ +#define MOUSE_TYPE_INTERNAL 1 /* achine has internal mouse */ #define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */ #define MOUSE_TYPE_INPORT 3 /* Microsoft InPort Mouse */ #if 0 @@ -39,30 +44,28 @@ #define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */ + #ifdef __cplusplus extern "C" { #endif -extern int mouse_type; -extern int mouse_x; -extern int mouse_y; -extern int mouse_z; -extern int mouse_mode; /* 1 = Absolute, 0 = Relative */ -extern int mouse_tablet_in_proximity; +extern int mouse_type; +extern int mouse_input_mode; /* 1 = Absolute, 0 = Relative */ +extern int mouse_timed; /* 1 = Timed, 0 = Constant */ +extern int mouse_tablet_in_proximity; extern double mouse_x_abs; extern double mouse_y_abs; -extern int mouse_buttons; -extern int tablet_tool_type; +extern int tablet_tool_type; +extern double mouse_sensitivity; #ifdef EMU_DEVICE_H -extern const device_t *mouse_get_device(int mouse); extern void *mouse_ps2_init(const device_t *); extern const device_t mouse_logibus_device; extern const device_t mouse_logibus_onboard_device; extern const device_t mouse_msinport_device; -# if 0 -extern const device_t mouse_genibus_device; +# ifdef USE_GENIBUS +extern const device_t mouse_genibus_device; # endif extern const device_t mouse_mssystems_device; extern const device_t mouse_msserial_device; @@ -72,28 +75,51 @@ extern const device_t mouse_wacom_device; extern const device_t mouse_wacom_artpad_device; #endif -extern void mouse_init(void); -extern void mouse_close(void); -extern void mouse_reset(void); -extern void mouse_set_buttons(int buttons); -extern void mouse_set_poll_ex(void (*poll_ex)(void)); -extern void mouse_process(void); -extern void mouse_set_poll(int (*f)(int, int, int, int, void *), void *); -extern void mouse_poll(void); - -extern void mouse_bus_set_irq(void *priv, int irq); - -extern void mouse_set_sample_rate(double new_rate); - -extern char *mouse_get_name(int mouse); -extern char *mouse_get_internal_name(int mouse); -extern int mouse_get_from_internal_name(char *s); -extern int mouse_has_config(int mouse); -extern int mouse_get_type(int mouse); -extern int mouse_get_ndev(void); -extern int mouse_get_buttons(void); +extern void mouse_clear_x(void); +extern void mouse_clear_y(void); +extern void mouse_clear_coords(void); +extern void mouse_clear_buttons(void); +extern void mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs); +extern void mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs); +extern void mouse_subtract_coords(int *delta_x, int *delta_y, int *o_x, int *o_y, + int min, int max, int invert, int abs); +extern int mouse_wheel_moved(void); +extern int mouse_moved(void); +extern int mouse_state_changed(void); +extern int mouse_mbut_changed(void); +extern void mouse_scale_fx(double x); +extern void mouse_scale_fy(double y); +extern void mouse_scale_x(int x); +extern void mouse_scale_y(int y); +extern void mouse_scalef(double x, double y); +extern void mouse_scale(int x, int y); +extern void mouse_scale_axis(int axis, int val); +extern void mouse_set_z(int z); +extern void mouse_clear_z(void); +extern void mouse_subtract_z(int *delta_z, int min, int max, int invert); +extern void mouse_set_buttons_ex(int b); +extern int mouse_get_buttons_ex(void); +extern void mouse_set_sample_rate(double new_rate); +extern void mouse_set_buttons(int buttons); +extern void mouse_get_abs_coords(double *x_abs, double *y_abs); +extern void mouse_process(void); +extern void mouse_set_poll_ex(void (*poll_ex)(void)); +extern void mouse_set_poll(int (*f)(void *), void *); +extern const char * mouse_get_name(int mouse); +extern const char * mouse_get_internal_name(int mouse); +extern int mouse_get_from_internal_name(char *s); +extern int mouse_has_config(int mouse); +#ifdef EMU_DEVICE_H +extern const device_t *mouse_get_device(int mouse); +#endif +extern int mouse_get_buttons(void); +extern int mouse_get_ndev(void); +extern void mouse_set_raw(int raw); +extern void mouse_reset(void); +extern void mouse_close(void); +extern void mouse_init(void); -extern void mouse_clear_data(void *priv); +extern void mouse_bus_set_irq(void *priv, int irq); #ifdef __cplusplus } diff --git a/src/include/86box/net_3c501.h b/src/include/86box/net_3c501.h deleted file mode 100644 index 996720f8f1..0000000000 --- a/src/include/86box/net_3c501.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 Project. - * - * Implementation of the following network controller: - * - 3Com Etherlink 3c500/3c501 (ISA 8-bit). - * - * - * - * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) - * - * Authors: TheCollector1995, - * Oracle - * - * Copyright 2022 TheCollector1995. - * Portions Copyright (C) 2022 Oracle and/or its affilitates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C501_H -#define NET_3C501_H - -extern const device_t threec501_device; - -#endif /*NET_3C501_H*/ diff --git a/src/include/86box/net_3c503.h b/src/include/86box/net_3c503.h deleted file mode 100644 index 44024850fc..0000000000 --- a/src/include/86box/net_3c503.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * - * Implementation of the following network controllers: - * - 3Com Etherlink II 3c503 (ISA 8-bit). - * - * - * - * Based on @(#)3c503.cpp Carl (MAME) - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * Carl, - * - * Copyright 2018 TheCollector1995. - * Copyright 2018 Miran Grca. - * Copyright 2017-2018 Fred N. van Kempen. - * Portions Copyright (C) 2018 MAME Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#ifndef NET_3C503_H -#define NET_3C503_H - -extern const device_t threec503_device; - -#endif /*NET_3C503_H*/ diff --git a/src/include/86box/net_dp8390.h b/src/include/86box/net_dp8390.h index bc3220c69c..e9e1e6c719 100644 --- a/src/include/86box/net_dp8390.h +++ b/src/include/86box/net_dp8390.h @@ -36,7 +36,7 @@ #define DP8390_FLAG_CHECK_CR 0x02 #define DP8390_FLAG_CLEAR_IRQ 0x04 -typedef struct { +typedef struct dp8390_t { /* Page 0 */ /* Command Register - 00h read/write */ diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/net_eeprom_nmc93cxx.h new file mode 100644 index 0000000000..f5260d1eda --- /dev/null +++ b/src/include/86box/net_eeprom_nmc93cxx.h @@ -0,0 +1,19 @@ +struct nmc93cxx_eeprom_t; +typedef struct nmc93cxx_eeprom_t nmc93cxx_eeprom_t; + +typedef struct nmc93cxx_eeprom_params_t { + uint16_t nwords; + char *filename; + uint16_t *default_content; +} nmc93cxx_eeprom_params_t; + +/* Read from the EEPROM. */ +uint16_t nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *eeprom); + +/* Write to the EEPROM. */ +void nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi); + +/* Get EEPROM data array. */ +uint16_t *nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom); + +extern const device_t nmc93cxx_device; diff --git a/src/include/86box/net_event.h b/src/include/86box/net_event.h index 61eaad166c..48580a3592 100644 --- a/src/include/86box/net_event.h +++ b/src/include/86box/net_event.h @@ -1,7 +1,7 @@ #ifndef EMU_NET_EVENT_H #define EMU_NET_EVENT_H -typedef struct { +typedef struct net_evt_t { #ifdef _WIN32 HANDLE handle; #else diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index 350668ccb2..fe1a71934c 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -37,18 +37,15 @@ #define NET_NE2000_H enum { - NE2K_NONE = 0, - NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ - NE2K_NE2000 = 2, /* 16-bit ISA NE2000 */ - NE2K_ETHERNEXT_MC = 3, /* 16-bit MCA EtherNext/MC */ - NE2K_RTL8019AS = 4, /* 16-bit ISA PnP Realtek 8019AS */ - NE2K_RTL8029AS = 5 /* 32-bit PCI Realtek 8029AS */ + NE2K_NONE = 0, + NE2K_NE1000 = 1, /* 8-bit ISA NE1000 */ + NE2K_NE1000_COMPAT = 2, /* 16-bit ISA NE2000-Compatible */ + NE2K_NE2000 = 3, /* 16-bit ISA NE2000 */ + NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ + NE2K_ETHERNEXT_MC = 5, /* 16-bit MCA EtherNext/MC */ + NE2K_RTL8019AS = 6, /* 16-bit ISA PnP Realtek 8019AS */ + NE2K_DE220P = 7, /* 16-bit ISA PnP D-Link DE-220P */ + NE2K_RTL8029AS = 8 /* 32-bit PCI Realtek 8029AS */ }; -extern const device_t ne1000_device; -extern const device_t ne2000_device; -extern const device_t ethernext_mc_device; -extern const device_t rtl8019as_device; -extern const device_t rtl8029as_device; - #endif /*NET_NE2000_H*/ diff --git a/src/include/86box/net_pcnet.h b/src/include/86box/net_pcnet.h index ccdc7e8323..994d88c75a 100644 --- a/src/include/86box/net_pcnet.h +++ b/src/include/86box/net_pcnet.h @@ -30,11 +30,4 @@ enum { DEV_AM79C973 = 6 /* PCnet-FAST III (PCI, 10/100 Mbps) */ }; -extern const device_t pcnet_am79c960_device; -extern const device_t pcnet_am79c960_eb_device; -extern const device_t pcnet_am79c960_vlb_device; -extern const device_t pcnet_am79c961_device; -extern const device_t pcnet_am79c970a_device; -extern const device_t pcnet_am79c973_device; - #endif /*NET_PCNET_H*/ diff --git a/src/include/86box/net_wd8003.h b/src/include/86box/net_wd8003.h index a0ea13287c..6797c7d882 100644 --- a/src/include/86box/net_wd8003.h +++ b/src/include/86box/net_wd8003.h @@ -45,20 +45,13 @@ #define NET_WD8003_H enum { - WD_NONE = 0, - WD8003E, /* WD8003E : 8-bit ISA, no interface chip */ - WD8003EB, /* WD8003EB : 8-bit ISA, 5x3 interface chip */ - WD8013EBT, /* WD8013EBT : 16-bit ISA, no interface chip */ - WD8003ETA, /* WD8003ET/A: 16-bit MCA, no interface chip */ - WD8003EA, /* WD8003E/A : 16-bit MCA, 5x3 interface chip */ - WD8013EPA + WD_NONE = 0, + WD8003E = 1, /* WD8003E : 8-bit ISA, no interface chip */ + WD8003EB = 2, /* WD8003EB : 8-bit ISA, 5x3 interface chip */ + WD8013EBT = 3, /* WD8013EBT : 16-bit ISA, no interface chip */ + WD8003ETA = 4, /* WD8003ET/A: 16-bit MCA, no interface chip */ + WD8003EA = 5, /* WD8003E/A : 16-bit MCA, 5x3 interface chip */ + WD8013EPA = 6 }; -extern const device_t wd8003e_device; -extern const device_t wd8003eb_device; -extern const device_t wd8013ebt_device; -extern const device_t wd8003eta_device; -extern const device_t wd8003ea_device; -extern const device_t wd8013epa_device; - #endif /*NET_WD8003_H*/ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 2684ed1c47..d0af3f09bc 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -78,22 +78,18 @@ enum { NET_LINK_1000_FD = (1 << 8), }; -/* Supported network cards. */ enum { - NONE = 0, - NE1000, - NE2000, - RTL8019AS, - RTL8029AS + NET_NONE = 0, + NET_INTERNAL }; enum { - NET_QUEUE_RX, - NET_QUEUE_TX_VM, - NET_QUEUE_TX_HOST + NET_QUEUE_RX = 0, + NET_QUEUE_TX_VM = 1, + NET_QUEUE_TX_HOST = 2 }; -typedef struct { +typedef struct netcard_conf_t { uint16_t device_num; int net_type; char host_dev_name[128]; @@ -111,7 +107,7 @@ typedef struct netpkt { int len; } netpkt_t; -typedef struct { +typedef struct netqueue_t { netpkt_t packets[NET_QUEUE_LEN]; int head; int tail; @@ -168,11 +164,11 @@ extern "C" { #endif /* Global variables. */ -extern int nic_do_log; /* config */ +extern int nic_do_log; // config extern network_devmap_t network_devmap; -extern int network_ndev; // Number of pcap devices +extern int network_ndev; // Number of pcap devices extern network_devmap_t network_devmap; // Bitmap of available network types -extern netdev_t network_devs[NET_HOST_INTF_MAX]; +extern netdev_t network_devs[NET_HOST_INTF_MAX]; /* Function prototypes. */ @@ -194,14 +190,65 @@ extern int network_dev_available(int); extern int network_dev_to_id(char *); extern int network_card_available(int); extern int network_card_has_config(int); -extern char *network_card_get_internal_name(int); +extern const char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); +#ifdef EMU_DEVICE_H extern const device_t *network_card_getdevice(int); +#endif extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt); extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size); extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len); extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt); + +#ifdef EMU_DEVICE_H +/* 3Com Etherlink */ +extern const device_t threec501_device; +extern const device_t threec503_device; + +/* Novell NE2000 and compatibles */ +extern const device_t ne1000_device; +extern const device_t ne1000_compat_device; +extern const device_t ne2000_device; +extern const device_t ne2000_compat_device; +extern const device_t ethernext_mc_device; +extern const device_t rtl8019as_device; +extern const device_t de220p_device; +extern const device_t rtl8029as_device; + +/* AMD PCnet*/ +extern const device_t pcnet_am79c960_device; +extern const device_t pcnet_am79c960_eb_device; +extern const device_t pcnet_am79c960_vlb_device; +extern const device_t pcnet_am79c961_device; +extern const device_t pcnet_am79c970a_device; +extern const device_t pcnet_am79c973_device; +extern const device_t pcnet_am79c973_onboard_device; + +/* PLIP */ +#ifdef EMU_LPT_H +extern const lpt_device_t lpt_plip_device; +#endif +extern const device_t plip_device; + +/* Realtek RTL8139C+ */ +extern const device_t rtl8139c_plus_device; + +/* DEC Tulip */ +extern const device_t dec_tulip_device; +extern const device_t dec_tulip_21140_device; +extern const device_t dec_tulip_21140_vpc_device; +extern const device_t dec_tulip_21040_device; + +/* WD 80x3 */ +extern const device_t wd8003e_device; +extern const device_t wd8003eb_device; +extern const device_t wd8013ebt_device; +extern const device_t wd8003eta_device; +extern const device_t wd8003ea_device; +extern const device_t wd8013epa_device; +#endif + #ifdef __cplusplus } #endif diff --git a/src/include/86box/nmi.h b/src/include/86box/nmi.h index 319d63b6b9..79aa68346e 100644 --- a/src/include/86box/nmi.h +++ b/src/include/86box/nmi.h @@ -11,6 +11,6 @@ extern int nmi_auto_clear; extern void nmi_init(void); -extern void nmi_write(uint16_t port, uint8_t val, void *p); +extern void nmi_write(uint16_t port, uint8_t val, void *priv); #endif /*EMU_NMI_H*/ diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 25f5e90ad1..85e0954f02 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -64,7 +64,8 @@ typedef struct _nvr_ { char *fn; /* pathname of image file */ uint16_t size; /* device configuration */ - int8_t irq, is_new; + int8_t irq; + int8_t is_new; uint8_t onesec_cnt; pc_timer_t onesec_time; @@ -84,6 +85,7 @@ extern int nvr_dosave; #ifdef EMU_DEVICE_H extern const device_t at_nvr_old_device; extern const device_t at_nvr_device; +extern const device_t at_mb_nvr_device; extern const device_t ps_nvr_device; extern const device_t amstrad_nvr_device; extern const device_t amstrad_megapc_nvr_device; @@ -120,10 +122,15 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_read_addr_set(int set, nvr_t *nvr); +extern uint8_t nvr_get_index(void *priv, uint8_t addr_id); +extern void nvr_at_data_port(int set, nvr_t *nvr); extern void nvr_wp_set(int set, int h, nvr_t *nvr); extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr); extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr); extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr); extern void nvr_irq_set(int irq, nvr_t *nvr); +extern void nvr_smi_enable(int enable, nvr_t *nvr); +extern uint8_t nvr_smi_status(nvr_t *nvr); +extern void nvr_smi_status_clear(nvr_t *nvr); #endif /*EMU_NVR_H*/ diff --git a/src/include/86box/opl4_defines.h b/src/include/86box/opl4_defines.h new file mode 100644 index 0000000000..248b1f7296 --- /dev/null +++ b/src/include/86box/opl4_defines.h @@ -0,0 +1,101 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2020 by RoboSoft Inc. + * + * opl4_defines.h + * + */ + +#ifndef __OPL4_DEFINES_H +#define __OPL4_DEFINES_H + +/* + * Register numbers + */ + +#define OPL4_REG_TEST0 0x00 +#define OPL4_REG_TEST1 0x01 + +#define OPL4_REG_MEMORY_CONFIGURATION 0x02 +#define OPL4_MODE_BIT 0x01 +#define OPL4_MTYPE_BIT 0x02 +#define OPL4_TONE_HEADER_MASK 0x1C +#define OPL4_DEVICE_ID_MASK 0xE0 + +#define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03 +#define OPL4_REG_MEMORY_ADDRESS_MID 0x04 +#define OPL4_REG_MEMORY_ADDRESS_LOW 0x05 +#define OPL4_REG_MEMORY_DATA 0x06 + +/* + * Offsets to the register banks for voices. To get the + * register number just add the voice number to the bank offset. + * + * Wave Table Number low bits (0x08 to 0x1F) + */ +#define OPL4_REG_TONE_NUMBER 0x08 + +/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */ +#define OPL4_REG_F_NUMBER 0x20 +#define OPL4_TONE_NUMBER_BIT8 0x01 +#define OPL4_F_NUMBER_LOW_MASK 0xFE + +/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */ +#define OPL4_REG_OCTAVE 0x38 +#define OPL4_F_NUMBER_HIGH_MASK 0x07 +#define OPL4_BLOCK_MASK 0xF0 +#define OPL4_PSEUDO_REVERB_BIT 0x08 + +/* Total Level, Level Direct (0x50 to 0x67) */ +#define OPL4_REG_LEVEL 0x50 +#define OPL4_TOTAL_LEVEL_MASK 0xFE +#define OPL4_LEVEL_DIRECT_BIT 0x01 + +/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */ +#define OPL4_REG_MISC 0x68 +#define OPL4_KEY_ON_BIT 0x80 +#define OPL4_DAMP_BIT 0x40 +#define OPL4_LFO_RESET_BIT 0x20 +#define OPL4_OUTPUT_CHANNEL_BIT 0x10 +#define OPL4_PAN_POT_MASK 0x0F + +/* LFO, VIB (0x80 to 0x97) */ +#define OPL4_REG_LFO_VIBRATO 0x80 +#define OPL4_LFO_FREQUENCY_MASK 0x38 +#define OPL4_VIBRATO_DEPTH_MASK 0x07 +#define OPL4_CHORUS_SEND_MASK 0xC0 + +/* Attack / Decay 1 rate (0x98 to 0xAF) */ +#define OPL4_REG_ATTACK_DECAY1 0x98 +#define OPL4_ATTACK_RATE_MASK 0xF0 +#define OPL4_DECAY1_RATE_MASK 0x0F + +/* Decay level / 2 rate (0xB0 to 0xC7) */ +#define OPL4_REG_LEVEL_DECAY2 0xB0 +#define OPL4_DECAY_LEVEL_MASK 0xF0 +#define OPL4_DECAY2_RATE_MASK 0x0F + +/* Release rate / Rate correction (0xC8 to 0xDF) */ +#define OPL4_REG_RELEASE_CORRECTION 0xC8 +#define OPL4_RELEASE_RATE_MASK 0x0F +#define OPL4_RATE_INTERPOLATION_MASK 0xF0 + +/* AM (0xE0 to 0xF7) */ +#define OPL4_REG_TREMOLO 0xE0 +#define OPL4_TREMOLO_DEPTH_MASK 0x07 +#define OPL4_REVERB_SEND_MASK 0xE0 + +/* Mixer */ +#define OPL4_REG_MIX_CONTROL_FM 0xF8 +#define OPL4_REG_MIX_CONTROL_PCM 0xF9 +#define OPL4_MIX_LEFT_MASK 0x07 +#define OPL4_MIX_RIGHT_MASK 0x38 + +#define OPL4_REG_ATC 0xFA +#define OPL4_ATC_BIT 0x01 + +/* Bits in the OPL4 Status register */ +#define OPL4_STATUS_BUSY 0x01 +#define OPL4_STATUS_LOAD 0x02 + +#endif /* __OPL4_DEFINES_H */ diff --git a/src/include/86box/path.h b/src/include/86box/path.h index 5ef0d9488a..f1c5e41774 100644 --- a/src/include/86box/path.h +++ b/src/include/86box/path.h @@ -3,5 +3,6 @@ extern char *path_get_filename(char *s); extern char *path_get_extension(char *s); extern void path_append_filename(char *dest, const char *s1, const char *s2); extern void path_slash(char *path); +extern const char *path_get_slash(char *path); extern void path_normalize(char *path); extern int path_abs(char *path); \ No newline at end of file diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 52c2df9810..8483eb417f 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -11,129 +11,268 @@ * * * Authors: Miran Grca, - * Fred N. van Kempen, - * Sarah Walker, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2008-2020 Sarah Walker. + * Copyright 2023 Miran Grca. */ - #ifndef EMU_PCI_H #define EMU_PCI_H -#define PCI_REG_COMMAND 0x04 +#define PCI_REG_VENDOR_ID_L 0x00 +#define PCI_REG_VENDOR_ID_H 0x01 +#define PCI_REG_DEVICE_ID_L 0x02 +#define PCI_REG_DEVICE_ID_H 0x03 +#define PCI_REG_COMMAND_L 0x04 +#define PCI_REG_COMMAND_H 0x05 +#define PCI_REG_STATUS_L 0x06 +#define PCI_REG_STATUS_H 0x07 +#define PCI_REG_REVISION 0x08 +#define PCI_REG_PROG_IF 0x09 +#define PCI_REG_SUBCLASS 0x0a +#define PCI_REG_CLASS 0x0b +#define PCI_REG_CACHELINE_SIZE 0x0c +#define PCI_REG_LATENCY_TIMER 0x0d +#define PCI_REG_HEADER_TYPE 0x0e +#define PCI_REG_BIST 0x0f + +#define PCI_COMMAND_L_IO 0x01 +#define PCI_COMMAND_L_MEM 0x02 +#define PCI_COMMAND_L_BM 0x04 +#define PCI_COMMAND_L_SPECIAL 0x08 +#define PCI_COMMAND_L_MEM_WIEN 0x10 +#define PCI_COMMAND_L_VGASNOOP 0x20 +#define PCI_COMMAND_L_PARITY 0x40 + +#define PCI_COMMAND_H_SERR 0x01 +#define PCI_COMMAND_H_FAST_B2B 0x02 +#define PCI_COMMAND_H_INT_DIS 0x04 + +#define PCI_STATUS_L_INT 0x08 +#define PCI_STATUS_L_CAPAB 0x10 +#define PCI_STATUS_L_66MHZ 0x20 +#define PCI_STATUS_L_FAST_B2B 0x80 + +#define PCI_STATUS_H_MDPERR 0x01 /* Master Data Parity Error */ +#define PCI_STATUS_H_DEVSEL 0x06 +#define PCI_STATUS_H_STA 0x08 /* Signaled Target Abort */ +#define PCI_STATUS_H_RTA 0x10 /* Received Target Abort */ +#define PCI_STATUS_H_RMA 0x20 /* Received Master Abort */ +#define PCI_STATUS_H_SSE 0x40 /* Signaled System Error */ +#define PCI_STATUS_H_DPERR 0x80 /* Detected Parity Error */ + +#define PCI_DEVSEL_FAST 0x00 +#define PCI_DEVSEL_MEDIUM 0x02 +#define PCI_DEVSEL_SLOW 0x04 + +#define FLAG_MECHANISM_1 0x00000001 +#define FLAG_MECHANISM_2 0x00000002 +#define FLAG_MECHANISM_SWITCH 0x00000004 +#define FLAG_CONFIG_IO_ON 0x00000008 +#define FLAG_CONFIG_DEV0_IO_ON 0x00000010 +#define FLAG_CONFIG_M1_IO_ON 0x00000020 +#define FLAG_NO_IRQ_STEERING 0x00000040 +#define FLAG_NO_BRIDGES 0x00000080 +#define FLAG_TRC_CONTROLS_CPURST 0x00000100 + +#define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2 +#define FLAG_MASK 0x0000007f + +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 + +#define PCI_MIRQ0 0 +#define PCI_MIRQ1 1 +#define PCI_MIRQ2 2 +#define PCI_MIRQ3 3 +#define PCI_MIRQ4 4 +#define PCI_MIRQ5 5 +#define PCI_MIRQ6 6 +#define PCI_MIRQ7 7 + +#define PCI_IRQ_DISABLED -1 + +#define PCI_ADD_STRICT 0x40 +#define PCI_ADD_MASK (PCI_ADD_STRICT - 1) +#define PCI_ADD_VFIO 0x80 +#define PCI_ADD_VFIO_MASK (PCI_ADD_VFIO - 1) -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEM 0x02 +#define PCI_CARD_VFIO PCI_ADD_VFIO -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 -#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 +#define PCI_BUS_INVALID 0xff -#define PCI_CONFIG_TYPE_1 1 -#define PCI_CONFIG_TYPE_2 2 +#define PCI_IGNORE_NO_SLOT 0xff -#define PCI_CONFIG_TYPE_MASK 0x7fff +/* The number of an invalid PCI card. */ +#define PCI_CARD_INVALID 0xef +/* PCI cards (currently 32). */ +#define PCI_CARDS_NUM 0x20 +#define PCI_CARD_MAX (PCI_CARDS_NUM - 1) +/* The number of PCI card INT pins - always at 4 per the PCI specification. */ +#define PCI_INT_PINS_NUM 4 +/* The base for MIRQ lines accepted by pci_irq(). */ +#define PCI_MIRQ_BASE PCI_CARDS_NUM +/* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */ +#define PCI_MIRQS_NUM 8 +#define PCI_MIRQ_MAX (PCI_MIRQS_NUM - 1) +/* The base for direct IRQ lines accepted by pci_irq(). */ +#define PCI_DIRQ_BASE 0xf0 +/* PCI direct IRQ lines (currently 16 because we only emulate the legacy PIC). */ +#define PCI_DIRQS_NUM 16 +#define PCI_DIRQ_MAX (PCI_DIRQS_NUM - 1) +/* PCI IRQ routings (currently 16, this many are needed by the OPTi 822). */ +#define PCI_IRQS_NUM 16 +#define PCI_IRQ_MAX (PCI_IRQS_NUM - 1) -#define PCI_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 +/* Legacy flags. */ +#define PCI_REG_COMMAND PCI_REG_COMMAND_L -#define PCI_MIRQ0 0 -#define PCI_MIRQ1 1 -#define PCI_MIRQ2 2 -#define PCI_MIRQ3 3 -#define PCI_MIRQ4 4 -#define PCI_MIRQ5 5 -#define PCI_MIRQ6 6 -#define PCI_MIRQ7 7 +#define PCI_COMMAND_IO PCI_COMMAND_L_IO +#define PCI_COMMAND_MEM PCI_COMMAND_L_MEM -#define PCI_IRQ_DISABLED -1 +#define PCI_CONFIG_TYPE_1 FLAG_MECHANISM_1 +#define PCI_CONFIG_TYPE_2 FLAG_MECHANISM_2 -#define PCI_ADD_STRICT 0x80 +#define PCI_CAN_SWITCH_TYPE FLAG_MECHANISM_SWITCH +#define PCI_ALWAYS_EXPOSE_DEV0 FLAG_CONFIG_DEV0_IO_ON +#define PCI_NO_IRQ_STEERING FLAG_NO_IRQ_STEERING +#define PCI_NO_BRIDGES FLAG_NO_BRIDGES + +#define PCI_CONFIG_TYPE_MASK FLAG_MECHANISM_MASK + +#define bar_t pci_bar_t +#define trc_init pci_trc_init + +#define pci_register_slot(card, type, inta, intb, intc, intd) \ + pci_register_bus_slot(0, card, type, inta, intb, intc, intd) + +#define pci_set_mirq(mirq, level, irq_state) \ + pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 1, irq_state) +#define pci_set_dirq(irq, irq_state) \ + pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 1, irq_state) +#define pci_set_irq(slot, pci_int, irq_state) \ + pci_irq(slot, pci_int, 0, 1, irq_state) +#define pci_clear_mirq(mirq, level, irq_state) \ + pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 0, irq_state) +#define pci_clear_dirq(dirq, irq_state) \ + pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 0, irq_state) +#define pci_clear_irq(slot, pci_int, irq_state) \ + pci_irq(slot, pci_int, 0, 0, irq_state) enum { - PCI_CARD_NORTHBRIDGE = 0, - PCI_CARD_AGPBRIDGE, - PCI_CARD_SOUTHBRIDGE, - PCI_CARD_SOUTHBRIDGE_IDE, - PCI_CARD_SOUTHBRIDGE_PMU, - PCI_CARD_SOUTHBRIDGE_USB, - PCI_CARD_AGP = 0x0f, - PCI_CARD_NORMAL = 0x10, - PCI_CARD_VIDEO, - PCI_CARD_SCSI, - PCI_CARD_SOUND, - PCI_CARD_IDE, - PCI_CARD_NETWORK, - PCI_CARD_BRIDGE, + PCI_CARD_NORTHBRIDGE = 0, + PCI_CARD_NORTHBRIDGE_SEC = 1, + PCI_CARD_AGPBRIDGE = 2, + PCI_CARD_SOUTHBRIDGE = 3, + PCI_CARD_SOUTHBRIDGE_IDE = 4, + PCI_CARD_SOUTHBRIDGE_PMU = 5, + PCI_CARD_SOUTHBRIDGE_USB = 6, + PCI_CARD_AGP = 0x0f, + PCI_CARD_NORMAL = 0x10, + PCI_CARD_VIDEO = 0x11, + PCI_CARD_HANGUL = 0x12, + PCI_CARD_IDE = 0x13, + PCI_CARD_SCSI = 0x14, + PCI_CARD_SOUND = 0x15, + PCI_CARD_MODEM = 0x16, + PCI_CARD_NETWORK = 0x17, + PCI_CARD_UART = 0x18, + PCI_CARD_USB = 0x19, + PCI_CARD_BRIDGE = 0x1a }; enum { - PCI_ADD_NORTHBRIDGE = 0, - PCI_ADD_AGPBRIDGE, - PCI_ADD_SOUTHBRIDGE, - PCI_ADD_SOUTHBRIDGE_IDE, - PCI_ADD_SOUTHBRIDGE_PMU, - PCI_ADD_SOUTHBRIDGE_USB, - PCI_ADD_AGP = 0x0f, - PCI_ADD_NORMAL = 0x10, - PCI_ADD_VIDEO, - PCI_ADD_SCSI, - PCI_ADD_SOUND, - PCI_ADD_IDE, - PCI_ADD_NETWORK, - PCI_ADD_BRIDGE + PCI_ADD_NORTHBRIDGE = 0, + PCI_ADD_NORTHBRIDGE_SEC = 1, + PCI_ADD_AGPBRIDGE = 2, + PCI_ADD_SOUTHBRIDGE = 3, + PCI_ADD_SOUTHBRIDGE_IDE = 4, + PCI_ADD_SOUTHBRIDGE_PMU = 5, + PCI_ADD_SOUTHBRIDGE_USB = 6, + PCI_ADD_AGP = 0x0f, + PCI_ADD_NORMAL = 0x10, + PCI_ADD_VIDEO = 0x11, + PCI_ADD_HANGUL = 0x12, + PCI_ADD_IDE = 0x13, + PCI_ADD_SCSI = 0x14, + PCI_ADD_SOUND = 0x15, + PCI_ADD_MODEM = 0x16, + PCI_ADD_NETWORK = 0x17, + PCI_ADD_UART = 0x18, + PCI_ADD_USB = 0x19, + PCI_ADD_BRIDGE = 0x1a }; typedef union { uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; + uint8_t addr_regs[4]; +} pci_bar_t; + +extern int pci_burst_time; +extern int agp_burst_time; +extern int pci_nonburst_time; +extern int agp_nonburst_time; + +extern int pci_flags; + +extern uint32_t pci_base; +extern uint32_t pci_size; + +extern void pci_set_irq_routing(int pci_int, int irq); +extern void pci_set_irq_level(int pci_int, int level); +extern void pci_enable_mirq(int mirq); +extern void pci_set_mirq_routing(int mirq, uint8_t irq); +extern uint8_t pci_get_mirq_level(int mirq); +extern void pci_set_mirq_level(int mirq, uint8_t irq); + +/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE + and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's + hack that may no longer be needed). */ +extern void pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state); + +extern uint8_t pci_get_int(uint8_t slot, uint8_t pci_int); + +/* Relocate a PCI device to a new slot, required for the configurable + IDSEL's of ALi M1543(c). */ +extern void pci_relocate_slot(int type, int new_slot); -extern int pci_burst_time; -extern int agp_burst_time; -extern int pci_nonburst_time; -extern int agp_nonburst_time; +/* Write PCI enable/disable key, split for the ALi M1435. */ +extern void pci_key_write(uint8_t val); -extern void pci_set_irq_routing(int pci_int, int irq); -extern void pci_set_irq_level(int pci_int, int level); +/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */ +extern void pci_set_pmc(uint8_t pmc); -extern void pci_enable_mirq(int mirq); -extern void pci_set_mirq_routing(int mirq, int irq); +extern void pci_pic_reset(void); +extern void pci_reset(void); -extern int pci_irq_is_level(int irq); +/* Needed for the io.c handling of configuration mechanism #2 ports C000-CFFF. */ +extern void pci_write(uint16_t port, uint8_t val, void *priv); +extern void pci_writew(uint16_t port, uint16_t val, void *priv); +extern void pci_writel(uint16_t port, uint32_t val, void *priv); +extern uint8_t pci_read(uint16_t port, void *priv); +extern uint16_t pci_readw(uint16_t port, void *priv); +extern uint32_t pci_readl(uint16_t port, void *priv); -extern void pci_set_mirq(uint8_t mirq, int level); -extern void pci_set_irq(uint8_t card, uint8_t pci_int); -extern void pci_clear_mirq(uint8_t mirq, int level); -extern void pci_clear_irq(uint8_t card, uint8_t pci_int); -extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int); +extern uint8_t pci_register_bus(void); +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); -extern void pci_reset(void); -extern void pci_init(int type); -extern uint8_t pci_register_bus(void); -extern void pci_set_pmc(uint8_t pmc); -extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); -extern void pci_relocate_slot(int type, int new_slot); -extern void pci_register_slot(int card, int type, - int inta, int intb, int intc, int intd); -extern void pci_register_bus_slot(int bus, int card, int type, - int inta, int intb, int intc, int intd); -extern void pci_close(void); -extern uint8_t 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); +/* 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 trc_init(void); +/* 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, + uint8_t *slot); -extern uint8_t trc_read(uint16_t port, void *priv); -extern void trc_write(uint16_t port, uint8_t val, void *priv); +/* Register the cards that have been added into slots. */ +extern void pci_register_cards(void); -extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); +extern void pci_init(int flags); -extern void pci_pic_reset(void); +/* PCI bridge stuff. */ +extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); #ifdef EMU_DEVICE_H extern const device_t dec21150_device; @@ -147,6 +286,7 @@ extern const device_t via_vp3_agp_device; extern const device_t via_mvp3_agp_device; extern const device_t via_apro_agp_device; extern const device_t via_vt8601_agp_device; +extern const device_t sis_5xxx_agp_device; #endif #endif /*EMU_PCI_H*/ diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 25c8662421..798cc33572 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -19,12 +19,39 @@ #ifndef EMU_PIC_H #define EMU_PIC_H +typedef struct pic_latch { + uint8_t d; + uint8_t e; + uint8_t q; + uint8_t nq; +} pic_latch_t; + typedef struct pic { - uint8_t icw1, icw2, icw3, icw4, - imr, isr, irr, ocw2, - ocw3, int_pending, is_master, elcr, - state, ack_bytes, priority, special_mask_mode, - auto_eoi_rotate, interrupt, lines, data_bus; + uint8_t icw1; + uint8_t icw2; + uint8_t icw3; + uint8_t icw4; + uint8_t imr; + uint8_t isr; + uint8_t irr; + uint8_t ocw2; + uint8_t ocw3; + uint8_t int_pending; + uint8_t is_master; + uint8_t elcr; + uint8_t state; + uint8_t ack_bytes; + uint8_t priority; + uint8_t special_mask_mode; + uint8_t auto_eoi_rotate; + uint8_t interrupt; + uint8_t data_bus; + uint8_t irq_latch; + uint8_t has_slaves; + uint8_t flags; + uint8_t edge_lines; + uint8_t pad; + uint32_t lines[8]; uint32_t at; struct pic *slaves[8]; } pic_t; @@ -54,12 +81,24 @@ extern void pic_init_pcjr(void); extern void pic2_init(void); extern void pic_reset(void); -extern int picint_is_level(int irq); -extern void picint_common(uint16_t num, int level, int set); -extern void picint(uint16_t num); -extern void picintlevel(uint16_t num); -extern void picintc(uint16_t num); -extern int picinterrupt(void); +extern uint8_t pic_read_icw(uint8_t pic_id, uint8_t icw); +extern uint8_t pic_read_ocw(uint8_t pic_id, uint8_t ocw); +extern int picint_is_level(int irq); +extern void picint_common(uint16_t num, int level, int set, uint8_t *irq_state); +extern int picinterrupt(void); + +#define PIC_IRQ_EDGE 0 +#define PIC_IRQ_LEVEL 1 + +#define PIC_SLAVE_PENDING 0x01 +#define PIC_FREEZE 0x02 +#define PIC_MASTER_CLEAR 0x04 + +/* Legacy defines. */ +#define picint(num) picint_common(num, PIC_IRQ_EDGE, 1, NULL) +#define picintlevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 1, irq_state) +#define picintc(num) picint_common(num, PIC_IRQ_EDGE, 0, NULL) +#define picintclevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 0, irq_state) extern uint8_t pic_irq_ack(void); diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index a9d114d8e8..d288b7e6c7 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -19,26 +19,38 @@ #ifndef EMU_PIT_H #define EMU_PIT_H -typedef struct { - uint8_t m, ctrl, - read_status, latch, - s1_det, l_det, - bcd, incomplete; +typedef struct ctr_t { + uint8_t m; + uint8_t ctrl; + uint8_t read_status; + uint8_t latch; + uint8_t s1_det; + uint8_t l_det; + uint8_t bcd; + uint8_t incomplete; uint16_t rl; - int rm, wm, gate, out, - newcount, clock, using_timer, latched, - state, null_count, do_read_status; + int rm; + int wm; + int gate; + int out; + int newcount; + int clock; + int using_timer; + int latched; + int state; + int null_count; + int do_read_status; union { - int count; + int32_t count; struct { - int units : 4; - int tens : 4; - int hundreds : 4; - int thousands : 4; - int myriads : 4; + int32_t units : 4; + int32_t tens : 4; + int32_t hundreds : 4; + int32_t thousands : 4; + int32_t myriads : 4; }; }; @@ -49,7 +61,8 @@ typedef struct { } ctr_t; typedef struct PIT { - int flags, clock; + int flags; + int clock; pc_timer_t callback_timer; ctr_t counters[3]; @@ -58,13 +71,13 @@ typedef struct PIT { } pit_t; enum { - PIT_8253 = 0, - PIT_8254, - PIT_8253_FAST, - PIT_8254_FAST + PIT_8253 = 0, + PIT_8254 = 1, + PIT_8253_FAST = 2, + PIT_8254_FAST = 3 }; -typedef struct { +typedef struct pit_intf_t { uint8_t (*read)(uint16_t addr, void *priv); void (*write)(uint16_t addr, uint8_t val, void *priv); /* Gets a counter's count. */ @@ -115,9 +128,11 @@ extern void pit_speaker_timer(int new_out, int old_out); extern void pit_nmi_timer_ps2(int new_out, int old_out); -extern void pit_set_clock(int clock); +extern void pit_set_clock(uint32_t clock); extern void pit_handler(int set, uint16_t base, int size, void *priv); +extern uint8_t pit_read_reg(void *priv, uint8_t reg); + #ifdef EMU_DEVICE_H extern const device_t i8253_device; extern const device_t i8254_device; diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index 242fb4207d..2485a360ce 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -19,15 +19,24 @@ #ifndef EMU_PIT_FAST_H #define EMU_PIT_FAST_H -typedef struct { - uint8_t m, ctrl, - read_status, latch, bcd; +typedef struct ctrf_t { + uint8_t m; + uint8_t ctrl; + uint8_t read_status; + uint8_t latch; + uint8_t bcd; uint16_t rl; - int rm, wm, gate, out, - newcount, clock, using_timer, latched, - do_read_status; + int rm; + int wm; + int gate; + int out; + int newcount; + int clock; + int using_timer; + int latched; + int do_read_status; int enabled; int disabled; int initial; @@ -36,13 +45,13 @@ typedef struct { int rereadlatch; union { - int count; + int32_t count; struct { - int units : 4; - int tens : 4; - int hundreds : 4; - int thousands : 4; - int myriads : 4; + int32_t units : 4; + int32_t tens : 4; + int32_t hundreds : 4; + int32_t thousands : 4; + int32_t myriads : 4; }; }; @@ -53,13 +62,15 @@ typedef struct { void (*out_func)(int new_out, int old_out); } ctrf_t; -typedef struct { +typedef struct pitf_t { int flags; ctrf_t counters[3]; uint8_t ctrl; } pitf_t; +extern uint8_t pitf_read_reg(void *priv, uint8_t reg); + extern const pit_intf_t pit_fast_intf; #ifdef EMU_DEVICE_H diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 05b9822169..84f0318c2e 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -49,7 +49,7 @@ extern int strnicmp(const char *s1, const char *s2, size_t n); # define ftello64 ftello # define off64_t off_t #elif defined(_MSC_VER) -// # define fopen64 fopen +// # define fopen64 fopen # define fseeko64 _fseeki64 # define ftello64 _ftelli64 # define off64_t off_t @@ -80,10 +80,23 @@ extern "C" { # define ssize_t intptr_t #endif +#ifdef _MSC_VER +# define fallthrough do {} while (0) /* fallthrough */ +#else +# if __has_attribute(fallthrough) +# define fallthrough __attribute__((fallthrough)) +# else +# if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +# endif +# define fallthrough do {} while (0) /* fallthrough */ +# endif +#endif + /* Global variables residing in the platform module. */ -extern int dopause, /* system is paused */ - mouse_capture; /* mouse is captured in app */ -extern volatile int is_quit; /* system exit requested */ +extern int dopause; /* system is paused */ +extern int mouse_capture; /* mouse is captured in app */ +extern volatile int is_quit; /* system exit requested */ #ifdef MTR_ENABLED extern int tracing_on; @@ -95,7 +108,9 @@ extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; -extern int kbd_req_capture, hide_status_bar, hide_tool_bar; +extern int kbd_req_capture; +extern int hide_status_bar; +extern int hide_tool_bar; /* System-related functions. */ extern char *fix_exe_path(char *str); @@ -131,6 +146,9 @@ extern void plat_vidapi_reload(void); extern void plat_vid_reload_options(void); extern uint32_t plat_language_code(char *langcode); extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len); +extern void plat_get_cpu_string(char *outbuf, uint8_t len); +extern double plat_get_dpi(void); +extern void plat_set_thread_name(void *thread, const char *name); /* Resource management. */ extern void set_language(uint32_t id); diff --git a/src/include/86box/plat_dir.h b/src/include/86box/plat_dir.h index 899ff325ea..965483d26a 100644 --- a/src/include/86box/plat_dir.h +++ b/src/include/86box/plat_dir.h @@ -39,24 +39,24 @@ struct dirent { }; # define d_namlen d_reclen -typedef struct { - short flags; /* internal flags */ - short offset; /* offset of entry into dir */ - long handle; /* open handle to Win32 system */ - short sts; /* last known status code */ - char *dta; /* internal work data */ +typedef struct DIR_t { + short flags; /* internal flags */ + short offset; /* offset of entry into dir */ + long handle; /* open handle to Win32 system */ + short sts; /* last known status code */ + char *dta; /* internal work data */ # ifdef UNICODE - wchar_t dir[MAXDIRLEN + 1]; /* open dir */ + wchar_t dir[MAXDIRLEN + 1]; /* open dir */ # else - char dir[MAXDIRLEN + 1]; /* open dir */ + char dir[MAXDIRLEN + 1]; /* open dir */ # endif - struct dirent dent; /* actual directory entry */ + struct dirent dent; /* actual directory entry */ } DIR; /* Directory routine flags. */ -# define DIR_F_LOWER 0x0001 /* force to lowercase */ -# define DIR_F_SANE 0x0002 /* force this to sane path */ -# define DIR_F_ISROOT 0x0010 /* this is the root directory */ +# define DIR_F_LOWER 0x0001 /* force to lowercase */ +# define DIR_F_SANE 0x0002 /* force this to sane path */ +# define DIR_F_ISROOT 0x0010 /* this is the root directory */ /* Function prototypes. */ extern DIR *opendir(const char *); @@ -66,12 +66,9 @@ extern void seekdir(DIR *, long); extern int closedir(DIR *); # define rewinddir(dirp) seekdir(dirp, 0L) -#elif defined(__FreeBSD__) -/* FreeBSD uses dirent.h instead of sys/dir.h */ -# include #else /* On linux and macOS, use the standard functions and types */ -# include +# include #endif #endif /*PLAT_DIR_H*/ diff --git a/src/include/86box/plat_dynld.h b/src/include/86box/plat_dynld.h index 986e724245..44891d4ace 100644 --- a/src/include/86box/plat_dynld.h +++ b/src/include/86box/plat_dynld.h @@ -18,7 +18,7 @@ #ifndef PLAT_DYNLD_H #define PLAT_DYNLD_H -typedef struct { +typedef struct dllimp_t { const char *name; void *func; } dllimp_t; diff --git a/src/include/86box/plat_fallthrough.h b/src/include/86box/plat_fallthrough.h new file mode 100644 index 0000000000..6165b266c3 --- /dev/null +++ b/src/include/86box/plat_fallthrough.h @@ -0,0 +1,36 @@ +/* + * 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. + * + * Define the various platform support functions. + * + * + * + * Authors: Jasmine Iwanek, + * + * Copyright 2023 Jasmine Iwanek + */ + +#ifndef EMU_PLAT_FALLTHROUGH_H +#define EMU_PLAT_FALLTHROUGH_H + +#ifndef EMU_PLAT_H +#ifdef _MSC_VER +# define fallthrough do {} while (0) /* fallthrough */ +#else +# if __has_attribute(fallthrough) +# define fallthrough __attribute__((fallthrough)) +# else +# if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +# endif +# define fallthrough do {} while (0) /* fallthrough */ +# endif +#endif +#endif + +#endif /*EMU_PLAT_FALLTHROUGH_H*/ diff --git a/src/include/86box/plat_serial_passthrough.h b/src/include/86box/plat_serial_passthrough.h index e9df0584eb..60674ea589 100644 --- a/src/include/86box/plat_serial_passthrough.h +++ b/src/include/86box/plat_serial_passthrough.h @@ -25,11 +25,11 @@ extern "C" { #endif -extern void plat_serpt_write(void *p, uint8_t data); -extern int plat_serpt_read(void *p, uint8_t *data); -extern int plat_serpt_open_device(void *p); -extern void plat_serpt_close(void *p); -extern void plat_serpt_set_params(void *p); +extern void plat_serpt_write(void *priv, uint8_t data); +extern int plat_serpt_read(void *priv, uint8_t *data); +extern int plat_serpt_open_device(void *priv); +extern void plat_serpt_close(void *priv); +extern void plat_serpt_set_params(void *priv); #ifdef __cplusplus } diff --git a/src/include/86box/plat_unused.h b/src/include/86box/plat_unused.h new file mode 100644 index 0000000000..226cf677dc --- /dev/null +++ b/src/include/86box/plat_unused.h @@ -0,0 +1,33 @@ +/* + * 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. + * + * Define the various platform support functions. + * + * + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2021 Laci bá' + */ + +#ifndef EMU_PLAT_UNUSED_H +#define EMU_PLAT_UNUSED_H + +#ifndef EMU_PLAT_H +#ifdef _MSC_VER +# define UNUSED(arg) arg +#else +/* A hack (GCC-specific?) to allow us to ignore unused parameters. */ +# define UNUSED(arg) __attribute__((unused)) arg +#endif +#endif + +#endif /*EMU_PLAT_UNUSED_H*/ diff --git a/src/include/86box/port_6x.h b/src/include/86box/port_6x.h index 7eb0c9a56a..e0c4b0508f 100644 --- a/src/include/86box/port_6x.h +++ b/src/include/86box/port_6x.h @@ -20,9 +20,9 @@ #define EMU_PORT_6X_H #ifdef _TIMER_H_ -typedef struct -{ - uint8_t refresh, flags; +typedef struct port_6x_t { + uint8_t refresh; + uint8_t flags; pc_timer_t refresh_timer; } port_6x_t; diff --git a/src/include/86box/port_92.h b/src/include/86box/port_92.h index 319b2b3ac8..2dd4319be6 100644 --- a/src/include/86box/port_92.h +++ b/src/include/86box/port_92.h @@ -20,9 +20,9 @@ #define EMU_PORT_92_H #ifdef _TIMER_H_ -typedef struct -{ - uint8_t reg, flags; +typedef struct port_92_t { + uint8_t reg; + uint8_t flags; pc_timer_t pulse_timer; diff --git a/src/include/86box/ppi.h b/src/include/86box/ppi.h index 0e12c98f86..d5649bcc82 100644 --- a/src/include/86box/ppi.h +++ b/src/include/86box/ppi.h @@ -3,7 +3,8 @@ typedef struct PPI { int s2; - uint8_t pa, pb; + uint8_t pa; + uint8_t pb; } PPI; extern int ppispeakon; diff --git a/src/include/86box/printer.h b/src/include/86box/printer.h index eb6eb4a753..b576fbf27a 100644 --- a/src/include/86box/printer.h +++ b/src/include/86box/printer.h @@ -46,7 +46,8 @@ #ifndef PRINTER_H #define PRINTER_H -#define FONT_FILE_DOTMATRIX "dotmatrix.ttf" +#define FONT_FILE_DOTMATRIX "dotmatrix.otf" +#define FONT_FILE_DOTMATRIX_ITALIC "dotmatrix_italic.otf" #define FONT_FILE_ROMAN "roman.ttf" #define FONT_FILE_SANSSERIF "sansserif.ttf" diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 2080c3a3b5..2e6628c772 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -67,7 +67,7 @@ #define IDT_CPU_SPEED 1710 /* CPU speed: */ #define IDT_FPU 1711 /* FPU: */ #define IDT_WAIT_STATES 1712 /* Wait states: */ -#define IDT_MB 1713 /* MB == IDC_TEXT_MB */ +#define IDT_MB 1713 /* MB == IDC_TEXT_MB */ #define IDT_MEMORY 1714 /* Memory: */ /* DLG_CFG_VIDEO */ @@ -79,10 +79,10 @@ #define IDT_JOYSTICK 1718 /* Joystick: */ /* DLG_CFG_SOUND */ -#define IDT_SOUND1 1719 /* Sound card 1: */ -#define IDT_SOUND2 1720 /* Sound card 2: */ -#define IDT_SOUND3 1721 /* Sound card 3: */ -#define IDT_SOUND4 1722 /* Sound card 4: */ +#define IDT_SOUND1 1719 /* Sound card #1: */ +#define IDT_SOUND2 1720 /* Sound card #2: */ +#define IDT_SOUND3 1721 /* Sound card #3: */ +#define IDT_SOUND4 1722 /* Sound card #4: */ #define IDT_MIDI_OUT 1723 /* MIDI Out Device: */ #define IDT_MIDI_IN 1724 /* MIDI In Device: */ diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 91f813a956..1f6e611b12 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -32,7 +32,7 @@ #define bios_load_interleavedr(a, b, c, d, e) bios_load(a, b, c, d, e, FLAG_INT | FLAG_REP) #define bios_load_aux_interleaved(a, b, c, d, e) bios_load(a, b, c, d, e, FLAG_INT | FLAG_AUX) -typedef struct { +typedef struct rom_t { uint8_t *rom; int sz; uint32_t mask; @@ -48,13 +48,13 @@ extern rom_path_t rom_paths; extern void rom_add_path(const char *path); -extern uint8_t rom_read(uint32_t addr, void *p); -extern uint16_t rom_readw(uint32_t addr, void *p); -extern uint32_t rom_readl(uint32_t addr, void *p); +extern uint8_t rom_read(uint32_t addr, void *priv); +extern uint16_t rom_readw(uint32_t addr, void *priv); +extern uint32_t rom_readl(uint32_t addr, void *priv); extern FILE *rom_fopen(const char *fn, char *mode); extern int rom_getfile(char *fn, char *s, int size); -extern int rom_present(char *fn); +extern int rom_present(const char *fn); extern int rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr); diff --git a/src/include/86box/row.h b/src/include/86box/row.h new file mode 100644 index 0000000000..a70c942742 --- /dev/null +++ b/src/include/86box/row.h @@ -0,0 +1,42 @@ +/* + * 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. + * + * Definitions for the SMRAM interface. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2020 Miran Grca. + */ + +#ifndef EMU_ROW_H +# define EMU_ROW_H + +typedef struct _row_ { + struct _smram_ *prev; + struct _smram_ *next; + + uint8_t *buf; + + mem_mapping_t mapping; + + uint32_t host_base; + uint32_t host_size; + uint32_t ram_base; + uint32_t ram_size; + uint32_t ram_mask; + uint32_t boundary; +} row_t; + +extern void row_disable(uint8_t row_id); +extern void row_set_boundary(uint8_t row_id, uint32_t boundary); + +extern device_t row_device; + +#endif /*EMU_ROW_H*/ diff --git a/src/include/86box/scsi.h b/src/include/86box/scsi.h index d194971014..376ac79b92 100644 --- a/src/include/86box/scsi.h +++ b/src/include/86box/scsi.h @@ -33,9 +33,9 @@ extern int scsi_card_available(int card); #ifdef EMU_DEVICE_H extern const device_t *scsi_card_getdevice(int card); #endif -extern int scsi_card_has_config(int card); -extern char *scsi_card_get_internal_name(int card); -extern int scsi_card_get_from_internal_name(char *s); -extern void scsi_card_init(void); +extern int scsi_card_has_config(int card); +extern const char *scsi_card_get_internal_name(int card); +extern int scsi_card_get_from_internal_name(char *s); +extern void scsi_card_init(void); #endif /*EMU_SCSI_H*/ diff --git a/src/include/86box/scsi_aha154x.h b/src/include/86box/scsi_aha154x.h index 3c82653919..800d2d72b9 100644 --- a/src/include/86box/scsi_aha154x.h +++ b/src/include/86box/scsi_aha154x.h @@ -8,6 +8,6 @@ extern const device_t aha154xcf_device; extern const device_t aha154xcp_device; extern const device_t aha1640_device; -extern void aha_device_reset(void *p); +extern void aha_device_reset(void *priv); #endif /*SCSI_AHA154X_H*/ diff --git a/src/include/86box/scsi_buslogic.h b/src/include/86box/scsi_buslogic.h index 12bff6fdf0..6de69e7007 100644 --- a/src/include/86box/scsi_buslogic.h +++ b/src/include/86box/scsi_buslogic.h @@ -29,6 +29,6 @@ extern const device_t buslogic_445s_device; extern const device_t buslogic_445c_device; extern const device_t buslogic_958d_pci_device; -extern void BuslogicDeviceReset(void *p); +extern void BuslogicDeviceReset(void *priv); #endif /*SCSI_BUSLOGIC_H*/ diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index 6b94c2aa49..dec537429e 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -22,37 +22,59 @@ #define CDROM_TIME 10.0 #ifdef SCSI_DEVICE_H -typedef struct { +typedef struct scsi_cdrom_t { /* Common block. */ mode_sense_pages_t ms_pages_saved; - cdrom_t *drv; + cdrom_t * drv; +#ifdef EMU_IDE_H + ide_tf_t *tf; +#else + void * tf; +#endif + + uint8_t *buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; - uint8_t *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; + uint8_t phase; + uint16_t request_length; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif - uint8_t status, phase, - error, id, - features, cur_lun, - early, pad1; + uint8_t id; + uint8_t cur_lun; + uint8_t early; + uint8_t pad1; - uint16_t request_length, max_transfer_len; + uint16_t max_transfer_len; + uint16_t pad2; - int requested_blocks, packet_status, - total_length, do_page_save, - unit_attention, request_pos, - old_len, media_status; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int media_status; - uint32_t sector_pos, sector_len, - packet_len, pos; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; double callback; mode_sense_pages_t ms_pages_saved_sony; mode_sense_pages_t ms_drive_status_pages_saved; - int sony_vendor; + int sony_vendor; } scsi_cdrom_t; #endif diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 61048fb54b..09f9ee2d9a 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -43,142 +43,144 @@ #define MCR_ERR 0x08 /* Media change request */ /* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_IOMEGA_SENSE 0x06 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c -#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ -#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command */ -#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command */ -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_SCSI_RESERVE 0x16 -#define GPCMD_SCSI_RELEASE 0x17 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_SEND_DIAGNOSTIC 0x1d -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_FORMAT_CAPACITIES 0x23 -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_UNKNOWN_CHINON 0x26 /*Chinon Vendor Unique command*/ -#define GPCMD_READ_10 0x28 -#define GPCMD_READ_GENERATION 0x29 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_ERASE_10 0x2c -#define GPCMD_WRITE_AND_VERIFY_10 0x2e -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_READ_BUFFER 0x3c -#define GPCMD_WRITE_SAME_10 0x41 -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10 0x49 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12 0xa9 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_ERASE_12 0xac -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_WRITE_AND_VERIFY_12 0xae -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_AUDIO_SCAN 0xba -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ -#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */ -#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */ -#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */ -#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */ -#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */ -#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */ -#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */ -#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */ -#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */ -#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */ -#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */ -#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ -#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ -#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */ -#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ -#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/ -#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/ -#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */ +#define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REZERO_UNIT 0x01 +#define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_FORMAT_UNIT 0x04 +#define GPCMD_IOMEGA_SENSE 0x06 +#define GPCMD_READ_6 0x08 +#define GPCMD_WRITE_6 0x0a +#define GPCMD_SEEK_6 0x0b +#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c +#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ +#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command */ +#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command */ +#define GPCMD_INQUIRY 0x12 +#define GPCMD_VERIFY_6 0x13 +#define GPCMD_MODE_SELECT_6 0x15 +#define GPCMD_SCSI_RESERVE 0x16 +#define GPCMD_SCSI_RELEASE 0x17 +#define GPCMD_MODE_SENSE_6 0x1a +#define GPCMD_START_STOP_UNIT 0x1b +#define GPCMD_SEND_DIAGNOSTIC 0x1d +#define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_FORMAT_CAPACITIES 0x23 +#define GPCMD_READ_CDROM_CAPACITY 0x25 +#define GPCMD_UNKNOWN_CHINON 0x26 /*Chinon Vendor Unique command*/ +#define GPCMD_READ_10 0x28 +#define GPCMD_READ_GENERATION 0x29 +#define GPCMD_WRITE_10 0x2a +#define GPCMD_SEEK_10 0x2b +#define GPCMD_ERASE_10 0x2c +#define GPCMD_WRITE_AND_VERIFY_10 0x2e +#define GPCMD_VERIFY_10 0x2f +#define GPCMD_READ_BUFFER 0x3c +#define GPCMD_WRITE_SAME_10 0x41 +#define GPCMD_READ_SUBCHANNEL 0x42 +#define GPCMD_READ_TOC_PMA_ATIP 0x43 +#define GPCMD_READ_HEADER 0x44 +#define GPCMD_PLAY_AUDIO_10 0x45 +#define GPCMD_GET_CONFIGURATION 0x46 +#define GPCMD_PLAY_AUDIO_MSF 0x47 +#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 +#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10 0x49 +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a +#define GPCMD_PAUSE_RESUME 0x4b +#define GPCMD_STOP_PLAY_SCAN 0x4e +#define GPCMD_READ_DISC_INFORMATION 0x51 +#define GPCMD_READ_TRACK_INFORMATION 0x52 +#define GPCMD_MODE_SELECT_10 0x55 +#define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_PLAY_AUDIO_12 0xa5 +#define GPCMD_READ_12 0xa8 +#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12 0xa9 +#define GPCMD_WRITE_12 0xaa +#define GPCMD_ERASE_12 0xac +#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ +#define GPCMD_WRITE_AND_VERIFY_12 0xae +#define GPCMD_VERIFY_12 0xaf +#define GPCMD_PLAY_CD_OLD 0xb4 +#define GPCMD_READ_CD_OLD 0xb8 +#define GPCMD_READ_CD_MSF 0xb9 +#define GPCMD_AUDIO_SCAN 0xba +#define GPCMD_SET_SPEED 0xbb +#define GPCMD_PLAY_CD 0xbc +#define GPCMD_MECHANISM_STATUS 0xbd +#define GPCMD_READ_CD 0xbe +#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ +#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */ +#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */ +#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */ +#define GPCMD_PAUSE_RESUME_ALT 0xc2 +#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */ +#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */ +#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */ +#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */ +#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */ +#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */ +#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ +#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ +#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */ +#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ +#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/ +#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/ +#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /*Matsushita Vendor Unique command */ -#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */ -#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */ -#define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */ -#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ -#define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */ -#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */ -#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */ -#define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */ +#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */ +#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */ +#define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */ +#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */ +#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ +#define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */ +#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */ +#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */ +#define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */ /* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */ -#define GPMODE_FORMAT_DEVICE_PAGE 0x03 -#define GPMODE_RIGID_DISK_PAGE 0x04 /* Rigid disk geometry page */ -#define GPMODE_FLEXIBLE_DISK_PAGE 0x05 -#define GPMODE_CACHING_PAGE 0x08 -#define GPMODE_CDROM_PAGE_SONY 0x08 +#define GPMODE_UNIT_ATN_PAGE 0x00 +#define GPMODE_R_W_ERROR_PAGE 0x01 +#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */ +#define GPMODE_FORMAT_DEVICE_PAGE 0x03 +#define GPMODE_RIGID_DISK_PAGE 0x04 /* Rigid disk geometry page */ +#define GPMODE_FLEXIBLE_DISK_PAGE 0x05 +#define GPMODE_CACHING_PAGE 0x08 +#define GPMODE_CDROM_PAGE_SONY 0x08 #define GPMODE_CDROM_AUDIO_PAGE_SONY 0x09 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_IOMEGA_PAGE 0x2f -#define GPMODE_UNK_VENDOR_PAGE 0x30 -#define GPMODE_ALL_PAGES 0x3f +#define GPMODE_CDROM_PAGE 0x0d +#define GPMODE_CDROM_AUDIO_PAGE 0x0e +#define GPMODE_CAPABILITIES_PAGE 0x2a +#define GPMODE_IOMEGA_PAGE 0x2f +#define GPMODE_UNK_VENDOR_PAGE 0x30 +#define GPMODE_ALL_PAGES 0x3f /* Mode page codes for presence */ -#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL -#define GPMODEP_DISCONNECT_PAGE 0x0000000000000004LL -#define GPMODEP_FORMAT_DEVICE_PAGE 0x0000000000000008LL -#define GPMODEP_RIGID_DISK_PAGE 0x0000000000000010LL -#define GPMODEP_FLEXIBLE_DISK_PAGE 0x0000000000000020LL -#define GPMODEP_CACHING_PAGE 0x0000000000000100LL -#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000200LL +#define GPMODEP_UNIT_ATN_PAGE 0x0000000000000001LL +#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL +#define GPMODEP_DISCONNECT_PAGE 0x0000000000000004LL +#define GPMODEP_FORMAT_DEVICE_PAGE 0x0000000000000008LL +#define GPMODEP_RIGID_DISK_PAGE 0x0000000000000010LL +#define GPMODEP_FLEXIBLE_DISK_PAGE 0x0000000000000020LL +#define GPMODEP_CACHING_PAGE 0x0000000000000100LL +#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000200LL #define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000400LL -#define GPMODEP_CDROM_PAGE 0x0000000000002000LL -#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL -#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL -#define GPMODEP_IOMEGA_PAGE 0x0000800000000000LL -#define GPMODEP_UNK_VENDOR_PAGE 0x0001000000000000LL -#define GPMODEP_ALL_PAGES 0x8000000000000000LL +#define GPMODEP_CDROM_PAGE 0x0000000000002000LL +#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL +#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL +#define GPMODEP_IOMEGA_PAGE 0x0000800000000000LL +#define GPMODEP_UNK_VENDOR_PAGE 0x0001000000000000LL +#define GPMODEP_ALL_PAGES 0x8000000000000000LL /* SCSI Status Codes */ #define SCSI_STATUS_OK 0 @@ -224,12 +226,12 @@ #define RW_DELAY (TIMER_USEC * 500) /* Some generally useful CD-ROM information */ -#define CD_MINS 75 /* max. minutes per CD */ +#define CD_MINS 90 /* max. minutes per CD */ #define CD_SECS 60 /* seconds per minute */ #define CD_FRAMES 75 /* frames per second */ #define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ #define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) -#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) +#define CD_MAX_SECTORS (CD_MAX_BYTES / 2048) /* Event notification classes for GET EVENT STATUS NOTIFICATION */ #define GESN_NO_EVENTS 0 @@ -338,7 +340,7 @@ #define MODE_SELECT_PHASE_PAGE_HEADER 3 #define MODE_SELECT_PHASE_PAGE 4 -typedef struct { +typedef struct mode_sense_pages_t { uint8_t pages[0x40][0x40]; } mode_sense_pages_t; @@ -347,45 +349,68 @@ typedef struct { typedef struct scsi_common_s { mode_sense_pages_t ms_pages_saved; - void *p; + void * priv; +#ifdef EMU_IDE_H + ide_tf_t *tf; +#else + void * tf; +#endif - uint8_t *temp_buffer, - atapi_cdb[16], /* This is atapi_cdb in ATAPI-supporting devices, - and pad in SCSI-only devices. */ - current_cdb[16], - sense[256]; + uint8_t *temp_buffer; + uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices, + and pad in SCSI-only devices. */ + uint8_t current_cdb[16]; + uint8_t sense[256]; + +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; + uint8_t phase; + uint16_t request_length; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif - uint8_t status, phase, - error, id, - features, cur_lun, - pad0, pad1; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - uint16_t request_length, max_transfer_len; + uint16_t max_transfer_len; + uint16_t pad2; - int requested_blocks, packet_status, - total_length, do_page_save, - unit_attention, request_pos, - old_len, media_status; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int media_status; - uint32_t sector_pos, sector_len, - packet_len, pos; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; double callback; } scsi_common_t; -typedef struct { +typedef struct scsi_device_t { int32_t buffer_length; - uint8_t status, phase; + uint8_t status; + uint8_t phase; uint16_t type; scsi_common_t *sc; - void (*command)(scsi_common_t *sc, uint8_t *cdb); - void (*request_sense)(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length); - void (*reset)(scsi_common_t *sc); + void (*command)(scsi_common_t *sc, uint8_t *cdb); + void (*request_sense)(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length); + void (*reset)(scsi_common_t *sc); uint8_t (*phase_data_out)(scsi_common_t *sc); - void (*command_stop)(scsi_common_t *sc); + void (*command_stop)(scsi_common_t *sc); } scsi_device_t; /* These are based on the INQUIRY values. */ @@ -423,4 +448,7 @@ extern void scsi_device_init(void); extern void scsi_reset(void); extern uint8_t scsi_get_bus(void); +extern void scsi_bus_set_speed(uint8_t bus, double speed); +extern double scsi_bus_get_speed(uint8_t bus); + #endif /*SCSI_DEVICE_H*/ diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index bff40a396f..eb4dc69a41 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -16,37 +16,60 @@ #ifndef SCSI_DISK_H #define SCSI_DISK_H -typedef struct { +typedef struct scsi_disk_t { mode_sense_pages_t ms_pages_saved; hard_disk_t *drv; +#ifdef EMU_IDE_H + ide_tf_t * tf; +#else + void * tf; +#endif - uint8_t *temp_buffer, - pad[16], /* This is atapi_cdb in ATAPI-supporting devices, - and pad in SCSI-only devices. */ - current_cdb[16], - sense[256]; + uint8_t *temp_buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; - uint8_t status, phase, - error, id, - pad0, cur_lun, - pad1, pad2; +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; + uint8_t phase; + uint16_t request_length; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif - uint16_t request_length, pad4; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - int requested_blocks, packet_status, - total_length, do_page_save, - unit_attention, pad5, - pad6, pad7; + uint16_t max_transfer_len; + uint16_t pad2; - uint32_t sector_pos, sector_len, - packet_len, pos; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int pad6; + int pad7; + + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; double callback; } scsi_disk_t; extern scsi_disk_t *scsi_disk[HDD_NUM]; +extern void scsi_disk_reset(scsi_common_t *sc); + extern void scsi_disk_hard_reset(void); extern void scsi_disk_close(void); diff --git a/src/include/86box/scsi_pcscsi.h b/src/include/86box/scsi_pcscsi.h index 0ce353d33f..3acee78f9c 100644 --- a/src/include/86box/scsi_pcscsi.h +++ b/src/include/86box/scsi_pcscsi.h @@ -26,6 +26,6 @@ #define SCSI_PCSCSI_H extern const device_t dc390_pci_device; -extern const device_t ncr53c90_mca_device; +extern const device_t ncr53c90a_mca_device; #endif /*SCSI_BUSLOGIC_H*/ diff --git a/src/include/86box/scsi_spock.h b/src/include/86box/scsi_spock.h index bfa579c824..0572717720 100644 --- a/src/include/86box/scsi_spock.h +++ b/src/include/86box/scsi_spock.h @@ -22,5 +22,6 @@ #define SCSI_SPOCK_H extern const device_t spock_device; +extern const device_t tribble_device; #endif /*SCSI_SPOCK_H*/ diff --git a/src/include/86box/scsi_x54x.h b/src/include/86box/scsi_x54x.h index a20f1e7887..0f18743029 100644 --- a/src/include/86box/scsi_x54x.h +++ b/src/include/86box/scsi_x54x.h @@ -30,32 +30,32 @@ #define NVR_SIZE 256 /* size of NVR */ /* EEPROM map and bit definitions. */ -#define EE0_HOSTID 0x07 /* EE(0) [2:0] */ -#define EE0_ALTFLOP 0x80 /* EE(0) [7] FDC at 370h */ -#define EE1_IRQCH 0x07 /* EE(1) [3:0] */ -#define EE1_DMACH 0x70 /* EE(1) [7:4] */ -#define EE2_RMVOK 0x01 /* EE(2) [0] Support removable disks */ -#define EE2_HABIOS 0x02 /* EE(2) [1] HA Bios Space Reserved */ -#define EE2_INT19 0x04 /* EE(2) [2] HA Bios Controls INT19 */ -#define EE2_DYNSCAN 0x08 /* EE(2) [3] Dynamically scan bus */ -#define EE2_TWODRV 0x10 /* EE(2) [4] Allow more than 2 drives */ -#define EE2_SEEKRET 0x20 /* EE(2) [5] Immediate return on seek */ -#define EE2_EXT1G 0x80 /* EE(2) [7] Extended Translation >1GB */ -#define EE3_SPEED 0x00 /* EE(3) [7:0] DMA Speed */ +#define EE0_HOSTID 0x07 /* EE(0) [2:0] */ +#define EE0_ALTFLOP 0x80 /* EE(0) [7] FDC at 370h */ +#define EE1_IRQCH 0x07 /* EE(1) [3:0] */ +#define EE1_DMACH 0x70 /* EE(1) [7:4] */ +#define EE2_RMVOK 0x01 /* EE(2) [0] Support removable disks */ +#define EE2_HABIOS 0x02 /* EE(2) [1] HA Bios Space Reserved */ +#define EE2_INT19 0x04 /* EE(2) [2] HA Bios Controls INT19 */ +#define EE2_DYNSCAN 0x08 /* EE(2) [3] Dynamically scan bus */ +#define EE2_TWODRV 0x10 /* EE(2) [4] Allow more than 2 drives */ +#define EE2_SEEKRET 0x20 /* EE(2) [5] Immediate return on seek */ +#define EE2_EXT1G 0x80 /* EE(2) [7] Extended Translation >1GB */ +#define EE3_SPEED 0x00 /* EE(3) [7:0] DMA Speed */ #define SPEED_33 0xFF #define SPEED_50 0x00 #define SPEED_56 0x04 #define SPEED_67 0x01 #define SPEED_80 0x02 #define SPEED_10 0x03 -#define EE4_FLOPTOK 0x80 /* EE(4) [7] Support Flopticals */ -#define EE6_PARITY 0x01 /* EE(6) [0] parity check enable */ -#define EE6_TERM 0x02 /* EE(6) [1] host term enable */ -#define EE6_RSTBUS 0x04 /* EE(6) [2] reset SCSI bus on boot */ -#define EEE_SYNC 0x01 /* EE(E) [0] Enable Sync Negotiation */ -#define EEE_DISCON 0x02 /* EE(E) [1] Enable Disconnection */ -#define EEE_FAST 0x04 /* EE(E) [2] Enable FAST SCSI */ -#define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ +#define EE4_FLOPTOK 0x80 /* EE(4) [7] Support Flopticals */ +#define EE6_PARITY 0x01 /* EE(6) [0] parity check enable */ +#define EE6_TERM 0x02 /* EE(6) [1] host term enable */ +#define EE6_RSTBUS 0x04 /* EE(6) [2] reset SCSI bus on boot */ +#define EEE_SYNC 0x01 /* EE(E) [0] Enable Sync Negotiation */ +#define EEE_DISCON 0x02 /* EE(E) [1] Enable Disconnection */ +#define EEE_FAST 0x04 /* EE(E) [2] Enable FAST SCSI */ +#define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ /* * Host Adapter I/O ports. @@ -166,11 +166,11 @@ #define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ -/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ -/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ -/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ -/* Byte 13 Command Link ID - TBD (I don't know yet) */ -/* Byte 14 Host Status - Host Adapter status */ +/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ +/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ +/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ +/* Byte 13 Command Link ID - TBD (I don't know yet) */ +/* Byte 14 Host Status - Host Adapter status */ #define CCB_COMPLETE 0x00 /* CCB completed without error */ #define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */ #define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */ @@ -196,51 +196,51 @@ #define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ #pragma pack(push, 1) -typedef struct { +typedef struct addr24_s { uint8_t hi; uint8_t mid; uint8_t lo; -} addr24; +} addr24_t; /* Structure for the INQUIRE_SETUP_INFORMATION reply. */ -typedef struct { - uint8_t uOffset : 4, - uTransferPeriod : 3, - fSynchronous : 1; +typedef struct ReplyInquireSetupInformationSynchronousValue_t { + uint8_t uOffset : 4; + uint8_t uTransferPeriod : 3; + uint8_t fSynchronous : 1; } ReplyInquireSetupInformationSynchronousValue; -typedef struct { - uint8_t fSynchronousInitiationEnabled : 1, - fParityCheckingEnabled : 1, - uReserved1 : 6; +typedef struct ReplyInquireSetupInformation_t { + uint8_t fSynchronousInitiationEnabled : 1; + uint8_t fParityCheckingEnabled : 1; + uint8_t uReserved1 : 6; uint8_t uBusTransferRate; uint8_t uPreemptTimeOnBus; uint8_t uTimeOffBus; uint8_t cMailbox; - addr24 MailboxAddress; + addr24_t MailboxAddress; ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; uint8_t uDisconnectPermittedId0To7; uint8_t VendorSpecificData[28]; } ReplyInquireSetupInformation; -typedef struct { +typedef struct MailboxInit_t { uint8_t Count; - addr24 Address; + addr24_t Address; } MailboxInit_t; -typedef struct { - uint8_t CmdStatus; - addr24 CCBPointer; +typedef struct Mailbox_t { + uint8_t CmdStatus; + addr24_t CCBPointer; } Mailbox_t; -typedef struct { +typedef struct Mailbox32_t { uint32_t CCBPointer; union { - struct { + struct out_t { uint8_t Reserved[3]; uint8_t ActionCode; } out; - struct { + struct in_t { uint8_t HostStatus; uint8_t TargetStatus; uint8_t Reserved; @@ -255,12 +255,12 @@ typedef struct { Bytes 16 and 17 Reserved (must be 0) Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ -typedef struct { - uint8_t Opcode; - uint8_t Reserved1 : 3, - ControlByte : 2, - TagQueued : 1, - QueueTag : 2; +typedef struct CCB32_t { + uint8_t Opcode; + uint8_t Reserved1 : 3; + uint8_t ControlByte : 2; + uint8_t TagQueued : 1; + uint8_t QueueTag : 2; uint8_t CdbLength; uint8_t RequestSenseLength; uint32_t DataLength; @@ -269,36 +269,36 @@ typedef struct { uint8_t HostStatus; uint8_t TargetStatus; uint8_t Id; - uint8_t Lun : 5, - LegacyTagEnable : 1, - LegacyQueueTag : 2; + uint8_t Lun : 5; + uint8_t LegacyTagEnable : 1; + uint8_t LegacyQueueTag : 2; uint8_t Cdb[12]; uint8_t Reserved3[6]; uint32_t SensePointer; } CCB32; -typedef struct { - uint8_t Opcode; - uint8_t Lun : 3, - ControlByte : 2, - Id : 3; - uint8_t CdbLength; - uint8_t RequestSenseLength; - addr24 DataLength; - addr24 DataPointer; - addr24 LinkPointer; - uint8_t LinkId; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved[2]; - uint8_t Cdb[12]; +typedef struct CCB_t { + uint8_t Opcode; + uint8_t Lun : 3; + uint8_t ControlByte : 2; + uint8_t Id : 3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + addr24_t DataLength; + addr24_t DataPointer; + addr24_t LinkPointer; + uint8_t LinkId; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved[2]; + uint8_t Cdb[12]; } CCB; -typedef struct { +typedef struct CCBC_t { uint8_t Opcode; - uint8_t Pad1 : 3, - ControlByte : 2, - Pad2 : 3; + uint8_t Pad1 : 3; + uint8_t ControlByte : 2; + uint8_t Pad2 : 3; uint8_t CdbLength; uint8_t RequestSenseLength; uint8_t Pad3[9]; @@ -309,10 +309,10 @@ typedef struct { uint8_t Cdb[12]; } CCBC; -typedef union { +typedef union CCBU_t { CCB32 new; - CCB old; - CCBC common; + CCB old; + CCBC common; } CCBU; typedef struct { @@ -320,44 +320,43 @@ typedef struct { uint8_t *RequestSenseBuffer; uint32_t CCBPointer; int Is24bit; - uint8_t TargetID, - LUN, - HostStatus, - TargetStatus, - MailboxCompletionCode; + uint8_t TargetID; + uint8_t LUN; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t MailboxCompletionCode; } Req_t; -typedef struct -{ +typedef struct BIOSCMD_t { uint8_t command; - uint8_t lun : 3, - reserved : 2, - id : 3; + uint8_t lun : 3; + uint8_t reserved : 2; + uint8_t id : 3; union { - struct { + struct chs_t { uint16_t cyl; uint8_t head; uint8_t sec; } chs; - struct { + struct lba_t { uint8_t lba0; /* MSB */ uint8_t lba1; uint8_t lba2; uint8_t lba3; /* LSB */ } lba; } u; - uint8_t secount; - addr24 dma_address; + uint8_t secount; + addr24_t dma_address; } BIOSCMD; -typedef struct { +typedef struct SGE32_t { uint32_t Segment; uint32_t SegmentPointer; } SGE32; -typedef struct { - addr24 Segment; - addr24 SegmentPointer; +typedef struct SGE_t { + addr24_t Segment; + addr24_t SegmentPointer; } SGE; #pragma pack(pop) @@ -367,131 +366,156 @@ typedef struct { #define X54X_INT_GEOM_WRITABLE 8 #define X54X_MBX_24BIT 16 #define X54X_ISAPNP 32 +#define X54X_HAS_SIGNATURE 64 -typedef struct { +typedef struct x54x_t { /* 32 bytes */ - char vendor[16], /* name of device vendor */ - name[16]; /* name of device */ + char vendor[16]; /* name of device vendor */ + char name[16]; /* name of device */ /* 24 bytes */ - int8_t type, /* type of device */ - IrqEnabled, Irq, - DmaChannel, - HostID; - - uint8_t callback_phase : 4, - callback_sub_phase : 4, - scsi_cmd_phase, bus, - sync, - parity, shram_mode, - Geometry, Control, - Command, CmdParam, - BusOnTime, BusOffTime, - ATBusSpeed, setup_info_len, - max_id, pci_slot, - temp_cdb[12]; - - volatile uint8_t /* for multi-threading, keep */ - Status, - Interrupt, /* these volatile */ - MailboxIsBIOS, ToRaise, - flags; + int8_t type; /* type of device */ + int8_t IrqEnabled; + int8_t Irq; + int8_t DmaChannel; + int8_t HostID; + + uint8_t callback_phase : 4; + uint8_t callback_sub_phase : 4; + uint8_t scsi_cmd_phase; + uint8_t bus; + uint8_t sync; + uint8_t parity; + uint8_t shram_mode; + uint8_t Geometry; + uint8_t Control; + uint8_t Command; + uint8_t CmdParam; + uint8_t BusOnTime; + uint8_t BusOffTime; + uint8_t ATBusSpeed; + uint8_t setup_info_len; + uint8_t max_id; + uint8_t pci_slot; + uint8_t irq_state; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t temp_cdb[12]; + + /* for multi-threading, keep these volatile */ + volatile uint8_t Status; + volatile uint8_t Interrupt; + volatile uint8_t MailboxIsBIOS; + volatile uint8_t ToRaise; + volatile uint8_t flags; /* 65928 bytes */ - uint8_t pos_regs[8], /* MCA */ - CmdBuf[128], - DataBuf[65536], - shadow_ram[128], - dma_buffer[128], - cmd_33_buf[4096]; + uint8_t pos_regs[8]; /* MCA */ + uint8_t CmdBuf[128]; + uint8_t DataBuf[65536]; + uint8_t shadow_ram[128]; + uint8_t dma_buffer[128]; + uint8_t cmd_33_buf[4096]; /* 16 bytes */ char *fw_rev; /* The 4 bytes of the revision command information + 2 extra bytes for BusLogic */ - uint8_t *rom1, /* main BIOS image */ - *rom2, /* SCSI-Select image */ - *nvr; /* EEPROM buffer */ + uint8_t *rom1; /* main BIOS image */ + uint8_t *rom2; /* SCSI-Select image */ + uint8_t *nvr; /* EEPROM buffer */ /* 6 words = 12 bytes */ - uint16_t DataReply, DataReplyLeft, - rom_ioaddr, /* offset in BIOS of I/O addr */ - rom_shram, /* index to shared RAM */ - rom_shramsz, /* size of shared RAM */ - rom_fwhigh, /* offset in BIOS of ver ID */ - pnp_len, /* length of the PnP ROM */ - pnp_offset, /* offset in the microcode ROM of the PnP ROM */ - cmd_33_len, /* length of the SCSISelect code decompressor program */ - cmd_33_offset; /* offset in the microcode ROM of the SCSISelect code decompressor program */ + uint16_t DataReply; + uint16_t DataReplyLeft; + uint16_t rom_ioaddr; /* offset in BIOS of I/O addr */ + uint16_t rom_shram; /* index to shared RAM */ + uint16_t rom_shramsz; /* size of shared RAM */ + uint16_t rom_fwhigh; /* offset in BIOS of ver ID */ + uint16_t pnp_len; /* length of the PnP ROM */ + uint16_t pnp_offset; /* offset in the microcode ROM of the PnP ROM */ + uint16_t cmd_33_len; /* length of the SCSISelect code decompressor program */ + uint16_t cmd_33_offset; /* offset in the microcode ROM of the SCSISelect code decompressor program */ /* 16 + 20 + 52 = 88 bytes */ - volatile int - MailboxOutInterrupts, - PendingInterrupt, Lock, - target_data_len, pad0; - - uint32_t Base, fdc_address, rom_addr, /* address of BIOS ROM */ - CmdParamLeft, Outgoing, - transfer_size; - - volatile uint32_t - MailboxInit, - MailboxCount, - MailboxOutAddr, MailboxOutPosCur, - MailboxInAddr, MailboxInPosCur, - MailboxReq, - BIOSMailboxInit, BIOSMailboxCount, - BIOSMailboxOutAddr, BIOSMailboxOutPosCur, - BIOSMailboxReq, - Residue, card_bus; /* Basically a copy of device flags */ + volatile int MailboxOutInterrupts; + volatile int PendingInterrupt; + volatile int Lock; + volatile int target_data_len; + volatile int pad2; + + uint32_t Base; + uint32_t fdc_address; + uint32_t rom_addr; /* address of BIOS ROM */ + uint32_t CmdParamLeft; + uint32_t Outgoing; + uint32_t transfer_size; + + volatile uint32_t MailboxInit; + volatile uint32_t MailboxCount; + volatile uint32_t MailboxOutAddr; + volatile uint32_t MailboxOutPosCur; + volatile uint32_t MailboxInAddr; + volatile uint32_t MailboxInPosCur; + volatile uint32_t MailboxReq; + volatile uint32_t BIOSMailboxInit; + volatile uint32_t BIOSMailboxCount; + volatile uint32_t BIOSMailboxOutAddr; + volatile uint32_t BIOSMailboxOutPosCur; + volatile uint32_t BIOSMailboxReq; + volatile uint32_t Residue; + volatile uint32_t card_bus; /* Basically a copy of device flags */ /* 8 bytes */ uint64_t temp_period; /* 16 bytes */ - double media_period, ha_bps; /* bytes per second */ + double media_period; + double ha_bps; /* bytes per second */ /* 8 bytes */ - char *bios_path, /* path to BIOS image file */ - *mcode_path, /* path to microcode image file, needed by the AHA-1542CP */ - *nvr_path; /* path to NVR image file */ + char *bios_path; /* path to BIOS image file */ + char *mcode_path; /* path to microcode image file, needed by the AHA-1542CP */ + char *nvr_path; /* path to NVR image file */ /* 56 bytes */ /* Pointer to a structure of vendor-specific data that only the vendor-specific code can understand */ void *ven_data; /* Pointer to a function that performs vendor-specific operation during the timer callback */ - void (*ven_callback)(void *p); + void (*ven_callback)(void *priv); /* Pointer to a function that executes the second parameter phase of the vendor-specific command */ - void (*ven_cmd_phase1)(void *p); + void (*ven_cmd_phase1)(void *priv); /* Pointer to a function that gets the host adapter ID in case it has to be read from a non-standard location */ - uint8_t (*ven_get_host_id)(void *p); + uint8_t (*ven_get_host_id)(void *priv); /* Pointer to a function that updates the IRQ in the vendor-specific space */ - uint8_t (*ven_get_irq)(void *p); + uint8_t (*ven_get_irq)(void *priv); /* Pointer to a function that updates the DMA channel in the vendor-specific space */ - uint8_t (*ven_get_dma)(void *p); + uint8_t (*ven_get_dma)(void *priv); /* Pointer to a function that returns whether command is fast */ - uint8_t (*ven_cmd_is_fast)(void *p); + uint8_t (*ven_cmd_is_fast)(void *priv); /* Pointer to a function that executes vendor-specific fast path commands */ - uint8_t (*ven_fast_cmds)(void *p, uint8_t cmd); + uint8_t (*ven_fast_cmds)(void *priv, uint8_t cmd); /* Pointer to a function that gets the parameter length for vendor-specific commands */ - uint8_t (*get_ven_param_len)(void *p); + uint8_t (*get_ven_param_len)(void *priv); /* Pointer to a function that executes vendor-specific commands and returns whether or not to suppress the IRQ */ - uint8_t (*ven_cmds)(void *p); + uint8_t (*ven_cmds)(void *priv); /* Pointer to a function that fills in the vendor-specific setup data */ - void (*get_ven_data)(void *p); + void (*get_ven_data)(void *priv); /* Pointer to a function that determines if the mode is aggressive */ - uint8_t (*is_aggressive_mode)(void *p); + uint8_t (*is_aggressive_mode)(void *priv); /* Pointer to a function that returns interrupt type (0 = edge, 1 = level) */ - uint8_t (*interrupt_type)(void *p); + uint8_t (*interrupt_type)(void *priv); /* Pointer to a function that resets vendor-specific data */ - void (*ven_reset)(void *p); + void (*ven_reset)(void *priv); - rom_t bios, /* BIOS memory descriptor */ - uppersck; /* BIOS memory descriptor */ + rom_t bios; /* BIOS memory descriptor */ + rom_t uppersck; /* BIOS memory descriptor */ mem_mapping_t mmio_mapping; - pc_timer_t timer, ResetCB; + pc_timer_t timer; + pc_timer_t ResetCB; Req_t Req; diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 8ed3606a76..08f77ea13e 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -48,52 +48,73 @@ struct serial_device_s; struct serial_s; typedef struct serial_s { - uint8_t lsr, thr, mctrl, rcr, - iir, ier, lcr, msr, - dat, int_status, scratch, fcr, - irq, type, inst, transmit_enabled, - fifo_enabled, rcvr_fifo_len, bits, data_bits, - baud_cycles, rcvr_fifo_full, txsr, out, - msr_set, pad, pad0, pad1; - - uint16_t dlab, base_address, out_new, pad2; - - uint8_t rcvr_fifo_pos, xmit_fifo_pos, - rcvr_fifo_end, xmit_fifo_end, - rcvr_fifo[SERIAL_FIFO_SIZE], xmit_fifo[SERIAL_FIFO_SIZE]; - - pc_timer_t transmit_timer, timeout_timer, - receive_timer; - double clock_src, transmit_period; + uint8_t lsr; + uint8_t thr; + uint8_t mctrl; + uint8_t rcr; + uint8_t iir; + uint8_t ier; + uint8_t lcr; + uint8_t msr; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + uint8_t irq; + uint8_t type; + uint8_t inst; + uint8_t transmit_enabled; + uint8_t fifo_enabled; + uint8_t bits; + uint8_t data_bits; + uint8_t baud_cycles; + uint8_t txsr; + uint8_t txsr_empty; + uint8_t msr_set; + uint8_t irq_state; + + uint16_t dlab; + uint16_t base_address; + uint16_t out_new; + uint16_t thr_empty; + + void *rcvr_fifo; + void *xmit_fifo; + + pc_timer_t transmit_timer; + pc_timer_t timeout_timer; + pc_timer_t receive_timer; + double clock_src; + double transmit_period; struct serial_device_s *sd; } serial_t; typedef struct serial_device_s { - void (*rcr_callback)(struct serial_s *serial, void *p); - void (*dev_write)(struct serial_s *serial, void *p, uint8_t data); - void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t lcr); - void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period); + void (*rcr_callback)(struct serial_s *serial, void *priv); + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data); + void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t lcr); + void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period); void *priv; serial_t *serial; } serial_device_t; -typedef struct { +typedef struct serial_port_s { uint8_t enabled; } serial_port_t; extern serial_port_t com_ports[SERIAL_MAX]; -extern serial_t *serial_attach(int port, - void (*rcr_callback)(struct serial_s *serial, void *p), - void (*dev_write)(struct serial_s *serial, void *p, uint8_t data), - void *priv); extern serial_t *serial_attach_ex(int port, - void (*rcr_callback)(struct serial_s *serial, void *p), - void (*dev_write)(struct serial_s *serial, void *p, uint8_t data), - void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period), - void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t data_bits), + void (*rcr_callback)(struct serial_s *serial, void *priv), + void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data), + void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period), + void (*lcr_callback)(struct serial_s *serial, void *priv, uint8_t data_bits), void *priv); + +#define serial_attach(port, rcr_callback, dev_write, priv) \ + serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv); + extern void serial_remove(serial_t *dev); extern void serial_set_type(serial_t *dev, int type); extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq); @@ -103,11 +124,11 @@ extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); extern void serial_set_clock_src(serial_t *dev, double clock_src); extern void serial_reset_port(serial_t *dev); +extern uint8_t serial_read(uint16_t addr, void *priv); extern void serial_device_timeout(void *priv); - -extern void serial_set_cts(serial_t *dev, uint8_t enabled); -extern void serial_set_dsr(serial_t *dev, uint8_t enabled); -extern void serial_set_dcd(serial_t *dev, uint8_t enabled); +extern void serial_set_cts(serial_t *dev, uint8_t enabled); +extern void serial_set_dsr(serial_t *dev, uint8_t enabled); +extern void serial_set_dcd(serial_t *dev, uint8_t enabled); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/include/86box/serial_passthrough.h b/src/include/86box/serial_passthrough.h index 9612b95002..7ca6479d6c 100644 --- a/src/include/86box/serial_passthrough.h +++ b/src/include/86box/serial_passthrough.h @@ -43,7 +43,8 @@ typedef struct serial_passthrough_s { pc_timer_t serial_to_host_timer; serial_t *serial; double baudrate; - uint8_t bits, data_bits; + uint8_t bits; + uint8_t data_bits; uint8_t port; uint8_t data; char slave_pt[32]; /* used for pseudo term name of slave side */ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 8b95b55b54..31d5d12ae8 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -19,17 +19,21 @@ extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); extern const device_t acc3221_device; +extern const device_t ali5105_device; extern const device_t ali5123_device; extern const device_t f82c710_device; extern const device_t f82c606_device; extern const device_t fdc37c651_device; extern const device_t fdc37c651_ide_device; extern const device_t fdc37c661_device; +extern const device_t fdc37c661_ide_device; +extern const device_t fdc37c661_ide_sec_device; extern const device_t fdc37c663_device; extern const device_t fdc37c663_ide_device; extern const device_t fdc37c665_device; extern const device_t fdc37c665_ide_device; extern const device_t fdc37c665_ide_pri_device; +extern const device_t fdc37c665_ide_sec_device; extern const device_t fdc37c666_device; extern const device_t fdc37c67x_device; extern const device_t fdc37c669_device; @@ -42,6 +46,7 @@ extern const device_t fdc37c935_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; extern const device_t it8661f_device; +extern const device_t it8671f_device; extern const device_t i82091aa_device; extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_pri_device; @@ -70,8 +75,17 @@ extern const device_t ps1_m2133_sio; #if defined(DEV_BRANCH) && defined(USE_SIO_DETECT) extern const device_t sio_detect_device; #endif +extern const device_t um8663af_device; +extern const device_t um8663af_ide_device; +extern const device_t um8663af_sec_device; +extern const device_t um8663bf_device; +extern const device_t um8663bf_ide_device; +extern const device_t um8663bf_sec_device; extern const device_t um8669f_device; +extern const device_t um8669f_ide_device; +extern const device_t um8669f_ide_sec_device; extern const device_t via_vt82c686_sio_device; +extern const device_t w83787f_88h_device; extern const device_t w83787f_device; extern const device_t w83787f_ide_device; extern const device_t w83787f_ide_en_device; diff --git a/src/include/86box/sis_55xx.h b/src/include/86box/sis_55xx.h new file mode 100644 index 0000000000..99ccf7dfa5 --- /dev/null +++ b/src/include/86box/sis_55xx.h @@ -0,0 +1,78 @@ +/* + * 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 for the implementation of the SiS 55xx Pentium + * PCI/ISA Chipsets. + * + * Authors: Miran Grca, + * + * Copyright 2019-2020 Miran Grca. + */ +#ifndef EMU_SIS_55XX_H +#define EMU_SIS_55XX_H + +typedef struct +{ + uint8_t sb_pci_slot; + uint8_t ide_bits_1_3_writable; + uint8_t usb_enabled; + + uint8_t *pmu_regs; + + sff8038i_t *bm[2]; + acpi_t *acpi; +} sis_55xx_common_t; + +extern void sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5511_host_to_pci_read(int addr, void *priv); +extern void sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5571_host_to_pci_read(int addr, void *priv); +extern void sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5581_host_to_pci_read(int addr, void *priv); +extern void sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5591_host_to_pci_read(int addr, void *priv); +extern void sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5600_host_to_pci_read(int addr, void *priv); + +extern void sis_5513_pci_to_isa_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_pci_to_isa_read(int addr, void *priv); +extern void sis_5513_ide_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5513_ide_read(int addr, void *priv); +extern void sis_5572_usb_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5572_usb_read(int addr, void *priv); +extern void sis_5595_pmu_write(int addr, uint8_t val, void *priv); +extern uint8_t sis_5595_pmu_read(int addr, void *priv); + +extern const device_t sis_5511_h2p_device; +extern const device_t sis_5571_h2p_device; +extern const device_t sis_5581_h2p_device; +extern const device_t sis_5591_h2p_device; +extern const device_t sis_5600_h2p_device; + +extern const device_t sis_5513_p2i_device; +extern const device_t sis_5572_p2i_device; +extern const device_t sis_5582_p2i_device; +extern const device_t sis_5595_1997_p2i_device; +extern const device_t sis_5595_p2i_device; + +extern const device_t sis_5513_ide_device; +extern const device_t sis_5572_ide_device; +extern const device_t sis_5582_ide_device; +extern const device_t sis_5591_5600_ide_device; + +extern const device_t sis_5572_usb_device; +extern const device_t sis_5582_usb_device; +extern const device_t sis_5595_usb_device; + +extern const device_t sis_5595_pmu_device; +extern const device_t sis_5595_1997_pmu_device; + +extern const device_t sis_55xx_common_device; + + +#endif /*EMU_SIS_55XX_H*/ diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index 9bb429b437..2c06c3d4e9 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -15,8 +15,8 @@ * Copyright 2020 RichardG. */ -#ifndef EMU_SMBUS_PIIX4_H -#define EMU_SMBUS_PIIX4_H +#ifndef EMU_SMBUS_H +#define EMU_SMBUS_H #define SMBUS_PIIX4_BLOCK_DATA_SIZE 32 #define SMBUS_PIIX4_BLOCK_DATA_MASK (SMBUS_PIIX4_BLOCK_DATA_SIZE - 1) @@ -24,43 +24,89 @@ #define SMBUS_ALI7101_BLOCK_DATA_SIZE 32 #define SMBUS_ALI7101_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) +#define SMBUS_SIS5595_BLOCK_DATA_SIZE 32 +#define SMBUS_SIS5595_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) + enum { SMBUS_PIIX4 = 0, - SMBUS_VIA + SMBUS_VIA = 1 }; -typedef struct { - uint32_t local; - uint16_t io_base; - int clock; - double bit_period; - uint8_t stat, next_stat, ctl, cmd, addr, - data0, data1, - index, data[SMBUS_PIIX4_BLOCK_DATA_SIZE]; +typedef struct smbus_piix4_t { + uint32_t local; + uint16_t io_base; + int clock; + double bit_period; + uint8_t stat; + uint8_t next_stat; + uint8_t ctl; + uint8_t cmd; + uint8_t addr; + uint8_t data0; + uint8_t data1; + uint8_t index; + uint8_t data[SMBUS_PIIX4_BLOCK_DATA_SIZE]; pc_timer_t response_timer; void *i2c; } smbus_piix4_t; -typedef struct { - uint32_t local; - uint16_t io_base; - uint8_t stat, next_stat, ctl, cmd, addr, - data0, data1, - index, data[SMBUS_ALI7101_BLOCK_DATA_SIZE]; +typedef struct smbus_ali7101_t { + uint32_t local; + uint16_t io_base; + uint8_t stat; + uint8_t next_stat; + uint8_t ctl; + uint8_t cmd; + uint8_t addr; + uint8_t data0; + uint8_t data1; + uint8_t index; + uint8_t data[SMBUS_ALI7101_BLOCK_DATA_SIZE]; pc_timer_t response_timer; void *i2c; } smbus_ali7101_t; -extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); -extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); +typedef struct smbus_sis5595_t { + uint32_t local; + uint16_t stat; + uint16_t next_stat; + uint16_t ctl; + uint8_t cmd; + uint8_t addr; + uint8_t saved_addr; + uint8_t block_ptr; + uint8_t count; + uint8_t data0; + uint8_t data1; + uint8_t alias; + uint8_t reg_ff; + uint8_t index; + uint8_t irq_enable; + uint8_t irq_state; + uint8_t data[SMBUS_SIS5595_BLOCK_DATA_SIZE]; + pc_timer_t response_timer; + void *i2c; +} smbus_sis5595_t; + +extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); -extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); + +extern void smbus_sis5595_irq_enable(void *priv, uint8_t enable); + +extern uint8_t smbus_sis5595_read_index(void *priv); +extern uint8_t smbus_sis5595_read_data(void *priv); +extern void smbus_sis5595_write_index(void *priv, uint8_t val); +extern void smbus_sis5595_write_data(void *priv, uint8_t val); #ifdef EMU_DEVICE_H extern const device_t piix4_smbus_device; extern const device_t via_smbus_device; extern const device_t ali7101_smbus_device; + +extern const device_t sis5595_smbus_device; #endif -#endif /*EMU_SMBUS_PIIX4_H*/ +#endif /*EMU_SMBUS_H*/ diff --git a/src/include/86box/smram.h b/src/include/86box/smram.h index 84d1cbe8dd..707c967f5c 100644 --- a/src/include/86box/smram.h +++ b/src/include/86box/smram.h @@ -19,13 +19,16 @@ #define EMU_SMRAM_H typedef struct _smram_ { - struct _smram_ *prev, *next; + struct _smram_ *prev; + struct _smram_ *next; mem_mapping_t mapping; - uint32_t host_base, ram_base, - size, - old_host_base, old_size; + uint32_t host_base; + uint32_t ram_base; + uint32_t size; + uint32_t old_host_base; + uint32_t old_size; } smram_t; /* Make a backup copy of host_base and size of all the SMRAM structs, needed so that if diff --git a/src/include/86box/snd_ac97.h b/src/include/86box/snd_ac97.h index d6d2eacae9..45a921863f 100644 --- a/src/include/86box/snd_ac97.h +++ b/src/include/86box/snd_ac97.h @@ -17,7 +17,7 @@ #ifndef SOUND_AC97_H #define SOUND_AC97_H -#define AC97_VENDOR_ID(f, s, t, dev) ((((f) &0xff) << 24) | (((s) &0xff) << 16) | (((t) &0xff) << 8) | ((dev) &0xff)) +#define AC97_VENDOR_ID(a, b, c, i) ((((a) &0xff) << 24) | (((b) &0xff) << 16) | (((c) &0xff) << 8) | ((i) &0xff)) /* Misc support bits (misc_flags). Most of these are not part of any registers, but control enabling/disabling of registers and bits. */ @@ -91,33 +91,27 @@ #define AC97_PRK (1 << 13) #define AC97_PRL (1 << 14) -/* New codecs should be added to the end of this enum to avoid breaking configs. */ -enum { - AC97_CODEC_AD1881 = 0, - AC97_CODEC_ALC100, - AC97_CODEC_CS4297, - AC97_CODEC_CS4297A, - AC97_CODEC_WM9701A, - AC97_CODEC_STAC9708, - AC97_CODEC_STAC9721, - AC97_CODEC_AK4540 -}; - -typedef struct { - const uint16_t index; - const uint16_t value; - const uint16_t write_mask; +/* Codec IDs. */ +#define AC97_CODEC_AD1881 AC97_VENDOR_ID('A', 'D', 'S', 0x40) +#define AC97_CODEC_AK4540 AC97_VENDOR_ID('A', 'D', 'S', 0x40) +#define AC97_CODEC_ALC100 AC97_VENDOR_ID('A', 'L', 'C', 0x20) +#define AC97_CODEC_CS4297 AC97_VENDOR_ID('C', 'R', 'Y', 0x03) +#define AC97_CODEC_CS4297A AC97_VENDOR_ID('C', 'R', 'Y', 0x11) +#define AC97_CODEC_STAC9708 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08) +#define AC97_CODEC_STAC9721 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09) +#define AC97_CODEC_TR28023 AC97_VENDOR_ID('T', 'R', 'A', 0x03) +#define AC97_CODEC_WM9701A AC97_VENDOR_ID('W', 'M', 'L', 0x00) + +typedef struct ac97_vendor_reg_t { + uint8_t page; /* for paged registers [60:6F], 0 otherwise */ + uint8_t index; + uint16_t value; + uint16_t write_mask; } ac97_vendor_reg_t; -typedef struct { - uint32_t vendor_id; - uint32_t min_rate; - uint32_t max_rate; - uint32_t misc_flags; - uint16_t reset_flags; - uint16_t extid_flags; - uint16_t powerdown_mask; - uint16_t regs[64]; +typedef struct ac97_codec_t { + int model; + uint16_t regs[64]; uint8_t codec_id; uint8_t vendor_reg_page_max; const ac97_vendor_reg_t *vendor_regs; @@ -129,7 +123,7 @@ extern void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_ extern void ac97_codec_reset(void *priv); extern void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r); extern uint32_t ac97_codec_getrate(void *priv, uint8_t reg); -extern const device_t *ac97_codec_get(int model); +extern const device_t *ac97_codec_get(uint32_t id); extern void ac97_via_set_slot(void *priv, int slot, int irq_pin); extern uint8_t ac97_via_read_status(void *priv, uint8_t modem); @@ -152,8 +146,10 @@ extern const device_t ak4540_device; extern const device_t alc100_device; extern const device_t cs4297_device; extern const device_t cs4297a_device; +# define ct1297_device tr28023_device extern const device_t stac9708_device; extern const device_t stac9721_device; +extern const device_t tr28023_device; extern const device_t wm9701a_device; extern const device_t ac97_via_device; diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 76fc775dbb..6bdd2bf400 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -24,26 +24,42 @@ enum { AD1848_TYPE_DEFAULT = 0, - AD1848_TYPE_CS4248, - AD1848_TYPE_CS4231, - AD1848_TYPE_CS4235, - AD1848_TYPE_CS4236 + AD1848_TYPE_CS4248 = 1, + AD1848_TYPE_CS4231 = 2, + AD1848_TYPE_CS4235 = 3, + AD1848_TYPE_CS4236 = 4 }; -typedef struct { - uint8_t type, index, xindex, regs[32], xregs[32], status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ +typedef struct ad1848_t { + uint8_t type; + uint8_t index; + uint8_t xindex; + uint8_t regs[32]; + uint8_t xregs[32]; + uint8_t status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ int count; - uint8_t trd, mce, wten : 1; + uint8_t trd; + uint8_t mce; + uint8_t wten : 1; - int16_t out_l, out_r; - double cd_vol_l, cd_vol_r; - int fm_vol_l, fm_vol_r; - uint8_t fmt_mask, wave_vol_mask; + int16_t out_l; + int16_t out_r; + double cd_vol_l; + double cd_vol_r; + int fm_vol_l; + int fm_vol_r; + uint8_t fmt_mask; + uint8_t wave_vol_mask; - uint8_t enable : 1, irq : 4, dma : 3, adpcm_ref; + uint8_t enable : 1; + uint8_t irq : 4; + uint8_t dma : 3; + uint8_t adpcm_ref; int8_t adpcm_step; - int freq, adpcm_data, adpcm_pos; + int freq; + int adpcm_data; + int adpcm_pos; pc_timer_t timer_count; uint64_t timer_latch; @@ -51,8 +67,8 @@ typedef struct { int16_t buffer[SOUNDBUFLEN * 2]; int pos; - void *cram_priv, - (*cram_write)(uint16_t addr, uint8_t val, void *priv); + void *cram_priv; + void (*cram_write)(uint16_t addr, uint8_t val, void *priv); uint8_t (*cram_read)(uint16_t addr, void *priv); } ad1848_t; diff --git a/src/include/86box/snd_azt2316a.h b/src/include/86box/snd_azt2316a.h index 63a0ff2439..8aae3f1ff3 100644 --- a/src/include/86box/snd_azt2316a.h +++ b/src/include/86box/snd_azt2316a.h @@ -1,6 +1,6 @@ #ifndef SOUND_AZT2316A_H #define SOUND_AZT2316A_H -extern void azt2316a_enable_wss(uint8_t enable, void *p); +extern void azt2316a_enable_wss(uint8_t enable, void *priv); #endif /*SOUND_AZT2316A*/ diff --git a/src/include/86box/snd_cms.h b/src/include/86box/snd_cms.h index 0da6fcdabc..8eec229359 100644 --- a/src/include/86box/snd_cms.h +++ b/src/include/86box/snd_cms.h @@ -27,7 +27,7 @@ typedef struct cms_t { } cms_t; extern void cms_update(cms_t *cms); -extern void cms_write(uint16_t addr, uint8_t val, void *p); -extern uint8_t cms_read(uint16_t addr, void *p); +extern void cms_write(uint16_t addr, uint8_t val, void *priv); +extern uint8_t cms_read(uint16_t addr, void *priv); #endif /*SOUND_CMS_H*/ diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index a163bdeaf2..090ab662af 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -85,10 +85,14 @@ typedef struct emu8k_mem_pointers_t { */ typedef struct emu8k_envelope_t { int state; - int32_t delay_samples, hold_samples, attack_samples; - int32_t value_amp_hz, value_db_oct; + int32_t delay_samples; + int32_t hold_samples; + int32_t attack_samples; + int32_t value_amp_hz; + int32_t value_db_oct; int32_t sustain_value_db_oct; - int32_t attack_amount_amp_hz, ramp_amount_db_oct; + int32_t attack_amount_amp_hz; + int32_t ramp_amount_db_oct; } emu8k_envelope_t; typedef struct emu8k_chorus_eng_t { @@ -320,10 +324,14 @@ typedef struct emu8k_voice_t { emu8k_envelope_t vol_envelope; emu8k_envelope_t mod_envelope; - int64_t lfo1_speed, lfo2_speed; - emu8k_mem_internal_t lfo1_count, lfo2_count; - int32_t lfo1_delay_samples, lfo2_delay_samples; - int vol_l, vol_r; + int64_t lfo1_speed; + int64_t lfo2_speed; + emu8k_mem_internal_t lfo1_count; + emu8k_mem_internal_t lfo2_count; + int32_t lfo1_delay_samples; + int32_t lfo2_delay_samples; + int vol_l; + int vol_r; int16_t fixed_modenv_filter_height; int16_t fixed_modenv_pitch_height; @@ -342,28 +350,44 @@ typedef struct emu8k_voice_t { typedef struct emu8k_t { emu8k_voice_t voice[32]; - uint16_t hwcf1, hwcf2, hwcf3; - uint32_t hwcf4, hwcf5, hwcf6, hwcf7; - - uint16_t init1[32], init2[32], init3[32], init4[32]; - - uint32_t smalr, smarr, smalw, smarw; - uint16_t smld_buffer, smrd_buffer; + uint16_t hwcf1; + uint16_t hwcf2; + uint16_t hwcf3; + uint32_t hwcf4; + uint32_t hwcf5; + uint32_t hwcf6; + uint32_t hwcf7; + + uint16_t init1[32]; + uint16_t init2[32]; + uint16_t init3[32]; + uint16_t init4[32]; + + uint32_t smalr; + uint32_t smarr; + uint32_t smalw; + uint32_t smarw; + uint16_t smld_buffer; + uint16_t smrd_buffer; uint16_t wc; uint16_t id; /* The empty block is used to act as an unallocated memory returning zero. */ - int16_t *ram, *rom, *empty; + int16_t *ram; + int16_t *rom; + int16_t *empty; /* RAM pointers are a way to avoid checking ram boundaries on read */ int16_t *ram_pointers[0x100]; uint32_t ram_end_addr; - int cur_reg, cur_voice; + int cur_reg; + int cur_voice; - int16_t out_l, out_r; + int16_t out_l; + int16_t out_r; emu8k_chorus_eng_t chorus_engine; int32_t chorus_in_buffer[SOUNDBUFLEN]; @@ -644,11 +668,11 @@ Short Delay Short Delay + Feedback // Chorus Params typedef struct { - WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) - WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] - WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) - DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] - DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) + WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) + WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] + WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) + DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] + DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) } CHORUS_TYPE; diff --git a/src/include/86box/snd_mpu401.h b/src/include/86box/snd_mpu401.h index 00fdd54f6e..8cd275af88 100644 --- a/src/include/86box/snd_mpu401.h +++ b/src/include/86box/snd_mpu401.h @@ -71,77 +71,115 @@ typedef enum RecState { typedef struct mpu_t { uint16_t addr; - int uart_mode, intelligent, - irq, midi_thru, - queue_pos, queue_used; - uint8_t rx_data, is_mca, - status, - queue[MPU401_QUEUE], pos_regs[8]; + int uart_mode; + int intelligent; + int irq; + int midi_thru; + int queue_pos; + int queue_used; + uint8_t rx_data; + uint8_t is_mca; + uint8_t status; + uint8_t queue[MPU401_QUEUE]; + uint8_t pos_regs[8]; MpuMode mode; uint8_t rec_queue[MPU401_INPUT_QUEUE]; - int rec_queue_pos, rec_queue_used; + int rec_queue_pos; + int rec_queue_used; uint32_t ch_toref[16]; struct track { - int counter; - uint8_t value[3], sys_val, - vlength, length; + int counter; + uint8_t value[3]; + uint8_t sys_val; + uint8_t vlength; + uint8_t length; MpuDataType type; } playbuf[8], condbuf; struct { - int conductor, cond_req, - cond_set, block_ack, - playing, reset, - wsd, wsm, wsd_start, - run_irq, irq_pending, - track_req, - send_now, eoi_scheduled, - data_onoff, clock_to_host, - sync_in, sysex_in_finished, - rec_copy; + int conductor; + int cond_req; + int cond_set; + int block_ack; + int playing; + int reset; + int wsd; + int wsm; + int wsd_start; + int run_irq; + int irq_pending; + int track_req; + int send_now; + int eoi_scheduled; + int data_onoff; + int clock_to_host; + int sync_in; + int sysex_in_finished; + int rec_copy; RecState rec; - uint8_t tmask, cmask, - amask, - last_rtcmd; - uint16_t midi_mask, req_mask; - uint32_t command_byte, cmd_pending, - track, old_track; + uint8_t tmask; + uint8_t cmask; + uint8_t amask; + uint8_t last_rtcmd; + uint16_t midi_mask; + uint16_t req_mask; + uint32_t command_byte; + uint32_t cmd_pending; + uint32_t track; + uint32_t old_track; } state; struct { - uint8_t timebase, old_timebase, - tempo, old_tempo, - tempo_rel, old_tempo_rel, - tempo_grad, cth_rate[4], - cth_mode, midimetro, - metromeas; - uint32_t cth_counter, cth_old, - rec_counter; - int32_t measure_counter, meas_old, - freq; - int ticks_in, active; - float freq_mod; + uint8_t timebase; + uint8_t old_timebase; + uint8_t tempo; + uint8_t old_tempo; + uint8_t tempo_rel; + uint8_t old_tempo_rel; + uint8_t tempo_grad; + uint8_t cth_rate[4]; + uint8_t cth_mode; + uint8_t midimetro; + uint8_t metromeas; + uint32_t cth_counter; + uint32_t cth_old; + uint32_t rec_counter; + int32_t measure_counter; + int32_t meas_old; + int32_t freq; + int ticks_in; + int active; + float freq_mod; } clock; struct { - int all_thru, midi_thru, - sysex_thru, commonmsgs_thru, - modemsgs_in, commonmsgs_in, - bender_in, sysex_in, - allnotesoff_out, rt_affection, - rt_out, rt_in, - timing_in_stop, data_in_stop, - rec_measure_end; + int all_thru; + int midi_thru; + int sysex_thru; + int commonmsgs_thru; + int modemsgs_in; + int commonmsgs_in; + int bender_in; + int sysex_in; + int allnotesoff_out; + int rt_affection; + int rt_out; + int rt_in; + int timing_in_stop; + int data_in_stop; + int rec_measure_end; uint8_t prchg_buf[16]; uint16_t prchg_mask; } filter; struct { int on; - uint8_t chan, trmask; + uint8_t chan; + uint8_t trmask; uint32_t key[4]; } chanref[5], inputref[16]; - pc_timer_t mpu401_event_callback, mpu401_eoi_callback, - mpu401_reset_callback; - void (*ext_irq_update)(void *priv, int set); - int (*ext_irq_pending)(void *priv); - void *priv; + pc_timer_t mpu401_event_callback; + pc_timer_t mpu401_eoi_callback; + pc_timer_t mpu401_reset_callback; + void (*ext_irq_update)(void *priv, int set); + int (*ext_irq_pending)(void *priv); + void *priv; } mpu_t; extern int mpu401_standalone_enable; @@ -159,7 +197,7 @@ extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int rec extern void mpu401_device_add(void); extern void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv); -extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort); -extern void MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len); +extern int MPU401_InputSysex(void *priv, uint8_t *buffer, uint32_t len, int abort); +extern void MPU401_InputMsg(void *priv, uint8_t *msg, uint32_t len); #endif /*SOUND_MPU401_H*/ diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index b4f26543d9..0d89589c4d 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -18,26 +18,27 @@ #define SOUND_OPL_H enum fm_type { - FM_YM3812 = 0, - FM_YMF262, - FM_YMF289B, - FM_YMF278B, - FM_MAX + FM_YM3812 = 0, /* OPL2 */ + FM_YMF262 = 1, /* OPL3 */ + FM_YMF289B = 2, /* OPL3-L */ + FM_YMF278B = 3, /* OPL 4 */ + FM_MAX = 4 }; enum fm_driver { FM_DRV_NUKED = 0, - FM_DRV_YMFM, - FM_DRV_MAX + FM_DRV_YMFM = 1, + FM_DRV_MAX = 2 }; -typedef struct { - uint8_t (*read)(uint16_t port, void *priv); - void (*write)(uint16_t port, uint8_t val, void *priv); +typedef struct fm_drv_t { + uint8_t (*read)(uint16_t port, void *priv); + void (*write)(uint16_t port, uint8_t val, void *priv); int32_t *(*update)(void *priv); - void (*reset_buffer)(void *priv); - void (*set_do_cycles)(void *priv, int8_t do_cycles); - void *priv; + void (*reset_buffer)(void *priv); + void (*set_do_cycles)(void *priv, int8_t do_cycles); + void *priv; + void (*generate)(void *priv, int32_t *data, uint32_t num_samples); /* daughterboard only. */ } fm_drv_t; extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); diff --git a/src/include/86box/snd_opl_nuked.h b/src/include/86box/snd_opl_nuked.h index f82e85b0eb..e53f860f12 100644 --- a/src/include/86box/snd_opl_nuked.h +++ b/src/include/86box/snd_opl_nuked.h @@ -8,7 +8,7 @@ * * Definitions for the NukedOPL3 driver. * - * Version: @(#)snd_opl_nuked.h 1.0.5 2020/07/16 + * Version: @(#)snd_opl_nuked.h 1.0.5 2020/07/16 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/include/86box/snd_resid.h b/src/include/86box/snd_resid.h index 710ff4a61c..4ddaf9b91e 100644 --- a/src/include/86box/snd_resid.h +++ b/src/include/86box/snd_resid.h @@ -5,11 +5,11 @@ extern "C" { #endif void *sid_init(void); -void sid_close(void *p); -void sid_reset(void *p); -uint8_t sid_read(uint16_t addr, void *p); -void sid_write(uint16_t addr, uint8_t val, void *p); -void sid_fillbuf(int16_t *buf, int len, void *p); +void sid_close(void *priv); +void sid_reset(void *priv); +uint8_t sid_read(uint16_t addr, void *priv); +void sid_write(uint16_t addr, uint8_t val, void *priv); +void sid_fillbuf(int16_t *buf, int len, void *priv); #ifdef __cplusplus } #endif diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 88f2c74f10..f433dd107c 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -25,15 +25,18 @@ #include <86box/snd_opl.h> #include <86box/snd_sb_dsp.h> -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SBAWE32 8 /* DSP v4.13 + OPL3 */ -#define SBAWE64 9 /* DSP v4.16 + OPL3 */ +enum { + SADLIB = 1, /* No DSP */ + SB1, /* DSP v1.05 */ + SB15, /* DSP v2.00 */ + SB2, /* DSP v2.01 - needed for high-speed DMA */ + SBPRO, /* DSP v3.00 */ + SBPRO2, /* DSP v3.02 + OPL3 */ + SB16, /* DSP v4.05 + OPL3 */ + SBAWE32, /* DSP v4.12 + OPL3 */ + SBAWE32PNP, /* DSP v4.13 + OPL3 */ + SBAWE64 /* DSP v4.16 + OPL3 */ +}; /* SB 2.0 CD version */ typedef struct sb_ct1335_mixer_t { @@ -48,16 +51,16 @@ typedef struct sb_ct1335_mixer_t { /* SB PRO */ typedef struct sb_ct1345_mixer_t { - double master_l, - master_r; - double voice_l, - voice_r; - double fm_l, - fm_r; - double cd_l, - cd_r; - double line_l, - line_r; + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; double mic; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; @@ -71,28 +74,27 @@ typedef struct sb_ct1345_mixer_t { uint8_t index; uint8_t regs[256]; - } sb_ct1345_mixer_t; /* SB16 and AWE32 */ typedef struct sb_ct1745_mixer_t { - double master_l, - master_r; - double voice_l, - voice_r; - double fm_l, - fm_r; - double cd_l, - cd_r; - double line_l, - line_r; + double master_l; + double master_r; + double voice_l; + double voice_r; + double fm_l; + double fm_r; + double cd_l; + double cd_r; + double line_l; + double line_r; double mic; double speaker; - int bass_l, - bass_r; - int treble_l, - treble_r; + int bass_l; + int bass_r; + int treble_l; + int treble_r; int output_selector; #define OUTPUT_MIC 1 @@ -125,12 +127,12 @@ typedef struct sb_ct1745_mixer_t { } sb_ct1745_mixer_t; typedef struct sb_t { - uint8_t cms_enabled, - opl_enabled, - mixer_enabled; + uint8_t cms_enabled; + uint8_t opl_enabled; + uint8_t mixer_enabled; cms_t cms; - fm_drv_t opl, - opl2; + fm_drv_t opl; + fm_drv_t opl2; sb_dsp_t dsp; union { sb_ct1335_mixer_t mixer_sb2; @@ -142,28 +144,30 @@ typedef struct sb_t { void *gameport; int pos; + int pnp; - uint8_t pos_regs[8], - pnp_rom[512]; + uint8_t pos_regs[8]; + uint8_t pnp_rom[512]; uint16_t opl_pnp_addr; + uint16_t gameport_addr; void *opl_mixer; void (*opl_mix)(void*, double*, double*); } sb_t; -extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); -extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p); +extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv); +extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *priv); extern void sb_ct1345_mixer_reset(sb_t *sb); -extern void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p); -extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p); +extern void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv); +extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv); extern void sb_ct1745_mixer_reset(sb_t *sb); -extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p); -extern void sbpro_filter_cd_audio(int channel, double *buffer, void *p); -extern void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *p); -extern void sb_close(void *p); -extern void sb_speed_changed(void *p); +extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv); +extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv); +extern void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv); +extern void sb_close(void *priv); +extern void sb_speed_changed(void *priv); #endif /*SOUND_SND_SB_H*/ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 1e9a91828a..ecabe426d9 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -15,19 +15,38 @@ typedef struct sb_dsp_t { int sb_subtype; /* which clone */ void *parent; /* "sb_t *" if default subtype, "azt2316a_t *" if aztech. */ - int sb_8_length, sb_8_origlength, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; + int sb_8_length; + int sb_8_origlength; + int sb_8_format; + int sb_8_autoinit; + int sb_8_pause; + int sb_8_enable; + int sb_8_autolen; + int sb_8_output; int sb_8_dmanum; - int sb_16_length, sb_16_origlength, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; + int sb_16_length; + int sb_16_origlength; + int sb_16_format; + int sb_16_autoinit; + int sb_16_pause; + int sb_16_enable; + int sb_16_autolen; + int sb_16_output; int sb_16_dmanum; + int sb_16_8_dmanum; + int sb_16_dma_enabled; + int sb_16_dma_supported; + int sb_16_dma_translate; int sb_pausetime; - int (*dma_readb)(void *priv), - (*dma_readw)(void *priv), - (*dma_writeb)(void *priv, uint8_t val), - (*dma_writew)(void *priv, uint16_t val); + int (*dma_readb)(void *priv); + int (*dma_readw)(void *priv); + int (*dma_writeb)(void *priv, uint8_t val); + int (*dma_writew)(void *priv, uint16_t val); void *dma_priv; uint8_t sb_read_data[256]; - int sb_read_wp, sb_read_rp; + int sb_read_wp; + int sb_read_rp; int sb_speaker; int muted; @@ -41,8 +60,8 @@ typedef struct sb_dsp_t { int midi_in_timestamp; int sb_irqnum; - void (*irq_update)(void *priv, int set), - *irq_priv; + void (*irq_update)(void *priv, int set); + void *irq_priv; uint8_t sbe2; int sbe2count; @@ -53,23 +72,30 @@ typedef struct sb_dsp_t { int16_t sbdat; int sbdat2; - int16_t sbdatl, sbdatr; + int16_t sbdatl; + int16_t sbdatr; uint8_t sbref; int8_t sbstep; int sbdacpos; - int sbleftright, sbleftright_default; + int sbleftright; + int sbleftright_default; int sbreset; uint8_t sbreaddat; uint8_t sb_command; uint8_t sb_test; - int sb_timei, sb_timeo; + int sb_timei; + int sb_timeo; - int sb_irq8, sb_irq16, sb_irq401; - int sb_irqm8, sb_irqm16, sb_irqm401; + int sb_irq8; + int sb_irq16; + int sb_irq401; + int sb_irqm8; + int sb_irqm16; + int sb_irqm401; uint8_t sb_asp_regs[256]; uint8_t sb_asp_mode; @@ -79,11 +105,14 @@ typedef struct sb_dsp_t { uint8_t sb_8051_ram[256]; - int sbenable, sb_enable_i; + int sbenable; + int sb_enable_i; - pc_timer_t output_timer, input_timer; + pc_timer_t output_timer; + pc_timer_t input_timer; - double sblatcho, sblatchi; + double sblatcho; + double sblatchi; uint16_t sb_addr; @@ -107,35 +136,39 @@ typedef struct sb_dsp_t { mpu_t *mpu; } sb_dsp_t; -void sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len); +extern void sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len); -int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort); +extern int sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort); -void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *src_mpu); +extern void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *src_mpu); -void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent); -void sb_dsp_close(sb_dsp_t *dsp); +extern void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent); +extern void sb_dsp_close(sb_dsp_t *dsp); -void sb_dsp_setirq(sb_dsp_t *dsp, int irq); -void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); -void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); -void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); +extern void sb_dsp_setirq(sb_dsp_t *dsp, int irq); +extern void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled); +extern void sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported); +extern void sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate); +extern void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); -void sb_dsp_speed_changed(sb_dsp_t *dsp); +extern void sb_dsp_speed_changed(sb_dsp_t *dsp); -void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); +extern void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); -void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); +extern void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); -void sb_dsp_update(sb_dsp_t *dsp); -void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401); +extern void sb_dsp_update(sb_dsp_t *dsp); +extern void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401); -void sb_dsp_irq_attach(sb_dsp_t *dsp, void (*irq_update)(void *priv, int set), void *priv); -void sb_dsp_dma_attach(sb_dsp_t *dsp, - int (*dma_readb)(void *priv), - int (*dma_readw)(void *priv), - int (*dma_writeb)(void *priv, uint8_t val), - int (*dma_writew)(void *priv, uint16_t val), - void *priv); +extern void sb_dsp_irq_attach(sb_dsp_t *dsp, void (*irq_update)(void *priv, int set), void *priv); +extern void sb_dsp_dma_attach(sb_dsp_t *dsp, + int (*dma_readb)(void *priv), + int (*dma_readw)(void *priv), + int (*dma_writeb)(void *priv, uint8_t val), + int (*dma_writew)(void *priv, uint16_t val), + void *priv); #endif /* SOUND_SND_SB_DSP_H */ diff --git a/src/include/86box/snd_sn76489.h b/src/include/86box/snd_sn76489.h index c8a3a567c7..6e7399d548 100644 --- a/src/include/86box/snd_sn76489.h +++ b/src/include/86box/snd_sn76489.h @@ -14,8 +14,10 @@ extern int sn76489_mute; typedef struct sn76489_t { int stat[4]; - int latch[4], count[4]; - int freqlo[4], freqhi[4]; + int latch[4]; + int count[4]; + int freqlo[4]; + int freqhi[4]; int vol[4]; uint32_t shift; uint8_t noise; diff --git a/src/include/86box/snd_ym7128.h b/src/include/86box/snd_ym7128.h index 4d5400f342..a0796b1fa2 100644 --- a/src/include/86box/snd_ym7128.h +++ b/src/include/86box/snd_ym7128.h @@ -2,19 +2,26 @@ #define SOUND_YM7128_H typedef struct ym7128_t { - int a0, sci; + int a0; + int sci; uint8_t dat; int reg_sel; uint8_t regs[32]; - int gl[8], gr[8]; - int vm, vc, vl, vr; - int c0, c1; + int gl[8]; + int gr[8]; + int vm; + int vc; + int vl; + int vr; + int c0; + int c1; int t[9]; int16_t filter_dat; - int16_t prev_l, prev_r; + int16_t prev_l; + int16_t prev_r; int16_t delay_buffer[2400]; int delay_pos; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 4c01f289c8..60628ece81 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -50,21 +50,28 @@ extern int sound_pos_global; extern int sound_card_current[SOUND_CARD_MAX]; extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, - int len, void *p), - void *p); + int len, void *priv), + void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, - double *buffer, void *p), - void *p); + double *buffer, void *priv), + void *priv); +extern void sound_set_pc_speaker_filter(void (*filter)(int channel, + double *buffer, void *priv), + void *priv); + +extern void (*filter_pc_speaker)(int channel, double *buffer, void *priv); +extern void *filter_pc_speaker_p; extern int sound_card_available(int card); #ifdef EMU_DEVICE_H extern const device_t *sound_card_getdevice(int card); #endif -extern int sound_card_has_config(int card); -extern char *sound_card_get_internal_name(int card); -extern int sound_card_get_from_internal_name(const char *s); -extern void sound_card_init(void); -extern void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); +extern int sound_card_has_config(int card); +extern const char *sound_card_get_internal_name(int card); +extern int sound_card_get_from_internal_name(const char *s); +extern void sound_card_init(void); +extern void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); extern void sound_speed_changed(void); @@ -81,6 +88,9 @@ extern void inital(void); extern void givealbuffer(void *buf); extern void givealbuffer_cd(void *buf); +#define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base +extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv); + #ifdef EMU_DEVICE_H /* AdLib and AdLib Gold */ extern const device_t adlib_device; @@ -128,6 +138,11 @@ extern const device_t sb_pro_v2_device; extern const device_t sb_pro_mcv_device; extern const device_t sb_pro_compat_device; extern const device_t sb_16_device; +extern const device_t sb_vibra16s_onboard_device; +extern const device_t sb_vibra16s_device; +extern const device_t sb_vibra16xv_device; +extern const device_t sb_vibra16c_onboard_device; +extern const device_t sb_vibra16c_device; extern const device_t sb_16_pnp_device; extern const device_t sb_16_compat_device; extern const device_t sb_16_compat_nompu_device; diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index ae43426752..98eb4e178f 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -46,49 +46,92 @@ #define SPD_SDR_ATTR_VCC_LOW_5 0x10 #define SPD_SDR_ATTR_VCC_HI_5 0x20 -typedef struct { - uint8_t bytes_used, spd_size, mem_type, - row_bits, col_bits, banks, - data_width_lsb, data_width_msb, - signal_level, trac, tcac, - config, refresh_rate, - dram_width, ecc_width, - reserved[47], - spd_rev, checksum, - mfg_jedec[8], mfg_loc; +typedef struct spd_edo_t { + uint8_t bytes_used; + uint8_t spd_size; + uint8_t mem_type; + uint8_t row_bits; + uint8_t col_bits; + uint8_t banks; + uint8_t data_width_lsb; + uint8_t data_width_msb; + uint8_t signal_level; + uint8_t trac; + uint8_t tcac; + uint8_t config; + uint8_t refresh_rate; + uint8_t dram_width; + uint8_t ecc_width; + uint8_t reserved[47]; + uint8_t spd_rev; + uint8_t checksum; + uint8_t mfg_jedec[8]; + uint8_t mfg_loc; char part_no[18]; - uint8_t rev_code[2], - mfg_year, mfg_week, serial[4], mfg_specific[27], - vendor_specific[2], - other_data[127], - checksum2; + uint8_t rev_code[2]; + uint8_t mfg_year; + uint8_t mfg_week; + uint8_t serial[4]; + uint8_t mfg_specific[27]; + uint8_t vendor_specific[2]; + uint8_t other_data[127]; + uint8_t checksum2; } spd_edo_t; -typedef struct { - uint8_t bytes_used, spd_size, mem_type, - row_bits, col_bits, rows, - data_width_lsb, data_width_msb, - signal_level, tclk, tac, - config, refresh_rate, - sdram_width, ecc_width, - tccd, burst, banks, cas, cslat, we, - mod_attr, dev_attr, - tclk2, tac2, tclk3, tac3, - trp, trrd, trcd, tras, - bank_density, - ca_setup, ca_hold, data_setup, data_hold, - reserved[26], - spd_rev, checksum, - mfg_jedec[8], mfg_loc; +typedef struct spd_sdram_t { + uint8_t bytes_used; + uint8_t spd_size; + uint8_t mem_type; + uint8_t row_bits; + uint8_t col_bits; + uint8_t rows; + uint8_t data_width_lsb; + uint8_t data_width_msb; + uint8_t signal_level; + uint8_t tclk; + uint8_t tac; + uint8_t config; + uint8_t refresh_rate; + uint8_t sdram_width; + uint8_t ecc_width; + uint8_t tccd; + uint8_t burst; + uint8_t banks; + uint8_t cas; + uint8_t cslat; + uint8_t we; + uint8_t mod_attr; + uint8_t dev_attr; + uint8_t tclk2; + uint8_t tac2; + uint8_t tclk3; + uint8_t tac3; + uint8_t trp; + uint8_t trrd; + uint8_t trcd; + uint8_t tras; + uint8_t bank_density; + uint8_t ca_setup; + uint8_t ca_hold; + uint8_t data_setup; + uint8_t data_hold; + uint8_t reserved[26]; + uint8_t spd_rev, checksum; + uint8_t mfg_jedec[8]; + uint8_t mfg_loc; char part_no[18]; - uint8_t rev_code[2], - mfg_year, mfg_week, serial[4], mfg_specific[27], - freq, features, - other_data[127], - checksum2; + uint8_t rev_code[2]; + uint8_t mfg_year; + uint8_t mfg_week; + uint8_t serial[4]; + uint8_t mfg_specific[27]; + uint8_t freq; + uint8_t features; + uint8_t other_data[127]; + uint8_t checksum2; } spd_sdram_t; -typedef struct { +typedef struct spd_t { uint8_t slot; uint16_t size; uint16_t row1; diff --git a/src/include/86box/thread.h b/src/include/86box/thread.h index 3f09bf8f94..a71d03913a 100644 --- a/src/include/86box/thread.h +++ b/src/include/86box/thread.h @@ -1,3 +1,24 @@ +/* + * 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. + * + * Thread API header. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2023 Sarah Walker. + * Copyright 2016-2023 Miran Grca. + */ +#ifndef THREAD_H +# define THREAD_H + #ifdef __cplusplus extern "C" { #endif @@ -7,7 +28,7 @@ extern "C" { # define event_t plat_event_t # define mutex_t plat_mutex_t -# define thread_create plat_thread_create +# define thread_create_named plat_thread_create_named # define thread_wait plat_thread_wait # define thread_create_event plat_thread_create_event # define thread_set_event plat_thread_set_event @@ -27,7 +48,8 @@ typedef void thread_t; typedef void event_t; typedef void mutex_t; -extern thread_t *thread_create(void (*thread_func)(void *param), void *param); +#define thread_create(thread_func, param) thread_create_named((thread_func), (param), #thread_func) +extern thread_t *thread_create_named(void (*thread_func)(void *param), void *param, const char *name); extern int thread_wait(thread_t *arg); extern event_t *thread_create_event(void); extern void thread_set_event(event_t *arg); @@ -44,3 +66,5 @@ extern int thread_release_mutex(mutex_t *mutex); #ifdef __cplusplus } #endif + +#endif /*THREAD_H*/ diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index c9b89788a1..4ade8aab02 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -7,18 +7,18 @@ #define MAX_USEC64 1000000ULL #define MAX_USEC 1000000.0 +#define TIMER_PROCESS 4 #define TIMER_SPLIT 2 #define TIMER_ENABLED 1 #pragma pack(push, 1) -typedef struct -{ +typedef struct ts_struct_t { uint32_t frac; uint32_t integer; } ts_struct_t; #pragma pack(pop) -typedef union { +typedef union ts_t { uint64_t ts64; ts_struct_t ts32; } ts_t; @@ -42,14 +42,16 @@ typedef struct pc_timer_t { #else ts_t ts; #endif - int flags, pad; /* The flags are defined above. */ - double period; /* This is used for large period timers to count - the microseconds and split the period. */ + int flags; /* The flags are defined above. */ + int pad; + double period; /* This is used for large period timers to count + the microseconds and split the period. */ - void (*callback)(void *p); - void *p; + void (*callback)(void *priv); + void *priv; - struct pc_timer_t *prev, *next; + struct pc_timer_t *prev; + struct pc_timer_t *next; } pc_timer_t; #ifdef __cplusplus @@ -74,7 +76,7 @@ extern void timer_init(void); /*Add new timer. If start_timer is set, timer will be enabled with a zero timestamp - this is useful for permanently enabled timers*/ -extern void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer); +extern void timer_add(pc_timer_t *timer, void (*callback)(void *priv), void *priv, int start_timer); /*1us in 32:32 format*/ extern uint64_t TIMER_USEC; @@ -115,6 +117,13 @@ timer_is_enabled(pc_timer_t *timer) return !!(timer->flags & TIMER_ENABLED); } +/*True if timer currently on*/ +static __inline int +timer_is_on(pc_timer_t *timer) +{ + return ((timer->flags & TIMER_SPLIT) && (timer->flags & TIMER_ENABLED)); +} + /*Return integer timestamp of timer*/ static __inline uint32_t timer_get_ts_int(pc_timer_t *timer) @@ -160,59 +169,22 @@ timer_get_remaining_u64(pc_timer_t *timer) /*Set timer callback function*/ static __inline void -timer_set_callback(pc_timer_t *timer, void (*callback)(void *p)) +timer_set_callback(pc_timer_t *timer, void (*callback)(void *priv)) { timer->callback = callback; } /*Set timer private data*/ static __inline void -timer_set_p(pc_timer_t *timer, void *p) +timer_set_p(pc_timer_t *timer, void *priv) { - timer->p = p; + timer->priv = priv; } /* The API for big timer periods starts here. */ extern void timer_stop(pc_timer_t *timer); -extern void timer_advance_ex(pc_timer_t *timer, int start); -extern void timer_on(pc_timer_t *timer, double period, int start); extern void timer_on_auto(pc_timer_t *timer, double period); -extern void timer_remove_head(void); - -extern pc_timer_t *timer_head; -extern int timer_inited; - -static __inline void -timer_process_inline(void) -{ - pc_timer_t *timer; - - if (!timer_head) - return; - - while (1) { - timer = timer_head; - - if (!TIMER_LESS_THAN_VAL(timer, (uint32_t) tsc)) - break; - - timer_head = timer->next; - if (timer_head) - timer_head->prev = NULL; - - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - - if (timer->flags & TIMER_SPLIT) - timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ - else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */ - timer->callback(timer->p); - } - - timer_target = timer_head->ts.ts32.integer; -} - #ifdef __cplusplus } #endif diff --git a/src/include/86box/unittester.h b/src/include/86box/unittester.h new file mode 100644 index 0000000000..00abed3ff1 --- /dev/null +++ b/src/include/86box/unittester.h @@ -0,0 +1,37 @@ +/* + * 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. + * + * Debug device for assisting in unit testing. + * See doc/specifications/86box-unit-tester.md for more info. + * If modifying the protocol, you MUST modify the specification + * and increment the version number. + * + * + * + * Authors: GreaseMonkey, + * + * Copyright 2024 GreaseMonkey. + */ + +#ifndef UNITTESTER_H +#define UNITTESTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t unittester_device; + +/* Functions. */ + +#ifdef __cplusplus +} +#endif + +#endif /*UNITTESTER_H*/ diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index d0801b99c2..6237468299 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -1,18 +1,18 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * Definitions for the Distributed DMA emulation. + * Definitions for the Distributed DMA emulation. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #ifndef USB_H @@ -22,198 +22,22 @@ extern "C" { #endif -typedef struct usb_t usb_t; -typedef struct usb_device_t usb_device_t; - -enum usb_pid -{ - USB_PID_OUT = 0xE1, - USB_PID_IN = 0x69, - USB_PID_SETUP = 0x2D -}; - -enum usb_errors -{ - USB_ERROR_NO_ERROR = 0, - USB_ERROR_NAK = 1, - USB_ERROR_OVERRUN = 2, - USB_ERROR_UNDERRUN = 3 -}; - -enum usb_bus_types -{ - USB_BUS_OHCI = 0, - USB_BUS_UHCI, - USB_BUS_MAX -}; - -/* USB device creation parameters struct */ -typedef struct -{ - void (*update_interrupt)(usb_t*, void*); - /* Handle (but do not raise) SMI. Returns 1 if SMI can be raised, 0 otherwise. */ - uint8_t (*smi_handle)(usb_t*, void*); - void* parent_priv; -} usb_params_t; - -typedef union -{ - uint32_t l; - uint16_t w[2]; - uint8_t b[4]; -} ohci_mmio_t; - -/* USB Host Controller device struct */ -typedef struct usb_t -{ +typedef struct usb_t { uint8_t uhci_io[32]; - ohci_mmio_t ohci_mmio[1024]; + uint8_t ohci_mmio[4096]; uint16_t uhci_io_base; - int uhci_enable, ohci_enable; - uint32_t ohci_mem_base, irq_level; + int uhci_enable; + int ohci_enable; + uint32_t ohci_mem_base; mem_mapping_t ohci_mmio_mapping; - pc_timer_t ohci_frame_timer; - pc_timer_t ohci_port_reset_timer[2]; - uint8_t ohci_interrupt_counter : 3; - usb_device_t* ohci_devices[2]; - usb_device_t* uhci_devices[2]; - uint8_t ohci_usb_buf[4096]; - uint8_t ohci_initial_start; - - usb_params_t* usb_params; } usb_t; -#pragma pack(push, 1) - -/* Base USB descriptor struct. */ -typedef struct -{ - uint8_t bLength; - uint8_t bDescriptorType; -} usb_desc_base_t; - -enum usb_desc_setup_req_types -{ - USB_SETUP_TYPE_DEVICE = 0x0, - USB_SETUP_TYPE_INTERFACE = 0x1, - USB_SETUP_TYPE_ENDPOING = 0x2, - USB_SETUP_TYPE_OTHER = 0x3, -}; - -#define USB_SETUP_TYPE_MAX 0x1F - -#define USB_SETUP_DEV_TO_HOST 0x80 - -typedef struct -{ - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} usb_desc_setup_t; - -typedef struct -{ - usb_desc_base_t base; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} usb_desc_endpoint_t; - -typedef struct -{ - usb_desc_base_t base; - - uint16_t bcdHID; - uint8_t bCountryCode; - uint8_t bNumDescriptors; - uint8_t bDescriptorType; - uint16_t wDescriptorLength; -} usb_desc_hid_t; - -typedef struct -{ - usb_desc_base_t base; - - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; -} usb_desc_interface_t; - -typedef struct -{ - usb_desc_base_t base; - uint16_t bString[]; -} usb_desc_string_t; - -typedef struct -{ - usb_desc_base_t base; - - uint16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t bMaxPower; -} usb_desc_conf_t; - -typedef struct -{ - usb_desc_base_t base; - - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} usb_desc_device_t; - -#pragma pack(pop) - -/* USB endpoint device struct. Incomplete and unused. */ -typedef struct usb_device_t -{ - usb_desc_device_t device_desc; - struct { - usb_desc_conf_t conf_desc; - usb_desc_base_t* other_descs[16]; - } conf_desc_items; - - /* General-purpose function for I/O. Non-zero value indicates error. */ - uint8_t (*device_process)(void* priv, uint8_t* data, uint32_t *len, uint8_t pid_token, uint8_t endpoint, uint8_t underrun_not_allowed); - /* Device reset. */ - void (*device_reset)(void* priv); - /* Get address. */ - uint8_t (*device_get_address)(void* priv); - - void* priv; -} usb_device_t; - /* Global variables. */ extern const device_t usb_device; -extern usb_t* usb_device_inst; /* Functions. */ extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable); extern void ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable); -/* Attach USB device to a port of a USB bus. Returns the port to which it got attached to. */ -extern uint8_t usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type); -/* Detach USB device from a port. */ -extern void usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type); #ifdef __cplusplus } diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index e6510e3f17..fab504bbe1 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -15,35 +15,73 @@ * * Copyright 2022 TheCollector1995. */ - #ifndef VIDEO_8514A_H #define VIDEO_8514A_H +typedef struct hwcursor8514_t { + int ena; + int x; + int y; + int xoff; + int yoff; + int cur_xsize; + int cur_ysize; + int v_acc; + int h_acc; + uint32_t addr; + uint32_t pitch; +} hwcursor8514_t; + typedef struct ibm8514_t { - uint8_t pos_regs[8]; + rom_t bios_rom; + rom_t bios_rom2; + hwcursor8514_t hwcursor; + hwcursor8514_t hwcursor_latch; + uint8_t pos_regs[8]; int force_old_addr; int type; + int local; + int bpp; + int on[2]; + int accel_bpp; uint32_t vram_size; uint32_t vram_mask; + uint32_t pallook[512]; PALETTE vgapal; - uint8_t dac_mask, dac_status; + uint8_t hwcursor_oddeven; + uint8_t dac_mask; + uint8_t dac_status; uint32_t *map8; - int dac_addr, dac_pos, dac_r, dac_g; + int dac_addr; + int dac_pos; + int dac_r; + int dac_g; + int dac_b; + int internal_pitch; + int hwcursor_on; + int modechange; + + uint64_t dispontime; + uint64_t dispofftime; struct { uint16_t subsys_cntl; uint16_t setup_md; - uint8_t advfunc_cntl, ext_advfunc_cntl; - uint16_t cur_y, cur_y_bitres; - uint16_t cur_x, cur_x_bitres; + uint16_t advfunc_cntl; + uint16_t cur_y; + uint16_t cur_x; + int16_t destx; + int16_t desty; int16_t desty_axstp; int16_t destx_distp; int16_t err_term; int16_t maj_axis_pcnt; - uint16_t cmd, cmd_back; + int16_t maj_axis_pcnt_no_limit; + uint16_t cmd; + uint16_t cmd_back; uint16_t short_stroke; uint16_t bkgd_color; uint16_t frgd_color; @@ -54,60 +92,131 @@ typedef struct ibm8514_t { uint16_t frgd_mix; uint16_t multifunc_cntl; uint16_t multifunc[16]; - int16_t clip_left, clip_top; + int16_t clip_left; + int16_t clip_top; uint8_t pix_trans[2]; int poly_draw; int ssv_state; - int x1, x2, y1, y2; - int sys_cnt, sys_cnt2; + int x1; + int x2; + int x3; + int y1; + int y2; + int sys_cnt; + int sys_cnt2; int temp_cnt; - int16_t cx, cy, oldcy; - int16_t sx, sy; - int16_t dx, dy; + int16_t cx; + int16_t cx_back; + int16_t cy; + int16_t oldcx; + int16_t oldcy; + int16_t sx; + int16_t sy; + int16_t dx; + int16_t dy; int16_t err; - uint32_t src, dest; - uint32_t newsrc_blt, newdest_blt; - uint32_t newdest_in, newdest_out; - uint8_t *writemono, *nibbleset; - int x_count, xx_count, y_count; - int input, output; - - uint16_t cur_x_bit12, cur_y_bit12; + uint32_t src; + uint32_t dest; + uint32_t newsrc_blt; + uint32_t newdest_blt; + uint32_t newdest_in; + uint32_t newdest_out; + uint8_t *writemono; + uint8_t *nibbleset; + int x_count; + int xx_count; + int y_count; + int input; + int output; + + uint16_t cur_x_bit12; + uint16_t cur_y_bit12; int ssv_len; uint8_t ssv_dir; uint8_t ssv_draw; - int odd_in, odd_out; + int odd_in; + int odd_out; uint16_t scratch; - int fill_state, xdir, ydir; + int fill_state; + int xdir; + int ydir; + int linedraw; + uint32_t ge_offset; } accel; uint16_t test; - int ibm_mode; + int vendor_mode[2]; + int h_blankstart; + int h_blank_end_val; + int hblankstart; + int hblank_end_val; + int hblankend; + int hblank_ext; + int hblank_sub; - int v_total, dispend, v_syncstart, split, - h_disp, h_disp_old, h_total, h_disp_time, rowoffset, - dispon, hdisp_on, linecountff, - vc, linepos, oddeven, cursoron, blink, scrollcache, - firstline, lastline, firstline_draw, lastline_draw, - displine, fullchange, x_add, y_add; - uint32_t ma, maback; + int v_total_reg; + int v_total; + int dispend; + int v_sync_start; + int v_syncstart; + int split; + int h_disp; + int h_total; + int h_sync_width; + int h_disp_time; + int rowoffset; + int dispon; + int hdisp_on; + int linecountff; + int vc; + int linepos; + int oddeven; + int cursoron; + int blink; + int scrollcache; + int firstline; + int lastline; + int firstline_draw; + int lastline_draw; + int displine; + int fullchange; + uint32_t ma; + uint32_t maback; - uint8_t *vram, *changedvram, linedbl; + uint8_t *vram; + uint8_t *changedvram; + uint8_t linedbl; - uint8_t data_available, data_available2; - uint8_t scanmodulos, rowcount; - int htotal, hdisp, vtadj, vdadj, vsadj, sc, - vtb, vdb, vsb, vsyncstart, vsyncwidth; - int vtotal, vdisp; - int disp_cntl, interlace; - uint8_t subsys_cntl, subsys_stat; + uint8_t data_available; + uint8_t data_available2; + uint8_t rowcount; + int hsync_start; + int hsync_width; + int htotal; + int hdisp; + int hdisped; + int sc; + int vsyncstart; + int vsyncwidth; + int vtotal; + int v_disp; + int vdisp; + int disp_cntl; + int interlace; + uint8_t subsys_cntl; + uint8_t subsys_stat; - volatile int force_busy, force_busy2; + atomic_int force_busy; + atomic_int force_busy2; int blitter_busy; uint64_t blitter_time; uint64_t status_time; - int pitch; + int pitch; + int ext_pitch; + int ext_crt_pitch; + int extensions; } ibm8514_t; + #endif /*VIDEO_8514A_H*/ diff --git a/src/include/86box/vid_ati_eeprom.h b/src/include/86box/vid_ati_eeprom.h index 1fa083eaac..99af36edaf 100644 --- a/src/include/86box/vid_ati_eeprom.h +++ b/src/include/86box/vid_ati_eeprom.h @@ -32,8 +32,12 @@ enum { typedef struct ati_eeprom_t { uint16_t data[256]; - int oldclk, oldena; - int opcode, state, count, out; + int oldclk; + int oldena; + int opcode; + int state; + int count; + int out; int wp; uint32_t dat; int type; @@ -43,6 +47,7 @@ typedef struct ati_eeprom_t { } ati_eeprom_t; void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); +void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h new file mode 100644 index 0000000000..7b5862f35e --- /dev/null +++ b/src/include/86box/vid_ati_mach8.h @@ -0,0 +1,162 @@ +/* + * 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. + * + * Emulation of the 8514/A-compatible Mach8 and Mach32 graphics + * chips from ATI for the ISA/VLB/MCA/PCI buses. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2024 TheCollector1995. + */ +#ifndef VIDEO_ATI_MACH8_H +#define VIDEO_ATI_MACH8_H + +typedef struct mach_t { + ati_eeprom_t eeprom; + svga_t svga; + + rom_t bios_rom; + rom_t bios_rom2; + mem_mapping_t mmio_linear_mapping; + + int mca_bus; + int pci_bus; + int vlb_bus; + int has_bios; + + uint8_t regs[256]; + uint8_t pci_regs[256]; + uint8_t int_line; + uint8_t pci_slot; + uint8_t irq_state; + + int index; + int ramdac_type; + int old_mode; + + uint32_t memory; + + uint16_t config1; + uint16_t config2; + + uint8_t pos_regs[8]; + uint8_t pci_cntl_reg; + uint8_t cursor_col_0; + uint8_t cursor_col_1; + uint8_t ext_cur_col_0_r; + uint8_t ext_cur_col_1_r; + uint8_t ext_cur_col_0_g; + uint8_t ext_cur_col_1_g; + uint16_t cursor_col_0_rg; + uint16_t cursor_col_1_rg; + uint16_t cursor_col_b; + uint16_t cursor_offset_lo; + uint16_t cursor_offset_lo_reg; + uint16_t cursor_offset_hi; + uint16_t cursor_offset_hi_reg; + uint16_t cursor_vh_offset; + uint16_t cursor_x; + uint16_t cursor_y; + uint16_t misc; + uint16_t memory_aperture; + uint16_t local_cntl; + uint32_t linear_base; + uint8_t ap_size; + uint8_t bank_w; + uint8_t bank_r; + uint16_t shadow_set; + uint16_t shadow_cntl; + int ext_on[2]; + int compat_mode; + + struct { + uint8_t line_idx; + int16_t line_array[6]; + uint8_t patt_idx; + uint8_t patt_len; + uint8_t pix_trans[2]; + uint8_t eeprom_control; + uint16_t dest_x_end; + uint16_t dest_x_start; + uint16_t dest_y_end; + uint16_t src_x_end; + uint16_t src_x_start; + uint16_t src_x; + uint16_t src_y; + int16_t bres_count; + uint16_t clock_sel; + uint16_t crt_pitch; + uint16_t ge_pitch; + uint16_t dest_cmp_fn; + uint16_t dp_config; + uint16_t ext_ge_config; + uint16_t ge_offset_lo; + uint16_t ge_offset_hi; + uint16_t linedraw_opt; + uint16_t max_waitstates; + uint8_t patt_data_idx; + uint8_t patt_data[0x18]; + uint16_t scan_to_x; + uint16_t scratch0; + uint16_t scratch1; + uint16_t test; + uint16_t pattern; + uint16_t test2; + int src_y_dir; + int cmd_type; + int block_write_mono_pattern_enable; + int mono_pattern_enable; + int16_t cx_end_line; + int16_t cy_end_line; + int16_t cx; + int16_t cx_end; + int16_t cy_end; + int16_t dx; + int16_t dx_end; + int16_t dy; + int16_t dy_end; + int16_t dx_start; + int16_t dy_start; + int16_t cy; + int16_t sx_start; + int16_t sx_end; + int16_t sx; + int16_t x_count; + int16_t xx_count; + int16_t xxx_count; + int16_t sy; + int16_t y_count; + int16_t err; + int16_t width; + int16_t src_width; + int16_t height; + int16_t bleft, bright, btop, bbottom; + int poly_src; + int temp_cnt; + int stepx; + int stepy; + int src_stepx; + uint8_t color_pattern[16]; + uint8_t color_pattern_full[32]; + uint16_t color_pattern_word[8]; + int mono_pattern[8][8]; + uint32_t ge_offset; + uint32_t crt_offset; + uint32_t patt_len_reg; + int poly_fill; + uint16_t dst_clr_cmp_mask; + int clip_overrun; + int color_pattern_idx; + } accel; + + atomic_int force_busy; +} mach_t; + +#endif /*VIDEO_ATI_MACH8_H*/ diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 39e1c24ef7..5b6a2dea24 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -28,21 +28,31 @@ typedef struct cga_t { uint8_t cgastat; - uint8_t cgamode, cgacol; + uint8_t cgamode; + uint8_t cgacol; int fontbase; - int linepos, displine; - int sc, vc; + int linepos; + int displine; + int sc; + int vc; int cgadispon; - int con, coff, cursoron, cgablink; - int vsynctime, vadj; - uint16_t ma, maback; + int con; + int coff; + int cursoron; + int cgablink; + int vsynctime; + int vadj; + uint16_t ma; + uint16_t maback; int oddeven; - uint64_t dispontime, dispofftime; + uint64_t dispontime; + uint64_t dispofftime; pc_timer_t timer; - int firstline, lastline; + int firstline; + int lastline; int drawcursor; @@ -56,15 +66,16 @@ typedef struct cga_t { int composite; int snow_enabled; int rgb_type; + int double_type; } cga_t; void cga_init(cga_t *cga); -void cga_out(uint16_t addr, uint8_t val, void *p); -uint8_t cga_in(uint16_t addr, void *p); -void cga_write(uint32_t addr, uint8_t val, void *p); -uint8_t cga_read(uint32_t addr, void *p); +void cga_out(uint16_t addr, uint8_t val, void *priv); +uint8_t cga_in(uint16_t addr, void *priv); +void cga_write(uint32_t addr, uint8_t val, void *priv); +uint8_t cga_read(uint32_t addr, void *priv); void cga_recalctimings(cga_t *cga); -void cga_poll(void *p); +void cga_poll(void *priv); #ifdef EMU_DEVICE_H extern const device_config_t cga_config[]; diff --git a/src/include/86box/vid_cga_comp.h b/src/include/86box/vid_cga_comp.h index 3c79160344..2911452911 100644 --- a/src/include/86box/vid_cga_comp.h +++ b/src/include/86box/vid_cga_comp.h @@ -21,13 +21,11 @@ #ifndef VIDEO_CGA_COMP_H #define VIDEO_CGA_COMP_H -#define Bit8u uint8_t -#define Bit32u uint32_t -#define Bitu unsigned int -#define bool uint8_t +#define Bitu unsigned int +#define bool uint8_t void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); -Bit32u *Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit32u *TempLine); +Bit32u *Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doublewidth*/, uint32_t *TempLine); #endif /*VIDEO_CGA_COMP_H*/ diff --git a/src/include/86box/vid_colorplus.h b/src/include/86box/vid_colorplus.h index 51b735ec7c..5acd4c8a20 100644 --- a/src/include/86box/vid_colorplus.h +++ b/src/include/86box/vid_colorplus.h @@ -7,12 +7,12 @@ typedef struct colorplus_t { } colorplus_t; void colorplus_init(colorplus_t *colorplus); -void colorplus_out(uint16_t addr, uint8_t val, void *p); -uint8_t colorplus_in(uint16_t addr, void *p); -void colorplus_write(uint32_t addr, uint8_t val, void *p); -uint8_t colorplus_read(uint32_t addr, void *p); +void colorplus_out(uint16_t addr, uint8_t val, void *priv); +uint8_t colorplus_in(uint16_t addr, void *priv); +void colorplus_write(uint32_t addr, uint8_t val, void *priv); +uint8_t colorplus_read(uint32_t addr, void *priv); void colorplus_recalctimings(colorplus_t *colorplus); -void colorplus_poll(void *p); +void colorplus_poll(void *priv); extern const device_t colorplus_device; diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 6c4eb02a88..0bccd607e9 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -27,11 +27,26 @@ typedef struct ega_t { rom_t bios_rom; - uint8_t crtcreg, gdcaddr, attraddr, attrff, - attr_palette_enable, seqaddr, miscout, - writemask, la, lb, lc, ld, - stat, colourcompare, colournocare, scrblank, - plane_mask, pad, pad0, pad1; + uint8_t crtcreg; + uint8_t gdcaddr; + uint8_t attraddr; + uint8_t attrff; + uint8_t attr_palette_enable; + uint8_t seqaddr; + uint8_t miscout; + uint8_t writemask; + uint8_t la; + uint8_t lb; + uint8_t lc; + uint8_t ld; + uint8_t stat; + uint8_t colourcompare; + uint8_t colournocare; + uint8_t scrblank; + uint8_t plane_mask; + uint8_t ctl_mode; + uint8_t color_mux; + uint8_t dot; uint8_t crtc[32]; uint8_t gdcreg[16]; uint8_t attrregs[32]; @@ -41,35 +56,90 @@ typedef struct ega_t { uint8_t *vram; - int vidclock, fast, extvram, vres, - readmode, writemode, readplane, vrammask, - chain4, chain2_read, chain2_write, con, - oddeven_page, oddeven_chain, vc, sc, - dispon, hdisp_on, cursoron, blink, fullchange, - linepos, vslines, linecountff, oddeven, - lowres, interlace, linedbl, lindebl, rowcount, - vtotal, dispend, vsyncstart, split, - hdisp, hdisp_old, htotal, hdisp_time, rowoffset, - vblankstart, scrollcache, firstline, lastline, - firstline_draw, lastline_draw, x_add, y_add, - displine, res_x, res_y, bpp, index; - - uint32_t charseta, charsetb, ma_latch, ma, - maback, ca, vram_limit, overscan_color; + uint16_t light_pen; + + int vidclock; + int fast; + int extvram; + int vres; + int readmode; + int writemode; + int readplane; + int vrammask; + int chain4; + int chain2_read; + int chain2_write; + int con; + int oddeven_page; + int oddeven_chain; + int vc; + int sc; + int dispon; + int hdisp_on; + int cursoron; + int blink; + int fullchange; + int linepos; + int vslines; + int linecountff; + int oddeven; + int lowres; + int interlace; + int linedbl; + int lindebl; + int rowcount; + int vtotal; + int dispend; + int vsyncstart; + int split; + int hdisp; + int hdisp_old; + int htotal; + int hdisp_time; + int rowoffset; + int vblankstart; + int scrollcache; + int firstline; + int lastline; + int firstline_draw; + int lastline_draw; + int x_add; + int y_add; + int displine; + int res_x; + int res_y; + int bpp; + int index; + int remap_required; + int actual_type; + int chipset; + + uint32_t charseta; + uint32_t charsetb; + uint32_t ma_latch; + uint32_t ma; + uint32_t maback; + uint32_t ca; + uint32_t vram_limit; + uint32_t overscan_color; + uint32_t cca; uint32_t *pallook; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime; + uint64_t dispofftime; - double clock; + uint64_t dot_time; - int remap_required; - uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + pc_timer_t timer; + pc_timer_t dot_timer; + + double dot_clock; - void (*render)(struct ega_t *svga); + void * eeprom; - void *eeprom; + uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + void (*render)(struct ega_t *svga); } ega_t; #endif @@ -77,7 +147,7 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; -extern const device_t atiega_device; +extern const device_t atiega800p_device; extern const device_t iskra_ega_device; extern const device_t et2000_device; #endif @@ -97,18 +167,22 @@ extern void ega_recalctimings(struct ega_t *ega); extern void ega_recalc_remap_func(struct ega_t *ega); #endif -extern void ega_out(uint16_t addr, uint8_t val, void *p); -extern uint8_t ega_in(uint16_t addr, void *p); -extern void ega_poll(void *p); -extern void ega_write(uint32_t addr, uint8_t val, void *p); -extern uint8_t ega_read(uint32_t addr, void *p); +extern void ega_out(uint16_t addr, uint8_t val, void *priv); +extern uint8_t ega_in(uint16_t addr, void *priv); +extern void ega_poll(void *priv); +extern void ega_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t ega_read(uint32_t addr, void *priv); -extern int firstline_draw, lastline_draw; +extern int firstline_draw; +extern int lastline_draw; extern int displine; extern int sc; -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; +extern uint32_t ma; +extern uint32_t ca; +extern int con; +extern int cursoron; +extern int cgablink; extern int scrollcache; diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index 37f6904db9..b01bb2b0eb 100644 --- a/src/include/86box/vid_ega_render_remap.h +++ b/src/include/86box/vid_ega_render_remap.h @@ -85,7 +85,7 @@ ega_recalc_remap_func(ega_t *ega) func_nr = VAR_DWORD_MODE; else if (ega->crtc[0x17] & 0x40) func_nr = VAR_BYTE_MODE; - else if ((ega->crtc[0x17] & 0x20) && ega->vram_limit > 64*1024) + else if ((ega->crtc[0x17] & 0x20) && ega->vram_limit > 64 * 1024) func_nr = VAR_WORD_MODE_MA15; else func_nr = VAR_WORD_MODE_MA13; diff --git a/src/include/86box/vid_hercules.h b/src/include/86box/vid_hercules.h index bbb4239aae..c58a50aa3a 100644 --- a/src/include/86box/vid_hercules.h +++ b/src/include/86box/vid_hercules.h @@ -25,32 +25,34 @@ typedef struct { mem_mapping_t mapping; - uint8_t crtc[32], charbuffer[4096]; + uint8_t crtc[32]; + uint8_t charbuffer[4096]; int crtcreg; - uint8_t ctrl, - ctrl2, - stat; + uint8_t ctrl; + uint8_t ctrl2; + uint8_t stat; - uint64_t dispontime, - dispofftime; + uint64_t dispontime; + uint64_t dispofftime; pc_timer_t timer; - int firstline, - lastline; + int firstline; + int lastline; - int linepos, - displine; - int vc, - sc; - uint16_t ma, - maback; - int con, coff, - cursoron; - int dispon, - blink; - int vsynctime; - int vadj; + int linepos; + int displine; + int vc; + int sc; + uint16_t ma; + uint16_t maback; + int con; + int coff; + int cursoron; + int dispon; + int blink; + int vsynctime; + int vadj; int lp_ff; int fullchange; diff --git a/src/include/86box/vid_mda.h b/src/include/86box/vid_mda.h index 0f50808651..d13c45a287 100644 --- a/src/include/86box/vid_mda.h +++ b/src/include/86box/vid_mda.h @@ -11,18 +11,28 @@ typedef struct mda_t { uint8_t crtc[32]; int crtcreg; - uint8_t ctrl, stat; + uint8_t ctrl; + uint8_t stat; - uint64_t dispontime, dispofftime; + uint64_t dispontime; + uint64_t dispofftime; pc_timer_t timer; - int firstline, lastline; + int firstline; + int lastline; - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; + int fontbase; + int linepos; + int displine; + int vc; + int sc; + uint16_t ma; + uint16_t maback; + int con; + int coff; + int cursoron; + int dispon; + int blink; int vsynctime; int vadj; int monitor_index; @@ -43,12 +53,12 @@ typedef struct mda_t { void mda_init(mda_t *mda); void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink); -void mda_out(uint16_t addr, uint8_t val, void *p); -uint8_t mda_in(uint16_t addr, void *p); -void mda_write(uint32_t addr, uint8_t val, void *p); -uint8_t mda_read(uint32_t addr, void *p); +void mda_out(uint16_t addr, uint8_t val, void *priv); +uint8_t mda_in(uint16_t addr, void *priv); +void mda_write(uint32_t addr, uint8_t val, void *priv); +uint8_t mda_read(uint32_t addr, void *priv); void mda_recalctimings(mda_t *mda); -void mda_poll(void *p); +void mda_poll(void *priv); #ifdef EMU_DEVICE_H extern const device_t mda_device; diff --git a/src/include/86box/vid_nga.h b/src/include/86box/vid_nga.h index 93786b15ed..bbb5b3c955 100644 --- a/src/include/86box/vid_nga.h +++ b/src/include/86box/vid_nga.h @@ -11,14 +11,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, * EngiNerd, * - * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2020 EngiNerd. */ diff --git a/src/include/86box/vid_ogc.h b/src/include/86box/vid_ogc.h index 6b80f58599..839769e69b 100644 --- a/src/include/86box/vid_ogc.h +++ b/src/include/86box/vid_ogc.h @@ -11,14 +11,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, + * Authors: Miran Grca, * EngiNerd, * - * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2020 EngiNerd. */ diff --git a/src/include/86box/vid_pgc.h b/src/include/86box/vid_pgc.h index 12450c0d12..35e2d9e423 100644 --- a/src/include/86box/vid_pgc.h +++ b/src/include/86box/vid_pgc.h @@ -45,9 +45,9 @@ typedef struct pgc_cl { typedef struct pgc_cmd { char ascii[6]; uint8_t hex; - void (*handler)(struct pgc *); - int (*parser)(struct pgc *, pgc_cl_t *, int); - int p; + void (*handler)(struct pgc *); + int (*parser)(struct pgc *, pgc_cl_t *, int); + int p; } pgc_cmd_t; typedef struct pgc { @@ -59,10 +59,10 @@ typedef struct pgc { mem_mapping_t mapping; mem_mapping_t cga_mapping; - pgc_cl_t *clist, - *clcur; - const pgc_cmd_t *master, - *commands; + pgc_cl_t *clist; + pgc_cl_t *clcur; + const pgc_cmd_t *master; + const pgc_cmd_t *commands; uint8_t mapram[2048]; /* host <> PGC communication buffer */ uint8_t *cga_vram; @@ -71,12 +71,22 @@ typedef struct pgc { uint8_t hex_command; uint32_t palette[256]; uint32_t userpal[256]; - uint32_t maxw, maxh; /* maximum framebuffer size */ - uint32_t visw, vish; /* maximum screen size */ - uint32_t screenw, screenh; - int16_t pan_x, pan_y; - uint16_t win_x1, win_x2, win_y1, win_y2; - uint16_t vp_x1, vp_x2, vp_y1, vp_y2; + uint32_t maxw; /* maximum framebuffer size - Width */ + uint32_t maxh; /* maximum framebuffer size - Height */ + uint32_t visw; /* maximum screen size - Width */ + uint32_t vish; /* maximum screen size - Height */ + uint32_t screenw; + uint32_t screenh; + int16_t pan_x; + int16_t pan_y; + uint16_t win_x1; + uint16_t win_x2; + uint16_t win_y1; + uint16_t win_y2; + uint16_t vp_x1; + uint16_t vp_x2; + uint16_t vp_y1; + uint16_t vp_y2; int16_t fill_pattern[16]; int16_t line_pattern; uint8_t draw_mode; @@ -86,7 +96,9 @@ typedef struct pgc { uint8_t tjust_v; /* vert alignment 1=bottom 2=ctr 3=top*/ int32_t tsize; /* horizontal spacing */ - int32_t x, y, z; /* drawing position */ + int32_t x; + int32_t y; + int32_t z; /* drawing position */ thread_t *pgc_thread; event_t *pgc_wake_thread; @@ -98,18 +110,23 @@ typedef struct pgc { int ascii_mode; int result_count; - int fontbase; - int linepos, - displine; + int fontbase; + int linepos; + int displine; int vc; int cgadispon; - int con, coff, cursoron, cgablink; - int vsynctime, vadj; - uint16_t ma, maback; + int con; + int coff; + int cursoron; + int cgablink; + int vsynctime; + int vadj; + uint16_t ma; + uint16_t maback; int oddeven; - uint64_t dispontime, - dispofftime; + uint64_t dispontime; + uint64_t dispofftime; pc_timer_t timer; double native_pixel_clock; @@ -140,10 +157,14 @@ extern void pgc_init(pgc_t *, extern void pgc_sto_raster(pgc_t *, int16_t *x, int16_t *y); extern void pgc_ito_raster(pgc_t *, int32_t *x, int32_t *y); extern void pgc_dto_raster(pgc_t *, double *x, double *y); -// extern int pgc_input_byte(pgc_t *, uint8_t *val); -// extern int pgc_output_byte(pgc_t *, uint8_t val); +#if 0 +extern int pgc_input_byte(pgc_t *, uint8_t *val); +extern int pgc_output_byte(pgc_t *, uint8_t val); +#endif extern int pgc_output_string(pgc_t *, const char *val); -// extern int pgc_error_byte(pgc_t *, uint8_t val); +#if 0 +extern int pgc_error_byte(pgc_t *, uint8_t val); +#endif extern int pgc_error_string(pgc_t *, const char *val); extern int pgc_error(pgc_t *, int err); diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 93fb9f17c7..2f8a83a1d2 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -16,11 +16,6 @@ * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ - -#include <86box/thread.h> -#include <86box/vid_8514a.h> -#include <86box/vid_xga.h> - #ifndef VIDEO_SVGA_H # define VIDEO_SVGA_H @@ -31,15 +26,23 @@ # define FLAG_NOSKEW 16 # define FLAG_ADDR_BY16 32 # define FLAG_RAMDAC_SHIFT 64 -# define FLAG_128K_MASK 128 - +# define FLAG_ATI 128 +# define FLAG_S3_911_16BIT 256 +# define FLAG_512K_MASK 512 struct monitor_t; -typedef struct { - int ena, - x, y, xoff, yoff, cur_xsize, cur_ysize, - v_acc, h_acc; - uint32_t addr, pitch; +typedef struct hwcursor_t { + int ena; + int x; + int y; + int xoff; + int yoff; + int cur_xsize; + int cur_ysize; + int v_acc; + int h_acc; + uint32_t addr; + uint32_t pitch; } hwcursor_t; typedef union { @@ -50,29 +53,83 @@ typedef union { } latch_t; typedef struct svga_t { - ibm8514_t dev8514; - xga_t xga; mem_mapping_t mapping; - uint8_t fast, chain4, chain2_write, chain2_read, - ext_overscan, bus_size, - lowres, interlace, linedbl, rowcount, - set_reset_disabled, bpp, ramdac_type, fb_only, - readmode, writemode, readplane, - hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven, - fcr, hblank_overscan; - - int dac_addr, dac_pos, dac_r, dac_g, - vtotal, dispend, vsyncstart, split, vblankstart, - hdisp, hdisp_old, htotal, hdisp_time, rowoffset, - dispon, hdisp_on, - vc, sc, linepos, vslines, linecountff, oddeven, - con, cursoron, blink, scrollcache, char_width, - firstline, lastline, firstline_draw, lastline_draw, - displine, fullchange, x_add, y_add, pan, - vram_display_mask, vidclock, dots_per_clock, hblank_ext, - hwcursor_on, dac_hwcursor_on, overlay_on, set_override, - hblankstart, hblankend, hblank_sub, hblank_end_val, hblank_end_len; + uint8_t fast; + uint8_t chain4; + uint8_t chain2_write; + uint8_t chain2_read; + uint8_t ext_overscan; + uint8_t bus_size; + uint8_t lowres; + uint8_t interlace; + uint8_t linedbl; + uint8_t rowcount; + uint8_t set_reset_disabled; + uint8_t bpp; + uint8_t ramdac_type; + uint8_t fb_only; + uint8_t readmode; + uint8_t writemode; + uint8_t readplane; + uint8_t hwcursor_oddeven; + uint8_t dac_hwcursor_oddeven; + uint8_t overlay_oddeven; + uint8_t fcr; + uint8_t hblank_overscan; + + int dac_addr; + int dac_pos; + int dac_r; + int dac_g; + int dac_b; + int vtotal; + int dispend; + int vsyncstart; + int split; + int vblankstart; + int hdisp; + int hdisp_old; + int htotal; + int hdisp_time; + int rowoffset; + int dispon; + int hdisp_on; + int vc; + int sc; + int linepos; + int vslines; + int linecountff; + int oddeven; + int con; + int cursoron; + int blink; + int scrollcache; + int char_width; + int firstline; + int lastline; + int firstline_draw; + int lastline_draw; + int displine; + int fullchange; + int x_add; + int y_add; + int pan; + int vram_display_mask; + int vidclock; + int dots_per_clock; + int hwcursor_on; + int dac_hwcursor_on; + int overlay_on; + int set_override; + int hblankstart; + int hblankend; + int hblank_end_val; + int hblank_end_len; + int hblank_end_mask; + int hblank_sub; + int packed_4bpp; + int ati_4color; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM @@ -83,35 +140,52 @@ typedef struct svga_t { For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) */ - uint32_t decode_mask, vram_max, - vram_mask, - charseta, charsetb, - adv_flags, ma_latch, - ca_adj, ma, maback, - write_bank, read_bank, - extra_banks[2], - banked_mask, - ca, overscan_color, - *map8, pallook[512]; + uint32_t decode_mask; + uint32_t vram_max; + uint32_t vram_mask; + uint32_t charseta; + uint32_t charsetb; + uint32_t adv_flags; + uint32_t ma_latch; + uint32_t ca_adj; + uint32_t ma; + uint32_t maback; + uint32_t write_bank; + uint32_t read_bank; + uint32_t extra_banks[2]; + uint32_t banked_mask; + uint32_t ca; + uint32_t overscan_color; + uint32_t *map8; + uint32_t pallook[512]; PALETTE vgapal; - uint64_t dispontime, dispofftime; + uint64_t dispontime; + uint64_t dispofftime; latch_t latch; pc_timer_t timer; + pc_timer_t timer8514; double clock; + double clock8514; + + double multiplier; - hwcursor_t hwcursor, hwcursor_latch, - dac_hwcursor, dac_hwcursor_latch, - overlay, overlay_latch; + hwcursor_t hwcursor; + hwcursor_t hwcursor_latch; + hwcursor_t dac_hwcursor; + hwcursor_t dac_hwcursor_latch; + hwcursor_t overlay; + hwcursor_t overlay_latch; void (*render)(struct svga_t *svga); + void (*render8514)(struct svga_t *svga); void (*recalctimings_ex)(struct svga_t *svga); - void (*video_out)(uint16_t addr, uint8_t val, void *p); - uint8_t (*video_in)(uint16_t addr, void *p); + void (*video_out)(uint16_t addr, uint8_t val, void *priv); + uint8_t (*video_in)(uint16_t addr, void *priv); void (*hwcursor_draw)(struct svga_t *svga, int displine); @@ -122,7 +196,7 @@ typedef struct svga_t { void (*vblank_start)(struct svga_t *svga); void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); - float (*getclock)(int clock, void *p); + float (*getclock)(int clock, void *priv); /* Called when VC=R18 and friends. If this returns zero then MA resetting is skipped. Matrox Mystique in Power mode reuses this counter for @@ -132,24 +206,40 @@ typedef struct svga_t { /*Called at the start of vertical sync*/ void (*vsync_callback)(struct svga_t *svga); - uint32_t (*translate_address)(uint32_t addr, void *p); + uint32_t (*translate_address)(uint32_t addr, void *priv); /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ int override; - void *p; - - uint8_t crtc[256], gdcreg[256], attrregs[32], seqregs[256], - egapal[16], - *vram, *changedvram; - - uint8_t crtcreg, gdcaddr, - attrff, attr_palette_enable, attraddr, seqaddr, - miscout, cgastat, scrblank, - plane_mask, writemask, - colourcompare, colournocare, - dac_mask, dac_status, - dpms, dpms_ui, - ksc5601_sbyte_mask, ksc5601_udc_area_msb[2]; + void *priv; + + uint8_t crtc[256]; + uint8_t gdcreg[256]; + uint8_t attrregs[32]; + uint8_t seqregs[256]; + uint8_t egapal[16]; + uint8_t *vram; + uint8_t *changedvram; + + uint8_t crtcreg; + uint8_t gdcaddr; + uint8_t attrff; + uint8_t attr_palette_enable; + uint8_t attraddr; + uint8_t seqaddr; + uint8_t miscout; + uint8_t cgastat; + uint8_t scrblank; + uint8_t plane_mask; + uint8_t writemask; + uint8_t colourcompare; + uint8_t colournocare; + uint8_t dac_mask; + uint8_t dac_status; + uint8_t dpms; + uint8_t dpms_ui; + uint8_t color_2bpp; + uint8_t ksc5601_sbyte_mask; + uint8_t ksc5601_udc_area_msb[2]; int ksc5601_swap_mode; uint16_t ksc5601_english_font_type; @@ -163,6 +253,11 @@ typedef struct svga_t { addresses are shifted to match*/ int packed_chain4; + /*Disable 8bpp blink mode - some cards support it, some don't, it's a weird mode + If mode 13h appears in a reddish-brown background (0x88) with dark green text (0x8F), + you should set this flag when entering that mode*/ + int disable_blink; + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; @@ -171,61 +266,81 @@ typedef struct svga_t { int remap_required; uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); - void *ramdac, *clock_gen; + void *ramdac; + void *clock_gen; /* Monitor Index */ uint8_t monitor_index; /* Pointer to monitor */ - monitor_t* monitor; + monitor_t *monitor; + + /* Enable LUT mapping of >= 24 bpp modes. */ + int lut_map; + + /* Override the horizontal blanking stuff. */ + int hoverride; + + /* Return a 32 bpp color from a 15/16 bpp color. */ + uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp); + + void * dev8514; + void * ext8514; + void * xga; } svga_t; extern int vga_on; -extern int ibm8514_on; - -extern void ibm8514_poll(ibm8514_t *dev, svga_t *svga); -extern void ibm8514_recalctimings(svga_t *svga); -extern uint8_t ibm8514_ramdac_in(uint16_t port, void *p); -extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p); -extern int ibm8514_cpu_src(svga_t *svga); -extern int ibm8514_cpu_dest(svga_t *svga); -extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len); -extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); -extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); - -extern void xga_poll(xga_t *xga, svga_t *svga); + +extern void ibm8514_poll(void *priv); +extern void ibm8514_recalctimings(svga_t *svga); +extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); +extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); +extern int ibm8514_cpu_src(svga_t *svga); +extern int ibm8514_cpu_dest(svga_t *svga); +extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); +extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); +extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); + +#ifdef ATI_8514_ULTRA +extern void ati8514_recalctimings(svga_t *svga); +extern uint8_t ati8514_mca_read(int port, void *priv); +extern void ati8514_mca_write(int port, uint8_t val, void *priv); +extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); +#endif + +extern void xga_poll(void *priv, svga_t *svga); extern void xga_recalctimings(svga_t *svga); -extern int svga_init(const device_t *info, svga_t *svga, void *p, int memsize, +extern int svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in)(uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), + uint8_t (*video_in)(uint16_t addr, void *priv), + void (*video_out)(uint16_t addr, uint8_t val, void *priv), void (*hwcursor_draw)(struct svga_t *svga, int displine), void (*overlay_draw)(struct svga_t *svga, int displine)); extern void svga_recalctimings(svga_t *svga); extern void svga_close(svga_t *svga); -uint8_t svga_read(uint32_t addr, void *p); -uint16_t svga_readw(uint32_t addr, void *p); -uint32_t svga_readl(uint32_t addr, void *p); -void svga_write(uint32_t addr, uint8_t val, void *p); -void svga_writew(uint32_t addr, uint16_t val, void *p); -void svga_writel(uint32_t addr, uint32_t val, void *p); -uint8_t svga_read_linear(uint32_t addr, void *p); -uint8_t svga_readb_linear(uint32_t addr, void *p); -uint16_t svga_readw_linear(uint32_t addr, void *p); -uint32_t svga_readl_linear(uint32_t addr, void *p); -void svga_write_linear(uint32_t addr, uint8_t val, void *p); -void svga_writeb_linear(uint32_t addr, uint8_t val, void *p); -void svga_writew_linear(uint32_t addr, uint16_t val, void *p); -void svga_writel_linear(uint32_t addr, uint32_t val, void *p); - -void svga_add_status_info(char *s, int max_len, void *p); +uint8_t svga_read(uint32_t addr, void *priv); +uint16_t svga_readw(uint32_t addr, void *priv); +uint32_t svga_readl(uint32_t addr, void *priv); +void svga_write(uint32_t addr, uint8_t val, void *priv); +void svga_writew(uint32_t addr, uint16_t val, void *priv); +void svga_writel(uint32_t addr, uint32_t val, void *priv); +uint8_t svga_read_linear(uint32_t addr, void *priv); +uint8_t svga_readb_linear(uint32_t addr, void *priv); +uint16_t svga_readw_linear(uint32_t addr, void *priv); +uint32_t svga_readl_linear(uint32_t addr, void *priv); +void svga_write_linear(uint32_t addr, uint8_t val, void *priv); +void svga_writeb_linear(uint32_t addr, uint8_t val, void *priv); +void svga_writew_linear(uint32_t addr, uint16_t val, void *priv); +void svga_writel_linear(uint32_t addr, uint32_t val, void *priv); + +void svga_add_status_info(char *s, int max_len, void *priv); extern uint8_t svga_rotate[8][256]; -void svga_out(uint16_t addr, uint8_t val, void *p); -uint8_t svga_in(uint16_t addr, void *p); +void svga_out(uint16_t addr, uint8_t val, void *priv); +uint8_t svga_in(uint16_t addr, void *priv); svga_t *svga_get_pri(void); void svga_set_override(svga_t *svga, int val); @@ -243,70 +358,78 @@ enum { RAMDAC_8BIT }; +uint32_t svga_lookup_lut_ram(svga_t* svga, uint32_t val); + /* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */ -extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); -extern uint8_t ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga); -extern void ati68860_set_ramdac_type(void *p, int type); -extern void ati68860_ramdac_set_render(void *p, svga_t *svga); -extern void ati68860_ramdac_set_pallook(void *p, int i, uint32_t col); +extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); +extern uint8_t ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void ati68860_set_ramdac_type(void *priv, int type); +extern void ati68860_ramdac_set_render(void *priv, svga_t *svga); +extern void ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col); extern void ati68860_hwcursor_draw(svga_t *svga, int displine); -extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); -extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); +extern void ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); + +extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); -extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); -extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); -extern float av9194_getclock(int clock, void *p); +extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); +extern float av9194_getclock(int clock, void *priv); -extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); -extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); -extern void bt48x_recalctimings(void *p, svga_t *svga); +extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); +extern void bt48x_recalctimings(void *priv, svga_t *svga); extern void bt48x_hwcursor_draw(svga_t *svga, int displine); -extern void ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); -extern uint8_t ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); -extern void ibm_rgb528_recalctimings(void *p, svga_t *svga); +extern void ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); +extern void ibm_rgb528_recalctimings(void *priv, svga_t *svga); extern void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine); -extern void icd2061_write(void *p, int val); -extern float icd2061_getclock(int clock, void *p); +extern void icd2061_write(void *priv, int val); +extern float icd2061_getclock(int clock, void *priv); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write # define ics9161_getclock icd2061_getclock -extern float ics2494_getclock(int clock, void *p); +extern float ics2494_getclock(int clock, void *priv); -extern void ics2595_write(void *p, int strobe, int dat); -extern double ics2595_getclock(void *p); -extern void ics2595_setclock(void *p, double clock); +extern void ics2595_write(void *priv, int strobe, int dat); +extern double ics2595_getclock(void *priv); +extern void ics2595_setclock(void *priv, double clock); -extern void sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); -extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); +extern void sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); -extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); -extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga); -extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); -extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); -extern float sdac_getclock(int clock, void *p); +extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); +extern float sdac_getclock(int clock, void *priv); -extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); -extern uint8_t stg_ramdac_in(uint16_t addr, void *p, svga_t *svga); -extern float stg_getclock(int clock, void *p); +extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); +extern uint8_t stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern float stg_getclock(int clock, void *priv); -extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); -extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); +extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv, svga_t *svga); -extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); -extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); -extern void tvp3026_recalctimings(void *p, svga_t *svga); -extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); -extern float tvp3026_getclock(int clock, void *p); +extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); +extern uint32_t tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp); +extern void tvp3026_recalctimings(void *priv, svga_t *svga); +extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); +extern float tvp3026_getclock(int clock, void *priv); +extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; +extern const device_t ati68875_ramdac_device; extern const device_t att490_ramdac_device; extern const device_t att491_ramdac_device; extern const device_t att492_ramdac_device; @@ -320,6 +443,9 @@ extern const device_t bt485a_ramdac_device; extern const device_t gendac_ramdac_device; extern const device_t ibm_rgb528_ramdac_device; extern const device_t ics2494an_305_device; +extern const device_t ati18810_device; +extern const device_t ati18811_0_device; +extern const device_t ati18811_1_device; extern const device_t ics2595_device; extern const device_t icd2061_device; extern const device_t ics9161_device; diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index 13ff527e00..224d96c8e7 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -20,54 +20,70 @@ #ifndef VIDEO_SVGA_RENDER_H #define VIDEO_SVGA_RENDER_H -extern int firstline_draw, lastline_draw; +extern int firstline_draw; +extern int lastline_draw; extern int displine; extern int sc; -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; +extern uint32_t ma; +extern uint32_t ca; +extern int con; +extern int cursoron; +extern int cgablink; extern int scrollcache; extern uint8_t edatlookup[4][4]; +extern uint8_t egaremap2bpp[256]; -void svga_recalc_remap_func(svga_t *svga); +extern void svga_recalc_remap_func(svga_t *svga); -void svga_render_null(svga_t *svga); -void svga_render_blank(svga_t *svga); -void svga_render_overscan_left(svga_t *svga); -void svga_render_overscan_right(svga_t *svga); -void svga_render_text_40(svga_t *svga); -void svga_render_text_80(svga_t *svga); -void svga_render_text_80_ksc5601(svga_t *svga); +extern void svga_render_null(svga_t *svga); +extern void svga_render_blank(svga_t *svga); +extern void svga_render_overscan_left(svga_t *svga); +extern void svga_render_overscan_right(svga_t *svga); +extern void svga_render_text_40(svga_t *svga); +extern void svga_render_text_80(svga_t *svga); +extern void svga_render_text_80_ksc5601(svga_t *svga); -void svga_render_2bpp_lowres(svga_t *svga); -void svga_render_2bpp_highres(svga_t *svga); -void svga_render_2bpp_headland_highres(svga_t *svga); -void svga_render_4bpp_lowres(svga_t *svga); -void svga_render_4bpp_highres(svga_t *svga); -void svga_render_8bpp_lowres(svga_t *svga); -void svga_render_8bpp_highres(svga_t *svga); -void svga_render_8bpp_tseng_lowres(svga_t *svga); -void svga_render_8bpp_tseng_highres(svga_t *svga); -void svga_render_8bpp_gs_lowres(svga_t *svga); -void svga_render_8bpp_gs_highres(svga_t *svga); -void svga_render_8bpp_rgb_lowres(svga_t *svga); -void svga_render_8bpp_rgb_highres(svga_t *svga); -void svga_render_15bpp_lowres(svga_t *svga); -void svga_render_15bpp_highres(svga_t *svga); -void svga_render_15bpp_mix_lowres(svga_t *svga); -void svga_render_15bpp_mix_highres(svga_t *svga); -void svga_render_16bpp_lowres(svga_t *svga); -void svga_render_16bpp_highres(svga_t *svga); -void svga_render_24bpp_lowres(svga_t *svga); -void svga_render_24bpp_highres(svga_t *svga); -void svga_render_32bpp_lowres(svga_t *svga); -void svga_render_32bpp_highres(svga_t *svga); -void svga_render_ABGR8888_lowres(svga_t *svga); -void svga_render_ABGR8888_highres(svga_t *svga); -void svga_render_RGBA8888_lowres(svga_t *svga); -void svga_render_RGBA8888_highres(svga_t *svga); +extern void svga_render_2bpp_lowres(svga_t *svga); +extern void svga_render_2bpp_highres(svga_t *svga); +extern void svga_render_2bpp_headland_highres(svga_t *svga); +extern void svga_render_4bpp_lowres(svga_t *svga); +extern void svga_render_4bpp_highres(svga_t *svga); +extern void svga_render_8bpp_lowres(svga_t *svga); +extern void svga_render_8bpp_highres(svga_t *svga); +extern void svga_render_8bpp_clone_highres(svga_t *svga); +extern void svga_render_8bpp_tseng_lowres(svga_t *svga); +extern void svga_render_8bpp_tseng_highres(svga_t *svga); +extern void svga_render_8bpp_gs_lowres(svga_t *svga); +extern void svga_render_8bpp_gs_highres(svga_t *svga); +extern void svga_render_8bpp_rgb_lowres(svga_t *svga); +extern void svga_render_8bpp_rgb_highres(svga_t *svga); +extern void svga_render_15bpp_lowres(svga_t *svga); +extern void svga_render_15bpp_highres(svga_t *svga); +extern void svga_render_15bpp_mix_lowres(svga_t *svga); +extern void svga_render_15bpp_mix_highres(svga_t *svga); +extern void svga_render_16bpp_lowres(svga_t *svga); +extern void svga_render_16bpp_highres(svga_t *svga); +extern void svga_render_24bpp_lowres(svga_t *svga); +extern void svga_render_24bpp_highres(svga_t *svga); +extern void svga_render_32bpp_lowres(svga_t *svga); +extern void svga_render_32bpp_highres(svga_t *svga); +extern void svga_render_ABGR8888_lowres(svga_t *svga); +extern void svga_render_ABGR8888_highres(svga_t *svga); +extern void svga_render_RGBA8888_lowres(svga_t *svga); +extern void svga_render_RGBA8888_highres(svga_t *svga); + +extern void ibm8514_render_blank(svga_t *svga); +extern void ibm8514_render_8bpp(svga_t *svga); +extern void ibm8514_render_15bpp(svga_t *svga); +extern void ibm8514_render_16bpp(svga_t *svga); +extern void ibm8514_render_24bpp(svga_t *svga); +extern void ibm8514_render_BGR(svga_t *svga); +extern void ibm8514_render_32bpp(svga_t *svga); +extern void ibm8514_render_ABGR8888(svga_t *svga); +extern void ibm8514_render_RGBA8888(svga_t *svga); extern void (*svga_render)(svga_t *svga); diff --git a/src/include/86box/vid_vga.h b/src/include/86box/vid_vga.h index 08a1a25910..bc552b2857 100644 --- a/src/include/86box/vid_vga.h +++ b/src/include/86box/vid_vga.h @@ -30,7 +30,7 @@ typedef struct vga_t { static video_timings_t timing_vga = { VIDEO_ISA, 8, 16, 32, 8, 16, 32 }; -void vga_out(uint16_t addr, uint8_t val, void *p); -uint8_t vga_in(uint16_t addr, void *p); +void vga_out(uint16_t addr, uint8_t val, void *priv); +uint8_t vga_in(uint16_t addr, void *priv); #endif /*VIDEO_VGA_H*/ diff --git a/src/include/86box/vid_voodoo_banshee.h b/src/include/86box/vid_voodoo_banshee.h index 56fd47eeb1..89298e94e0 100644 --- a/src/include/86box/vid_voodoo_banshee.h +++ b/src/include/86box/vid_voodoo_banshee.h @@ -18,6 +18,6 @@ #ifndef VIDEO_VOODOO_BANSHEE_H #define VIDEO_VOODOO_BANSHEE_H -void banshee_set_overlay_addr(void *p, uint32_t addr); +void banshee_set_overlay_addr(void *priv, uint32_t addr); #endif /*VIDEO_VOODOO_BANSHEE_H*/ diff --git a/src/include/86box/vid_voodoo_blitter.h b/src/include/86box/vid_voodoo_blitter.h index 981c0856dd..2613521574 100644 --- a/src/include/86box/vid_voodoo_blitter.h +++ b/src/include/86box/vid_voodoo_blitter.h @@ -1,18 +1,18 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * 3DFX Voodoo emulation. + * 3DFX Voodoo emulation. * * * - * Authors: Sarah Walker, + * Authors: Sarah Walker, * - * Copyright 2008-2020 Sarah Walker. + * Copyright 2008-2020 Sarah Walker. */ #ifndef VIDEO_VOODOO_BLITTER_H diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index b50d3332a7..dc0ebce723 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -38,7 +38,9 @@ typedef struct voodoo_x86_data_t { int is_tiled; } voodoo_x86_data_t; -// static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; +#if 0 +static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; +#endif static int last_block[4] = { 0, 0 }; static int next_block_to_write[4] = { 0, 0 }; @@ -234,10 +236,12 @@ codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *pa addlong(1); addbyte(0x28); /*SUB DL, CL*/ addbyte(0xca); - // addbyte(0x8a); /*MOV DL, params->tex_shift[RSI+ECX*4]*/ - // addbyte(0x94); - // addbyte(0x8e); - // addlong(offsetof(voodoo_params_t, tex_shift)); +#if 0 + addbyte(0x8a); /*MOV DL, params->tex_shift[RSI+ECX*4]*/ + addbyte(0x94); + addbyte(0x8e); + addlong(offsetof(voodoo_params_t, tex_shift)); +#endif addbyte(0xd3); /*SHL EBP, CL*/ addbyte(0xe5); addbyte(0x8b); /*MOV EAX, state->tex_s[RDI]*/ @@ -656,24 +660,29 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; - // xmm_01_w = (__m128i)0x0001000100010001ull; - // xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; - // xmm_ff_b = (__m128i)0x00000000ffffffffull; +#if 0 + xmm_01_w = (__m128i)0x0001000100010001ull; + xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; + xmm_ff_b = (__m128i)0x00000000ffffffffull; +#endif xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); - // *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; - // block_pos = 0; - // voodoo_get_depth = &code_block[block_pos]; +#if 0 + *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; + block_pos = 0; + voodoo_get_depth = &code_block[block_pos]; +#endif /*W at (%esp+4) Z at (%esp+12) new_depth at (%esp+16)*/ - // if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) - // { - // addbyte(0xC3); /*RET*/ - // return; - // } +#if 0 + if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) { + addbyte(0xC3); /*RET*/ + return; + } +#endif addbyte(0x55); /*PUSH RBP*/ addbyte(0x57); /*PUSH RDI*/ addbyte(0x56); /*PUSH RSI*/ @@ -796,7 +805,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x75); /*JNZ got_depth*/ depth_jump_pos = block_pos; addbyte(0); - // addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); +#if 0 + addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); +#endif addbyte(0x8b); /*MOV EDX, w*/ addbyte(0x97); addlong(offsetof(voodoo_state_t, w)); @@ -810,7 +821,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x74); /*JZ got_depth*/ depth_jump_pos2 = block_pos; addbyte(0); - // addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); +#if 0 + addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); +#endif addbyte(0xb9); /*MOV ECX, 19*/ addlong(19); addbyte(0x0f); /*BSR EAX, EDX*/ @@ -2224,10 +2237,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(10); addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); - /* int fog_idx = (w_depth >> 10) & 0x3f; +#if 0 + int fog_idx = (w_depth >> 10) & 0x3f; - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ + fog_a = params->fogTable[fog_idx].fog; + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; +#endif break; case FOG_Z: @@ -2239,7 +2254,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); - // fog_a = (z >> 20) & 0xff; +#if 0 + fog_a = (z >> 20) & 0xff; +#endif break; case FOG_ALPHA: @@ -2261,7 +2278,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); - // fog_a = CLAMP(ia >> 12); +#if 0 + fog_a = CLAMP(ia >> 12); +#endif break; case FOG_W: @@ -2282,7 +2301,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); - // fog_a = CLAMP(w >> 32); +#if 0 + fog_a = CLAMP(w >> 32); +#endif break; } addbyte(0x01); /*ADD EAX, EAX*/ @@ -3164,12 +3185,11 @@ int voodoo_recomp = 0; static inline void * voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { - int c; int b = last_block[odd_even]; voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data; voodoo_x86_data_t *data; - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { data = &voodoo_x86_data[odd_even + c * 4]; //&voodoo_x86_data[odd_even][b]; if (state->xdir == data->xdir && params->alphaMode == data->alphaMode && params->fbzMode == data->fbzMode && params->fogMode == data->fogMode && params->fbzColorPath == data->fbzColorPath && (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && params->textureMode[0] == data->textureMode[0] && params->textureMode[1] == data->textureMode[1] && (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && (params->tLOD[1] & LOD_MASK) == data->tLOD[1] && ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) { @@ -3181,7 +3201,9 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat } voodoo_recomp++; data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even] * 4]; - // code_block = data->code_block; +#if 0 + code_block = data->code_block; +#endif voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3205,11 +3227,9 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat void voodoo_codegen_init(voodoo_t *voodoo) { - int c; - voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, 1); - for (c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { int d[4]; int _ds = c & 0xf; int dt = c >> 4; diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index 9454c9bff3..996bd28f1a 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -639,24 +639,29 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; - // xmm_01_w = (__m128i)0x0001000100010001ull; - // xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; - // xmm_ff_b = (__m128i)0x00000000ffffffffull; +#if 0 + xmm_01_w = (__m128i)0x0001000100010001ull; + xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; + xmm_ff_b = (__m128i)0x00000000ffffffffull; +#endif xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); - // *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; - // block_pos = 0; - // voodoo_get_depth = &code_block[block_pos]; +#if 0 + *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; + block_pos = 0; + voodoo_get_depth = &code_block[block_pos]; +#endif /*W at (%esp+4) Z at (%esp+12) new_depth at (%esp+16)*/ - // if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) - // { - // addbyte(0xC3); /*RET*/ - // return; - // } +#if 0 + if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) { + addbyte(0xC3); /*RET*/ + return; + } +#endif addbyte(0x55); /*PUSH EBP*/ addbyte(0x57); /*PUSH EDI*/ addbyte(0x56); /*PUSH ESI*/ @@ -871,16 +876,19 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, fatal("Bad depth_op\n"); } else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) { addbyte(0xC3); /*RET*/ - // addbyte(0x30); /*XOR EAX, EAX*/ - // addbyte(0xc0); +#if 0 + addbyte(0x30); /*XOR EAX, EAX*/ + addbyte(0xc0); +#endif + } +#if 0 + else { + addbyte(0xb0); /*MOV AL, 1*/ + addbyte(1); } - // else - // { - // addbyte(0xb0); /*MOV AL, 1*/ - // addbyte(1); - // } - // voodoo_combine = &code_block[block_pos]; + voodoo_combine = &code_block[block_pos]; +#endif /*XMM0 = colour*/ /*XMM2 = 0 (for unpacking*/ @@ -2076,12 +2084,13 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x05); addlong((uint32_t) &xmm_ff_b); } - // #if 0 - // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ - // addbyte(0x0f); - // addbyte(0x7e); - // addbyte(0x87); - // addlong(offsetof(voodoo_state_t, out)); +#if 0 + addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x87); + addlong(offsetof(voodoo_state_t, out)); +#endif if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ @@ -2093,11 +2102,18 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); addbyte(0xdc); addbyte(0xc3); - /* src_r += params->fogColor.r; - src_g += params->fogColor.g; - src_b += params->fogColor.b; */ +#if 0 + src_r += params->fogColor.r; + src_g += params->fogColor.g; + src_b += params->fogColor.b; */ +#endif } else { - /*int fog_r, fog_g, fog_b, fog_a; */ +#if 0 + int fog_r; + int fog_g; + int fog_b; + int fog_a; +#endif addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); @@ -2168,10 +2184,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); - /* int fog_idx = (w_depth >> 10) & 0x3f; +#if 0 + int fog_idx = (w_depth >> 10) & 0x3f; - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ + fog_a = params->fogTable[fog_idx].fog; + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; +#endif break; case FOG_Z: @@ -2183,7 +2201,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); - // fog_a = (z >> 20) & 0xff; +#if 0 + fog_a = (z >> 20) & 0xff; +#endif break; case FOG_ALPHA: @@ -2205,7 +2225,9 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); - // fog_a = CLAMP(ia >> 12); +#if 0 + fog_a = CLAMP(ia >> 12); +#endif break; case FOG_W: @@ -2226,13 +2248,16 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); - // fog_a = CLAMP(w >> 32); +#if 0 + fog_a = CLAMP(w >> 32); +#endif break; } addbyte(0x01); /*ADD EAX, EAX*/ addbyte(0xc0); - // fog_a++; - +#if 0 + fog_a++; +#endif addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ addbyte(0x0f); addbyte(0xd5); @@ -2244,9 +2269,11 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x71); addbyte(0xe3); addbyte(7); - /* fog_r = (fog_r * fog_a) >> 8; - fog_g = (fog_g * fog_a) >> 8; - fog_b = (fog_b * fog_a) >> 8;*/ +#if 0 + fog_r = (fog_r * fog_a) >> 8; + fog_g = (fog_g * fog_a) >> 8; + fog_b = (fog_b * fog_a) >> 8; +#endif if (params->fogMode & FOG_MULT) { addbyte(0xf3); /*MOV XMM0, XMM3*/ @@ -2258,9 +2285,11 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); addbyte(0xfd); addbyte(0xc3); - /* src_r += fog_r; - src_g += fog_g; - src_b += fog_b;*/ +#if 0 + src_r += fog_r; + src_g += fog_g; + src_b += fog_b; +#endif } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ addbyte(0x0f); @@ -2268,9 +2297,11 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xc0); } - /* src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b);*/ +#if 0 + src_r = CLAMP(src_r); + src_g = CLAMP(src_g); + src_b = CLAMP(src_b); +#endif } if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) { @@ -2696,12 +2727,13 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x67); addbyte(0xc0); } - // #endif - // addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ - // addbyte(0x54); - // addbyte(0x24); - // addbyte(12); +#if 0 + addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ + addbyte(0x54); + addbyte(0x24); + addbyte(12); +#endif addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); @@ -2716,9 +2748,11 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xc0); if (params->fbzMode & FBZ_RGB_WMASK) { - // addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ - // addbyte(0x87); - // addlong(offsetof(voodoo_state_t, rgb_out)); +#if 0 + addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, rgb_out)); +#endif if (dither) { addbyte(0x8b); /*MOV ESI, real_y (ESP+16)*/ @@ -3118,7 +3152,9 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat } voodoo_recomp++; data = &codegen_data[odd_even + next_block_to_write[odd_even] * 4]; - // code_block = data->code_block; +#if 0 + code_block = data->code_block; +#endif voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3142,11 +3178,9 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat void voodoo_codegen_init(voodoo_t *voodoo) { - int c; - voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, 1); - for (c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { int d[4]; int _ds = c & 0xf; int dt = c >> 4; diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 6eae0bf6dd..96865ac6d9 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -271,6 +271,8 @@ typedef struct voodoo_t { int pci_enable; + uint8_t pci_slot; + uint8_t dac_data[8]; int dac_reg; int dac_reg_ff; @@ -348,8 +350,7 @@ typedef struct voodoo_t { int h_disp; int v_retrace; - struct - { + struct { uint32_t y[4]; uint32_t i[4]; uint32_t q[4]; @@ -487,8 +488,7 @@ typedef struct voodoo_t { uint32_t leftOverlayBuf; - struct - { + struct { int dst_x; int dst_y; int cur_x; @@ -499,8 +499,7 @@ typedef struct voodoo_t { int dst_stride; } blt; - struct - { + struct { uint32_t bresError0; uint32_t bresError1; uint32_t clip0Min; @@ -588,15 +587,16 @@ typedef struct voodoo_t { int line_bit_mask_size; } banshee_blt; - struct - { + struct { uint32_t vidOverlayStartCoords; uint32_t vidOverlayEndScreenCoords; uint32_t vidOverlayDudx; uint32_t vidOverlayDudxOffsetSrcWidth; uint32_t vidOverlayDvdy; uint32_t vidOverlayDvdyOffset; - // uint32_t vidDesktopOverlayStride; +#if 0 + uint32_t vidDesktopOverlayStride; +#endif int start_x; int start_y; @@ -667,7 +667,7 @@ typedef struct voodoo_t { uint8_t *vram; uint8_t *changedvram; - void *p; + void *priv; uint8_t monitor_index; } voodoo_t; diff --git a/src/include/86box/vid_voodoo_display.h b/src/include/86box/vid_voodoo_display.h index 25b3e9b1a6..f046263bf4 100644 --- a/src/include/86box/vid_voodoo_display.h +++ b/src/include/86box/vid_voodoo_display.h @@ -24,6 +24,6 @@ void voodoo_pixelclock_update(voodoo_t *voodoo); void voodoo_generate_filter_v1(voodoo_t *voodoo); void voodoo_generate_filter_v2(voodoo_t *voodoo); void voodoo_threshold_check(voodoo_t *voodoo); -void voodoo_callback(void *p); +void voodoo_callback(void *priv); #endif /*VIDEO_VOODOO_DISPLAY_H*/ diff --git a/src/include/86box/vid_voodoo_dither.h b/src/include/86box/vid_voodoo_dither.h index 3580cada24..51ec91f2e3 100644 --- a/src/include/86box/vid_voodoo_dither.h +++ b/src/include/86box/vid_voodoo_dither.h @@ -19,5145 +19,5140 @@ #ifndef VIDEO_VOODOO_DITHER_H #define VIDEO_VOODOO_DITHER_H -static const uint8_t dither_rb[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 0, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {0, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 1, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {3, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 3, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 3, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 3}, - {2, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {3, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {4, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 3}, - {4, 3, 4, 3}, - {3, 4, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 4, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {5, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 5, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {6, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {6, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {7, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 6}, - {7, 6, 7, 6}, - {6, 7, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 7, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 6, 7}, - {7, 7, 7, 7}, - {7, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {8, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 7}, - {8, 7, 8, 7}, - {7, 8, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 8, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 7, 8}, - {8, 8, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {9, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 9}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 9, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {10, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 10}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 9, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 10}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 10, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 11}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {11, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 12, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {12, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 13, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 14}, - {13, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 15, 14}, - {14, 14, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 15}, - {14, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 16, 15}, - {15, 15, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 16}, - {15, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 17, 16}, - {16, 16, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 17}, - {16, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 18, 17}, - {17, 17, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {17, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 18, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {18, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {20, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {21, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 21, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 21, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {21, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {22, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {21, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 22, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {22, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 24, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 24, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 23, 24}, - {24, 24, 24, 24}, - {24, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {25, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 24}, - {25, 24, 25, 24}, - {24, 25, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 25, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 24, 25}, - {25, 25, 25, 25}, - {25, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {26, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 25}, - {26, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 26, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {27, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 27, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 27}, - {28, 27, 28, 27}, - {27, 28, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 27, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 28}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 28, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {30, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 30}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 30, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {31, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 31}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 31, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - }, +static const uint8_t dither_rb[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {1, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 0, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 1}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 1, 1, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 1}, + }, + { + {0, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 0, 1}, + {1, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {1, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {2, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 1, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 2}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 2, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {1, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {1, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {3, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 3, 2}, + {2, 2, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 2, 2, 2}, + {3, 2, 3, 2}, + {2, 3, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 2, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 3, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 3}, + {2, 3, 2, 3}, + {3, 3, 3, 3}, + }, + { + {2, 3, 2, 3}, + {3, 3, 3, 3}, + {3, 3, 2, 3}, + {3, 3, 3, 3}, + }, + { + {2, 3, 3, 3}, + {3, 3, 3, 3}, + {3, 3, 3, 3}, + {3, 3, 3, 3}, + }, + { + {3, 3, 3, 3}, + {3, 3, 3, 3}, + {3, 3, 3, 3}, + {4, 3, 3, 3}, + }, + { + {3, 3, 3, 3}, + {3, 3, 4, 3}, + {3, 3, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 3, 3, 3}, + {4, 3, 4, 3}, + {3, 4, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 3, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 4, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 4}, + {3, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 3, 4}, + {4, 4, 4, 4}, + {4, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {5, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 4, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 5}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 5, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {4, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {6, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 5, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 6}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 6, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 5, 6}, + {6, 6, 6, 6}, + {6, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {7, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 7, 6}, + {6, 6, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 6}, + {7, 6, 7, 6}, + {6, 7, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 6, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 7, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 7}, + {6, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 6, 7}, + {7, 7, 7, 7}, + {7, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {8, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 8, 7}, + {7, 7, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 7}, + {8, 7, 8, 7}, + {7, 8, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 7, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 8, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 7, 8}, + {8, 8, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {9, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 8, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 9}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 9, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {8, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {10, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 9, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 10}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {9, 10, 9, 10}, + {10, 10, 10, 10}, + {10, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {9, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {11, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 11, 10}, + {10, 10, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 10, 10, 10}, + {11, 10, 11, 10}, + {10, 11, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 10, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 11}, + {11, 10, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 11}, + {11, 11, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 11}, + {10, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {10, 11, 10, 11}, + {11, 11, 11, 11}, + {11, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {10, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {12, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 12, 11}, + {11, 11, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 11, 11, 11}, + {12, 11, 12, 11}, + {11, 12, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 11, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 12}, + {12, 11, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 12, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {11, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 13, 12}, + {12, 12, 12, 12}, + {13, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {13, 12, 13, 12}, + {12, 12, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 12, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 13}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 13}, + {12, 13, 12, 13}, + {13, 13, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 13, 13, 13}, + {12, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {12, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 14, 13}, + {13, 13, 13, 13}, + {14, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {14, 13, 14, 13}, + {13, 13, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 13, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 14, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 14}, + {13, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {13, 14, 13, 14}, + {14, 14, 14, 14}, + {14, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {13, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {15, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 15, 14}, + {14, 14, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 14, 14, 14}, + {15, 14, 15, 14}, + {14, 15, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 14, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 14, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 15, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 15}, + {14, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {14, 15, 14, 15}, + {15, 15, 15, 15}, + {15, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {14, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {16, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 16, 15}, + {15, 15, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 15, 15, 15}, + {16, 15, 16, 15}, + {15, 16, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 15, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 15, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 16, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 16}, + {15, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {15, 16, 15, 16}, + {16, 16, 16, 16}, + {16, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {15, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {17, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 17, 16}, + {16, 16, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 16, 16, 16}, + {17, 16, 17, 16}, + {16, 17, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 16, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 16, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 17, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 17}, + {16, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {16, 17, 16, 17}, + {17, 17, 17, 17}, + {17, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {16, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {18, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 18, 17}, + {17, 17, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 17, 17, 17}, + {18, 17, 18, 17}, + {17, 18, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 17, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 18}, + {17, 18, 17, 18}, + {18, 18, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 18, 18, 18}, + {17, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {17, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 19, 18}, + {18, 18, 18, 18}, + {19, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {19, 18, 19, 18}, + {18, 18, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 18, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 19}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 19}, + {18, 19, 18, 19}, + {19, 19, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 19, 19, 19}, + {18, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {18, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 20, 19}, + {19, 19, 19, 19}, + {20, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {20, 19, 20, 19}, + {19, 19, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 19, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 19, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 19, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 20, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 20}, + {19, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {19, 20, 19, 20}, + {20, 20, 20, 20}, + {20, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {19, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {21, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 21, 20}, + {20, 20, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 20, 20, 20}, + {21, 20, 21, 20}, + {20, 21, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 20, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 21, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 21}, + {20, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {20, 21, 20, 21}, + {21, 21, 21, 21}, + {21, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {20, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {22, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 22, 21}, + {21, 21, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 21, 21, 21}, + {22, 21, 22, 21}, + {21, 22, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 21, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 22}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 22, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {21, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {23, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 22, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 23}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 23, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {22, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 24, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 23, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 24, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 24}, + {23, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 23, 24}, + {24, 24, 24, 24}, + {24, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {25, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 25, 24}, + {24, 24, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 24}, + {25, 24, 25, 24}, + {24, 25, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 24, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 25, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 25}, + {24, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 24, 25}, + {25, 25, 25, 25}, + {25, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {26, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 25}, + {26, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 26}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 26, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {25, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {27, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 26, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 27}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 27, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {26, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 27}, + {28, 27, 28, 27}, + {27, 28, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 27, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 28, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 28}, + {27, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {27, 28, 27, 28}, + {28, 28, 28, 28}, + {28, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {27, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {29, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 29, 28}, + {28, 28, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 28, 28, 28}, + {29, 28, 29, 28}, + {28, 29, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 28, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 29}, + {29, 28, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 29}, + {29, 29, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 29}, + {28, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {28, 29, 28, 29}, + {29, 29, 29, 29}, + {29, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {28, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {30, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 29, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 30}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 30, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {29, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {31, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 30, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 31}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 31, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {30, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {31, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 31, 31}, + }, }; -static const uint8_t dither_g[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {2, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {4, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 32, 31}, - {31, 31, 31, 31}, - {32, 31, 31, 31}, - }, - { - {31, 31, 31, 32}, - {32, 31, 32, 31}, - {31, 32, 31, 31}, - {32, 31, 32, 31}, - }, - { - {31, 32, 31, 32}, - {32, 31, 32, 32}, - {31, 32, 31, 32}, - {32, 32, 32, 31}, - }, - { - {31, 32, 32, 32}, - {32, 32, 32, 32}, - {32, 32, 31, 32}, - {32, 32, 32, 32}, - }, - { - {32, 32, 32, 32}, - {32, 32, 33, 32}, - {32, 32, 32, 32}, - {33, 32, 32, 32}, - }, - { - {32, 32, 32, 33}, - {33, 32, 33, 32}, - {32, 33, 32, 32}, - {33, 32, 33, 32}, - }, - { - {32, 33, 32, 33}, - {33, 32, 33, 33}, - {32, 33, 32, 33}, - {33, 33, 33, 32}, - }, - { - {32, 33, 33, 33}, - {33, 33, 33, 33}, - {33, 33, 32, 33}, - {33, 33, 33, 33}, - }, - { - {33, 33, 33, 33}, - {33, 33, 34, 33}, - {33, 33, 33, 33}, - {34, 33, 33, 33}, - }, - { - {33, 33, 33, 34}, - {34, 33, 34, 33}, - {33, 34, 33, 33}, - {34, 33, 34, 33}, - }, - { - {33, 34, 33, 34}, - {34, 33, 34, 34}, - {33, 34, 33, 34}, - {34, 34, 34, 33}, - }, - { - {33, 34, 34, 34}, - {34, 34, 34, 34}, - {34, 34, 33, 34}, - {34, 34, 34, 34}, - }, - { - {34, 34, 34, 34}, - {34, 34, 35, 34}, - {34, 34, 34, 34}, - {35, 34, 34, 34}, - }, - { - {34, 34, 34, 35}, - {35, 34, 35, 34}, - {34, 35, 34, 34}, - {35, 34, 35, 34}, - }, - { - {34, 35, 34, 35}, - {35, 34, 35, 35}, - {34, 35, 34, 35}, - {35, 35, 35, 34}, - }, - { - {34, 35, 35, 35}, - {35, 35, 35, 35}, - {35, 35, 34, 35}, - {35, 35, 35, 35}, - }, - { - {35, 35, 35, 35}, - {35, 35, 36, 35}, - {35, 35, 35, 35}, - {36, 35, 35, 35}, - }, - { - {35, 35, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 35}, - {36, 35, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 36}, - {36, 36, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 36, 36, 36}, - {36, 36, 35, 36}, - {36, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {37, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {37, 36, 37, 36}, - {36, 37, 36, 36}, - {37, 36, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 36, 37, 36}, - {36, 37, 36, 37}, - {37, 37, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 37, 37, 37}, - {37, 37, 36, 37}, - {37, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {38, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {38, 37, 38, 37}, - {37, 38, 37, 37}, - {38, 37, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 37, 38, 37}, - {37, 38, 37, 38}, - {38, 38, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 38, 38, 38}, - {38, 38, 37, 38}, - {38, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {39, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {39, 38, 39, 38}, - {38, 39, 38, 38}, - {39, 38, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 38, 39, 38}, - {38, 39, 38, 39}, - {39, 39, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 39, 39, 39}, - {39, 39, 38, 39}, - {39, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {40, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {40, 39, 40, 39}, - {39, 40, 39, 39}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 39, 40, 39}, - {39, 40, 39, 40}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 40, 40, 40}, - {39, 40, 39, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {41, 40, 41, 40}, - {40, 40, 40, 40}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 40, 41, 40}, - {40, 41, 40, 41}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 41, 41, 41}, - {40, 41, 40, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {42, 41, 42, 41}, - {41, 41, 41, 41}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 41, 42, 41}, - {41, 42, 41, 42}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 42, 42, 42}, - {41, 42, 41, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {43, 42, 43, 42}, - {42, 42, 42, 42}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 42, 43, 42}, - {42, 43, 42, 43}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 43, 43, 43}, - {42, 43, 42, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {44, 43, 44, 43}, - {43, 43, 43, 43}, - {44, 43, 44, 43}, - }, - { - {43, 43, 43, 44}, - {44, 43, 44, 43}, - {43, 44, 43, 44}, - {44, 43, 44, 43}, - }, - { - {43, 44, 43, 44}, - {44, 43, 44, 44}, - {43, 44, 43, 44}, - {44, 44, 44, 44}, - }, - { - {43, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - }, - { - {44, 44, 44, 44}, - {44, 44, 45, 44}, - {44, 44, 44, 44}, - {45, 44, 45, 44}, - }, - { - {44, 44, 44, 45}, - {45, 44, 45, 44}, - {44, 45, 44, 45}, - {45, 44, 45, 44}, - }, - { - {44, 45, 44, 45}, - {45, 44, 45, 45}, - {44, 45, 44, 45}, - {45, 45, 45, 45}, - }, - { - {44, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - }, - { - {45, 45, 45, 45}, - {45, 45, 46, 45}, - {45, 45, 45, 45}, - {46, 45, 46, 45}, - }, - { - {45, 45, 45, 46}, - {46, 45, 46, 45}, - {45, 46, 45, 46}, - {46, 45, 46, 45}, - }, - { - {45, 46, 45, 46}, - {46, 45, 46, 46}, - {45, 46, 45, 46}, - {46, 46, 46, 46}, - }, - { - {45, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - }, - { - {46, 46, 46, 46}, - {46, 46, 47, 46}, - {46, 46, 46, 46}, - {47, 46, 47, 46}, - }, - { - {46, 46, 46, 47}, - {47, 46, 47, 46}, - {46, 47, 46, 47}, - {47, 46, 47, 46}, - }, - { - {46, 47, 46, 47}, - {47, 46, 47, 47}, - {46, 47, 46, 47}, - {47, 47, 47, 47}, - }, - { - {46, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - }, - { - {47, 47, 47, 47}, - {47, 47, 48, 47}, - {47, 47, 47, 47}, - {48, 47, 48, 47}, - }, - { - {47, 47, 47, 48}, - {48, 47, 48, 47}, - {47, 48, 47, 48}, - {48, 47, 48, 47}, - }, - { - {47, 48, 47, 48}, - {48, 47, 48, 48}, - {47, 48, 47, 48}, - {48, 48, 48, 48}, - }, - { - {47, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - }, - { - {48, 48, 48, 48}, - {48, 48, 49, 48}, - {48, 48, 48, 48}, - {49, 48, 49, 48}, - }, - { - {48, 48, 48, 49}, - {49, 48, 49, 48}, - {48, 49, 48, 49}, - {49, 48, 49, 48}, - }, - { - {48, 49, 48, 49}, - {49, 48, 49, 49}, - {48, 49, 48, 49}, - {49, 49, 49, 49}, - }, - { - {48, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - }, - { - {49, 49, 49, 49}, - {49, 49, 50, 49}, - {49, 49, 49, 49}, - {50, 49, 50, 49}, - }, - { - {49, 49, 49, 50}, - {50, 49, 50, 49}, - {49, 50, 49, 50}, - {50, 49, 50, 49}, - }, - { - {49, 50, 49, 50}, - {50, 49, 50, 50}, - {49, 50, 49, 50}, - {50, 50, 50, 50}, - }, - { - {49, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - }, - { - {50, 50, 50, 50}, - {50, 50, 51, 50}, - {50, 50, 50, 50}, - {51, 50, 51, 50}, - }, - { - {50, 50, 50, 51}, - {51, 50, 51, 50}, - {50, 51, 50, 51}, - {51, 50, 51, 50}, - }, - { - {50, 51, 50, 51}, - {51, 50, 51, 51}, - {50, 51, 50, 51}, - {51, 51, 51, 51}, - }, - { - {50, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - }, - { - {51, 51, 51, 51}, - {51, 51, 52, 51}, - {51, 51, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 51, 51, 52}, - {52, 51, 52, 51}, - {51, 52, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 52, 51, 52}, - {52, 51, 52, 52}, - {51, 52, 51, 52}, - {52, 52, 52, 51}, - }, - { - {51, 52, 52, 52}, - {52, 52, 52, 52}, - {52, 52, 51, 52}, - {52, 52, 52, 52}, - }, - { - {52, 52, 52, 52}, - {52, 52, 53, 52}, - {52, 52, 52, 52}, - {53, 52, 52, 52}, - }, - { - {52, 52, 52, 53}, - {53, 52, 53, 52}, - {52, 53, 52, 52}, - {53, 52, 53, 52}, - }, - { - {52, 53, 52, 53}, - {53, 52, 53, 53}, - {52, 53, 52, 53}, - {53, 53, 53, 52}, - }, - { - {52, 53, 53, 53}, - {53, 53, 53, 53}, - {53, 53, 52, 53}, - {53, 53, 53, 53}, - }, - { - {53, 53, 53, 53}, - {53, 53, 54, 53}, - {53, 53, 53, 53}, - {54, 53, 53, 53}, - }, - { - {53, 53, 53, 54}, - {54, 53, 54, 53}, - {53, 54, 53, 53}, - {54, 53, 54, 53}, - }, - { - {53, 54, 53, 54}, - {54, 53, 54, 54}, - {53, 54, 53, 54}, - {54, 54, 54, 53}, - }, - { - {53, 54, 54, 54}, - {54, 54, 54, 54}, - {54, 54, 53, 54}, - {54, 54, 54, 54}, - }, - { - {54, 54, 54, 54}, - {54, 54, 55, 54}, - {54, 54, 54, 54}, - {55, 54, 54, 54}, - }, - { - {54, 54, 54, 55}, - {55, 54, 55, 54}, - {54, 55, 54, 54}, - {55, 54, 55, 54}, - }, - { - {54, 55, 54, 55}, - {55, 54, 55, 55}, - {54, 55, 54, 55}, - {55, 55, 55, 54}, - }, - { - {54, 55, 55, 55}, - {55, 55, 55, 55}, - {55, 55, 54, 55}, - {55, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {55, 55, 56, 55}, - {55, 55, 55, 55}, - {56, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {56, 55, 56, 55}, - {55, 56, 55, 55}, - {56, 55, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 55, 56, 55}, - {55, 56, 55, 56}, - {56, 56, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 56, 56, 56}, - {56, 56, 55, 56}, - {56, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {57, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {57, 56, 57, 56}, - {56, 57, 56, 56}, - {57, 56, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 56, 57, 56}, - {56, 57, 56, 57}, - {57, 57, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 57, 57, 57}, - {57, 57, 56, 57}, - {57, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {58, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {58, 57, 58, 57}, - {57, 58, 57, 57}, - {58, 57, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 57, 58, 57}, - {57, 58, 57, 58}, - {58, 58, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 58, 58, 58}, - {58, 58, 57, 58}, - {58, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {59, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {59, 58, 59, 58}, - {58, 59, 58, 58}, - {59, 58, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 58, 59, 58}, - {58, 59, 58, 59}, - {59, 59, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 59, 59, 59}, - {59, 59, 58, 59}, - {59, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {60, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {60, 59, 60, 59}, - {59, 59, 59, 59}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 59, 60, 59}, - {59, 60, 59, 60}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 60, 60, 60}, - {59, 60, 59, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {61, 60, 61, 60}, - {60, 60, 60, 60}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 60, 61, 60}, - {60, 61, 60, 61}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 61, 61, 61}, - {60, 61, 60, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {62, 61, 62, 61}, - {61, 61, 61, 61}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 61, 62, 61}, - {61, 62, 61, 62}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 62, 62, 62}, - {61, 62, 61, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {63, 62, 63, 62}, - {62, 62, 62, 62}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 62, 63, 62}, - {62, 63, 62, 63}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 63, 63, 63}, - {62, 63, 62, 63}, - {63, 63, 63, 63}, - }, - { - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - }, +static const uint8_t dither_g[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {1, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 1}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 1, 1, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {2, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 2}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 2, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {3, 2, 3, 2}, + {2, 2, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 3, 3, 3}, + {2, 3, 2, 3}, + {3, 3, 3, 3}, + }, + { + {3, 3, 3, 3}, + {3, 3, 3, 3}, + {3, 3, 3, 3}, + {3, 3, 3, 3}, + }, + { + {3, 3, 3, 3}, + {4, 3, 4, 3}, + {3, 3, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 4, 4, 4}, + {3, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 4, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 5}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {4, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 5, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 6}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 7, 6}, + {6, 6, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 6, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 7}, + {6, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 8, 7}, + {7, 7, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 7, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 8, 8}, + }, + { + {8, 8, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 8}, + }, + { + {8, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 9, 9}, + }, + { + {9, 9, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 9}, + }, + { + {9, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 11, 10}, + {10, 10, 10, 10}, + {11, 10, 10, 10}, + }, + { + {10, 10, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 11}, + {10, 11, 10, 11}, + {11, 11, 11, 10}, + }, + { + {10, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 12, 11}, + {11, 11, 11, 11}, + {12, 11, 11, 11}, + }, + { + {11, 11, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 12, 12, 12}, + {12, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {13, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {13, 12, 13, 12}, + {12, 13, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 13}, + {13, 13, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 13, 13, 13}, + {13, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {14, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {14, 13, 14, 13}, + {13, 14, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 14, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 14, 14, 14}, + {14, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {15, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {15, 14, 15, 14}, + {14, 15, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 15, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 15, 15, 15}, + {15, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {16, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {16, 15, 16, 15}, + {15, 16, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 16, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 16, 16, 16}, + {16, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {17, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {17, 16, 17, 16}, + {16, 17, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 17, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 17, 17, 17}, + {17, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {18, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {18, 17, 18, 17}, + {17, 18, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 18, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 18, 18, 18}, + {18, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {19, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {19, 18, 19, 18}, + {18, 19, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 19}, + {19, 19, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 19, 19, 19}, + {19, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {20, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {20, 19, 20, 19}, + {19, 20, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 20, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 20, 20, 20}, + {19, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {21, 20, 21, 20}, + {20, 20, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 21, 21, 21}, + {20, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {22, 21, 22, 21}, + {21, 21, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 22}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 22, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {23, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 23}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 23, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 24}, + {23, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 25, 24}, + {24, 24, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 24, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 25}, + {24, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 26}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {25, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 26, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 27}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {26, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 27, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 28}, + {27, 28, 27, 28}, + {28, 28, 28, 27}, + }, + { + {27, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 29, 28}, + {28, 28, 28, 28}, + {29, 28, 28, 28}, + }, + { + {28, 28, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 29}, + {28, 29, 28, 29}, + {29, 29, 29, 28}, + }, + { + {28, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 29}, + }, + { + {29, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 30, 30}, + }, + { + {30, 30, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 30}, + }, + { + {30, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {31, 31, 31, 31}, + {31, 31, 32, 31}, + {31, 31, 31, 31}, + {32, 31, 31, 31}, + }, + { + {31, 31, 31, 32}, + {32, 31, 32, 31}, + {31, 32, 31, 31}, + {32, 31, 32, 31}, + }, + { + {31, 32, 31, 32}, + {32, 31, 32, 32}, + {31, 32, 31, 32}, + {32, 32, 32, 31}, + }, + { + {31, 32, 32, 32}, + {32, 32, 32, 32}, + {32, 32, 31, 32}, + {32, 32, 32, 32}, + }, + { + {32, 32, 32, 32}, + {32, 32, 33, 32}, + {32, 32, 32, 32}, + {33, 32, 32, 32}, + }, + { + {32, 32, 32, 33}, + {33, 32, 33, 32}, + {32, 33, 32, 32}, + {33, 32, 33, 32}, + }, + { + {32, 33, 32, 33}, + {33, 32, 33, 33}, + {32, 33, 32, 33}, + {33, 33, 33, 32}, + }, + { + {32, 33, 33, 33}, + {33, 33, 33, 33}, + {33, 33, 32, 33}, + {33, 33, 33, 33}, + }, + { + {33, 33, 33, 33}, + {33, 33, 34, 33}, + {33, 33, 33, 33}, + {34, 33, 33, 33}, + }, + { + {33, 33, 33, 34}, + {34, 33, 34, 33}, + {33, 34, 33, 33}, + {34, 33, 34, 33}, + }, + { + {33, 34, 33, 34}, + {34, 33, 34, 34}, + {33, 34, 33, 34}, + {34, 34, 34, 33}, + }, + { + {33, 34, 34, 34}, + {34, 34, 34, 34}, + {34, 34, 33, 34}, + {34, 34, 34, 34}, + }, + { + {34, 34, 34, 34}, + {34, 34, 35, 34}, + {34, 34, 34, 34}, + {35, 34, 34, 34}, + }, + { + {34, 34, 34, 35}, + {35, 34, 35, 34}, + {34, 35, 34, 34}, + {35, 34, 35, 34}, + }, + { + {34, 35, 34, 35}, + {35, 34, 35, 35}, + {34, 35, 34, 35}, + {35, 35, 35, 34}, + }, + { + {34, 35, 35, 35}, + {35, 35, 35, 35}, + {35, 35, 34, 35}, + {35, 35, 35, 35}, + }, + { + {35, 35, 35, 35}, + {35, 35, 36, 35}, + {35, 35, 35, 35}, + {36, 35, 35, 35}, + }, + { + {35, 35, 35, 36}, + {36, 35, 36, 35}, + {35, 36, 35, 35}, + {36, 35, 36, 35}, + }, + { + {35, 36, 35, 36}, + {36, 35, 36, 35}, + {35, 36, 35, 36}, + {36, 36, 36, 35}, + }, + { + {35, 36, 35, 36}, + {36, 36, 36, 36}, + {36, 36, 35, 36}, + {36, 36, 36, 36}, + }, + { + {36, 36, 36, 36}, + {36, 36, 36, 36}, + {36, 36, 36, 36}, + {37, 36, 36, 36}, + }, + { + {36, 36, 36, 36}, + {37, 36, 37, 36}, + {36, 37, 36, 36}, + {37, 36, 37, 36}, + }, + { + {36, 37, 36, 37}, + {37, 36, 37, 36}, + {36, 37, 36, 37}, + {37, 37, 37, 36}, + }, + { + {36, 37, 36, 37}, + {37, 37, 37, 37}, + {37, 37, 36, 37}, + {37, 37, 37, 37}, + }, + { + {37, 37, 37, 37}, + {37, 37, 37, 37}, + {37, 37, 37, 37}, + {38, 37, 37, 37}, + }, + { + {37, 37, 37, 37}, + {38, 37, 38, 37}, + {37, 38, 37, 37}, + {38, 37, 38, 37}, + }, + { + {37, 38, 37, 38}, + {38, 37, 38, 37}, + {37, 38, 37, 38}, + {38, 38, 38, 37}, + }, + { + {37, 38, 37, 38}, + {38, 38, 38, 38}, + {38, 38, 37, 38}, + {38, 38, 38, 38}, + }, + { + {38, 38, 38, 38}, + {38, 38, 38, 38}, + {38, 38, 38, 38}, + {39, 38, 38, 38}, + }, + { + {38, 38, 38, 38}, + {39, 38, 39, 38}, + {38, 39, 38, 38}, + {39, 38, 39, 38}, + }, + { + {38, 39, 38, 39}, + {39, 38, 39, 38}, + {38, 39, 38, 39}, + {39, 39, 39, 38}, + }, + { + {38, 39, 38, 39}, + {39, 39, 39, 39}, + {39, 39, 38, 39}, + {39, 39, 39, 39}, + }, + { + {39, 39, 39, 39}, + {39, 39, 39, 39}, + {39, 39, 39, 39}, + {40, 39, 39, 39}, + }, + { + {39, 39, 39, 39}, + {40, 39, 40, 39}, + {39, 40, 39, 39}, + {40, 39, 40, 39}, + }, + { + {39, 40, 39, 40}, + {40, 39, 40, 39}, + {39, 40, 39, 40}, + {40, 39, 40, 39}, + }, + { + {39, 40, 39, 40}, + {40, 40, 40, 40}, + {39, 40, 39, 40}, + {40, 40, 40, 40}, + }, + { + {40, 40, 40, 40}, + {40, 40, 40, 40}, + {40, 40, 40, 40}, + {40, 40, 40, 40}, + }, + { + {40, 40, 40, 40}, + {41, 40, 41, 40}, + {40, 40, 40, 40}, + {41, 40, 41, 40}, + }, + { + {40, 41, 40, 41}, + {41, 40, 41, 40}, + {40, 41, 40, 41}, + {41, 40, 41, 40}, + }, + { + {40, 41, 40, 41}, + {41, 41, 41, 41}, + {40, 41, 40, 41}, + {41, 41, 41, 41}, + }, + { + {41, 41, 41, 41}, + {41, 41, 41, 41}, + {41, 41, 41, 41}, + {41, 41, 41, 41}, + }, + { + {41, 41, 41, 41}, + {42, 41, 42, 41}, + {41, 41, 41, 41}, + {42, 41, 42, 41}, + }, + { + {41, 42, 41, 42}, + {42, 41, 42, 41}, + {41, 42, 41, 42}, + {42, 41, 42, 41}, + }, + { + {41, 42, 41, 42}, + {42, 42, 42, 42}, + {41, 42, 41, 42}, + {42, 42, 42, 42}, + }, + { + {42, 42, 42, 42}, + {42, 42, 42, 42}, + {42, 42, 42, 42}, + {42, 42, 42, 42}, + }, + { + {42, 42, 42, 42}, + {43, 42, 43, 42}, + {42, 42, 42, 42}, + {43, 42, 43, 42}, + }, + { + {42, 43, 42, 43}, + {43, 42, 43, 42}, + {42, 43, 42, 43}, + {43, 42, 43, 42}, + }, + { + {42, 43, 42, 43}, + {43, 43, 43, 43}, + {42, 43, 42, 43}, + {43, 43, 43, 43}, + }, + { + {43, 43, 43, 43}, + {43, 43, 43, 43}, + {43, 43, 43, 43}, + {43, 43, 43, 43}, + }, + { + {43, 43, 43, 43}, + {44, 43, 44, 43}, + {43, 43, 43, 43}, + {44, 43, 44, 43}, + }, + { + {43, 43, 43, 44}, + {44, 43, 44, 43}, + {43, 44, 43, 44}, + {44, 43, 44, 43}, + }, + { + {43, 44, 43, 44}, + {44, 43, 44, 44}, + {43, 44, 43, 44}, + {44, 44, 44, 44}, + }, + { + {43, 44, 44, 44}, + {44, 44, 44, 44}, + {44, 44, 44, 44}, + {44, 44, 44, 44}, + }, + { + {44, 44, 44, 44}, + {44, 44, 45, 44}, + {44, 44, 44, 44}, + {45, 44, 45, 44}, + }, + { + {44, 44, 44, 45}, + {45, 44, 45, 44}, + {44, 45, 44, 45}, + {45, 44, 45, 44}, + }, + { + {44, 45, 44, 45}, + {45, 44, 45, 45}, + {44, 45, 44, 45}, + {45, 45, 45, 45}, + }, + { + {44, 45, 45, 45}, + {45, 45, 45, 45}, + {45, 45, 45, 45}, + {45, 45, 45, 45}, + }, + { + {45, 45, 45, 45}, + {45, 45, 46, 45}, + {45, 45, 45, 45}, + {46, 45, 46, 45}, + }, + { + {45, 45, 45, 46}, + {46, 45, 46, 45}, + {45, 46, 45, 46}, + {46, 45, 46, 45}, + }, + { + {45, 46, 45, 46}, + {46, 45, 46, 46}, + {45, 46, 45, 46}, + {46, 46, 46, 46}, + }, + { + {45, 46, 46, 46}, + {46, 46, 46, 46}, + {46, 46, 46, 46}, + {46, 46, 46, 46}, + }, + { + {46, 46, 46, 46}, + {46, 46, 47, 46}, + {46, 46, 46, 46}, + {47, 46, 47, 46}, + }, + { + {46, 46, 46, 47}, + {47, 46, 47, 46}, + {46, 47, 46, 47}, + {47, 46, 47, 46}, + }, + { + {46, 47, 46, 47}, + {47, 46, 47, 47}, + {46, 47, 46, 47}, + {47, 47, 47, 47}, + }, + { + {46, 47, 47, 47}, + {47, 47, 47, 47}, + {47, 47, 47, 47}, + {47, 47, 47, 47}, + }, + { + {47, 47, 47, 47}, + {47, 47, 48, 47}, + {47, 47, 47, 47}, + {48, 47, 48, 47}, + }, + { + {47, 47, 47, 48}, + {48, 47, 48, 47}, + {47, 48, 47, 48}, + {48, 47, 48, 47}, + }, + { + {47, 48, 47, 48}, + {48, 47, 48, 48}, + {47, 48, 47, 48}, + {48, 48, 48, 48}, + }, + { + {47, 48, 48, 48}, + {48, 48, 48, 48}, + {48, 48, 48, 48}, + {48, 48, 48, 48}, + }, + { + {48, 48, 48, 48}, + {48, 48, 49, 48}, + {48, 48, 48, 48}, + {49, 48, 49, 48}, + }, + { + {48, 48, 48, 49}, + {49, 48, 49, 48}, + {48, 49, 48, 49}, + {49, 48, 49, 48}, + }, + { + {48, 49, 48, 49}, + {49, 48, 49, 49}, + {48, 49, 48, 49}, + {49, 49, 49, 49}, + }, + { + {48, 49, 49, 49}, + {49, 49, 49, 49}, + {49, 49, 49, 49}, + {49, 49, 49, 49}, + }, + { + {49, 49, 49, 49}, + {49, 49, 50, 49}, + {49, 49, 49, 49}, + {50, 49, 50, 49}, + }, + { + {49, 49, 49, 50}, + {50, 49, 50, 49}, + {49, 50, 49, 50}, + {50, 49, 50, 49}, + }, + { + {49, 50, 49, 50}, + {50, 49, 50, 50}, + {49, 50, 49, 50}, + {50, 50, 50, 50}, + }, + { + {49, 50, 50, 50}, + {50, 50, 50, 50}, + {50, 50, 50, 50}, + {50, 50, 50, 50}, + }, + { + {50, 50, 50, 50}, + {50, 50, 51, 50}, + {50, 50, 50, 50}, + {51, 50, 51, 50}, + }, + { + {50, 50, 50, 51}, + {51, 50, 51, 50}, + {50, 51, 50, 51}, + {51, 50, 51, 50}, + }, + { + {50, 51, 50, 51}, + {51, 50, 51, 51}, + {50, 51, 50, 51}, + {51, 51, 51, 51}, + }, + { + {50, 51, 51, 51}, + {51, 51, 51, 51}, + {51, 51, 51, 51}, + {51, 51, 51, 51}, + }, + { + {51, 51, 51, 51}, + {51, 51, 52, 51}, + {51, 51, 51, 51}, + {52, 51, 52, 51}, + }, + { + {51, 51, 51, 52}, + {52, 51, 52, 51}, + {51, 52, 51, 51}, + {52, 51, 52, 51}, + }, + { + {51, 52, 51, 52}, + {52, 51, 52, 52}, + {51, 52, 51, 52}, + {52, 52, 52, 51}, + }, + { + {51, 52, 52, 52}, + {52, 52, 52, 52}, + {52, 52, 51, 52}, + {52, 52, 52, 52}, + }, + { + {52, 52, 52, 52}, + {52, 52, 53, 52}, + {52, 52, 52, 52}, + {53, 52, 52, 52}, + }, + { + {52, 52, 52, 53}, + {53, 52, 53, 52}, + {52, 53, 52, 52}, + {53, 52, 53, 52}, + }, + { + {52, 53, 52, 53}, + {53, 52, 53, 53}, + {52, 53, 52, 53}, + {53, 53, 53, 52}, + }, + { + {52, 53, 53, 53}, + {53, 53, 53, 53}, + {53, 53, 52, 53}, + {53, 53, 53, 53}, + }, + { + {53, 53, 53, 53}, + {53, 53, 54, 53}, + {53, 53, 53, 53}, + {54, 53, 53, 53}, + }, + { + {53, 53, 53, 54}, + {54, 53, 54, 53}, + {53, 54, 53, 53}, + {54, 53, 54, 53}, + }, + { + {53, 54, 53, 54}, + {54, 53, 54, 54}, + {53, 54, 53, 54}, + {54, 54, 54, 53}, + }, + { + {53, 54, 54, 54}, + {54, 54, 54, 54}, + {54, 54, 53, 54}, + {54, 54, 54, 54}, + }, + { + {54, 54, 54, 54}, + {54, 54, 55, 54}, + {54, 54, 54, 54}, + {55, 54, 54, 54}, + }, + { + {54, 54, 54, 55}, + {55, 54, 55, 54}, + {54, 55, 54, 54}, + {55, 54, 55, 54}, + }, + { + {54, 55, 54, 55}, + {55, 54, 55, 55}, + {54, 55, 54, 55}, + {55, 55, 55, 54}, + }, + { + {54, 55, 55, 55}, + {55, 55, 55, 55}, + {55, 55, 54, 55}, + {55, 55, 55, 55}, + }, + { + {55, 55, 55, 55}, + {55, 55, 56, 55}, + {55, 55, 55, 55}, + {56, 55, 55, 55}, + }, + { + {55, 55, 55, 55}, + {56, 55, 56, 55}, + {55, 56, 55, 55}, + {56, 55, 56, 55}, + }, + { + {55, 56, 55, 56}, + {56, 55, 56, 55}, + {55, 56, 55, 56}, + {56, 56, 56, 55}, + }, + { + {55, 56, 55, 56}, + {56, 56, 56, 56}, + {56, 56, 55, 56}, + {56, 56, 56, 56}, + }, + { + {56, 56, 56, 56}, + {56, 56, 56, 56}, + {56, 56, 56, 56}, + {57, 56, 56, 56}, + }, + { + {56, 56, 56, 56}, + {57, 56, 57, 56}, + {56, 57, 56, 56}, + {57, 56, 57, 56}, + }, + { + {56, 57, 56, 57}, + {57, 56, 57, 56}, + {56, 57, 56, 57}, + {57, 57, 57, 56}, + }, + { + {56, 57, 56, 57}, + {57, 57, 57, 57}, + {57, 57, 56, 57}, + {57, 57, 57, 57}, + }, + { + {57, 57, 57, 57}, + {57, 57, 57, 57}, + {57, 57, 57, 57}, + {58, 57, 57, 57}, + }, + { + {57, 57, 57, 57}, + {58, 57, 58, 57}, + {57, 58, 57, 57}, + {58, 57, 58, 57}, + }, + { + {57, 58, 57, 58}, + {58, 57, 58, 57}, + {57, 58, 57, 58}, + {58, 58, 58, 57}, + }, + { + {57, 58, 57, 58}, + {58, 58, 58, 58}, + {58, 58, 57, 58}, + {58, 58, 58, 58}, + }, + { + {58, 58, 58, 58}, + {58, 58, 58, 58}, + {58, 58, 58, 58}, + {59, 58, 58, 58}, + }, + { + {58, 58, 58, 58}, + {59, 58, 59, 58}, + {58, 59, 58, 58}, + {59, 58, 59, 58}, + }, + { + {58, 59, 58, 59}, + {59, 58, 59, 58}, + {58, 59, 58, 59}, + {59, 59, 59, 58}, + }, + { + {58, 59, 58, 59}, + {59, 59, 59, 59}, + {59, 59, 58, 59}, + {59, 59, 59, 59}, + }, + { + {59, 59, 59, 59}, + {59, 59, 59, 59}, + {59, 59, 59, 59}, + {60, 59, 59, 59}, + }, + { + {59, 59, 59, 59}, + {60, 59, 60, 59}, + {59, 59, 59, 59}, + {60, 59, 60, 59}, + }, + { + {59, 60, 59, 60}, + {60, 59, 60, 59}, + {59, 60, 59, 60}, + {60, 59, 60, 59}, + }, + { + {59, 60, 59, 60}, + {60, 60, 60, 60}, + {59, 60, 59, 60}, + {60, 60, 60, 60}, + }, + { + {60, 60, 60, 60}, + {60, 60, 60, 60}, + {60, 60, 60, 60}, + {60, 60, 60, 60}, + }, + { + {60, 60, 60, 60}, + {61, 60, 61, 60}, + {60, 60, 60, 60}, + {61, 60, 61, 60}, + }, + { + {60, 61, 60, 61}, + {61, 60, 61, 60}, + {60, 61, 60, 61}, + {61, 60, 61, 60}, + }, + { + {60, 61, 60, 61}, + {61, 61, 61, 61}, + {60, 61, 60, 61}, + {61, 61, 61, 61}, + }, + { + {61, 61, 61, 61}, + {61, 61, 61, 61}, + {61, 61, 61, 61}, + {61, 61, 61, 61}, + }, + { + {61, 61, 61, 61}, + {62, 61, 62, 61}, + {61, 61, 61, 61}, + {62, 61, 62, 61}, + }, + { + {61, 62, 61, 62}, + {62, 61, 62, 61}, + {61, 62, 61, 62}, + {62, 61, 62, 61}, + }, + { + {61, 62, 61, 62}, + {62, 62, 62, 62}, + {61, 62, 61, 62}, + {62, 62, 62, 62}, + }, + { + {62, 62, 62, 62}, + {62, 62, 62, 62}, + {62, 62, 62, 62}, + {62, 62, 62, 62}, + }, + { + {62, 62, 62, 62}, + {63, 62, 63, 62}, + {62, 62, 62, 62}, + {63, 62, 63, 62}, + }, + { + {62, 63, 62, 63}, + {63, 62, 63, 62}, + {62, 63, 62, 63}, + {63, 62, 63, 62}, + }, + { + {62, 63, 62, 63}, + {63, 63, 63, 63}, + {62, 63, 62, 63}, + {63, 63, 63, 63}, + }, + { + {63, 63, 63, 63}, + {63, 63, 63, 63}, + {63, 63, 63, 63}, + {63, 63, 63, 63}, + }, }; -static const uint8_t dither_rb2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, +static const uint8_t dither_rb2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, }; -static const uint8_t dither_g2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {32, 31}, - }, - { - {31, 32}, - {32, 31}, - }, - { - {31, 32}, - {32, 32}, - }, - { - {32, 32}, - {32, 32}, - }, - { - {32, 32}, - {33, 32}, - }, - { - {32, 33}, - {33, 32}, - }, - { - {32, 33}, - {33, 33}, - }, - { - {33, 33}, - {33, 33}, - }, - { - {33, 33}, - {34, 33}, - }, - { - {33, 34}, - {34, 33}, - }, - { - {33, 34}, - {34, 34}, - }, - { - {34, 34}, - {34, 34}, - }, - { - {34, 34}, - {35, 34}, - }, - { - {34, 35}, - {35, 34}, - }, - { - {34, 35}, - {35, 35}, - }, - { - {35, 35}, - {35, 35}, - }, - { - {35, 35}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 36}, - }, - { - {36, 36}, - {36, 36}, - }, - { - {36, 36}, - {37, 36}, - }, - { - {36, 37}, - {37, 36}, - }, - { - {36, 37}, - {37, 37}, - }, - { - {37, 37}, - {37, 37}, - }, - { - {37, 37}, - {38, 37}, - }, - { - {37, 38}, - {38, 37}, - }, - { - {37, 38}, - {38, 38}, - }, - { - {38, 38}, - {38, 38}, - }, - { - {38, 38}, - {39, 38}, - }, - { - {38, 39}, - {39, 38}, - }, - { - {38, 39}, - {39, 39}, - }, - { - {39, 39}, - {39, 39}, - }, - { - {39, 39}, - {40, 39}, - }, - { - {39, 40}, - {40, 39}, - }, - { - {39, 40}, - {40, 40}, - }, - { - {40, 40}, - {40, 40}, - }, - { - {40, 40}, - {41, 40}, - }, - { - {40, 41}, - {41, 40}, - }, - { - {40, 41}, - {41, 41}, - }, - { - {41, 41}, - {41, 41}, - }, - { - {41, 41}, - {42, 41}, - }, - { - {41, 42}, - {42, 41}, - }, - { - {41, 42}, - {42, 42}, - }, - { - {42, 42}, - {42, 42}, - }, - { - {42, 42}, - {43, 42}, - }, - { - {42, 43}, - {43, 42}, - }, - { - {42, 43}, - {43, 43}, - }, - { - {43, 43}, - {43, 43}, - }, - { - {43, 43}, - {44, 43}, - }, - { - {43, 44}, - {44, 43}, - }, - { - {43, 44}, - {44, 44}, - }, - { - {44, 44}, - {44, 44}, - }, - { - {44, 44}, - {45, 44}, - }, - { - {44, 45}, - {45, 44}, - }, - { - {44, 45}, - {45, 45}, - }, - { - {45, 45}, - {45, 45}, - }, - { - {45, 45}, - {46, 45}, - }, - { - {45, 46}, - {46, 45}, - }, - { - {45, 46}, - {46, 46}, - }, - { - {46, 46}, - {46, 46}, - }, - { - {46, 46}, - {47, 46}, - }, - { - {46, 47}, - {47, 46}, - }, - { - {46, 47}, - {47, 47}, - }, - { - {47, 47}, - {47, 47}, - }, - { - {47, 47}, - {48, 47}, - }, - { - {47, 48}, - {48, 47}, - }, - { - {47, 48}, - {48, 48}, - }, - { - {48, 48}, - {48, 48}, - }, - { - {48, 48}, - {49, 48}, - }, - { - {48, 49}, - {49, 48}, - }, - { - {48, 49}, - {49, 49}, - }, - { - {49, 49}, - {49, 49}, - }, - { - {49, 49}, - {50, 49}, - }, - { - {49, 50}, - {50, 49}, - }, - { - {49, 50}, - {50, 50}, - }, - { - {50, 50}, - {50, 50}, - }, - { - {50, 50}, - {51, 50}, - }, - { - {50, 51}, - {51, 50}, - }, - { - {50, 51}, - {51, 51}, - }, - { - {51, 51}, - {51, 51}, - }, - { - {51, 51}, - {52, 51}, - }, - { - {51, 52}, - {52, 51}, - }, - { - {51, 52}, - {52, 52}, - }, - { - {52, 52}, - {52, 52}, - }, - { - {52, 52}, - {53, 52}, - }, - { - {52, 53}, - {53, 52}, - }, - { - {52, 53}, - {53, 53}, - }, - { - {53, 53}, - {53, 53}, - }, - { - {53, 53}, - {54, 53}, - }, - { - {53, 54}, - {54, 53}, - }, - { - {53, 54}, - {54, 54}, - }, - { - {54, 54}, - {54, 54}, - }, - { - {54, 54}, - {55, 54}, - }, - { - {54, 55}, - {55, 54}, - }, - { - {54, 55}, - {55, 55}, - }, - { - {55, 55}, - {55, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 56}, - {56, 55}, - }, - { - {55, 56}, - {56, 56}, - }, - { - {56, 56}, - {56, 56}, - }, - { - {56, 56}, - {57, 56}, - }, - { - {56, 57}, - {57, 56}, - }, - { - {56, 57}, - {57, 57}, - }, - { - {57, 57}, - {57, 57}, - }, - { - {57, 57}, - {58, 57}, - }, - { - {57, 58}, - {58, 57}, - }, - { - {57, 58}, - {58, 58}, - }, - { - {58, 58}, - {58, 58}, - }, - { - {58, 58}, - {59, 58}, - }, - { - {58, 59}, - {59, 58}, - }, - { - {58, 59}, - {59, 59}, - }, - { - {59, 59}, - {59, 59}, - }, - { - {59, 59}, - {60, 59}, - }, - { - {59, 60}, - {60, 59}, - }, - { - {59, 60}, - {60, 60}, - }, - { - {60, 60}, - {60, 60}, - }, - { - {60, 60}, - {61, 60}, - }, - { - {60, 61}, - {61, 60}, - }, - { - {60, 61}, - {61, 61}, - }, - { - {61, 61}, - {61, 61}, - }, - { - {61, 61}, - {62, 61}, - }, - { - {61, 62}, - {62, 61}, - }, - { - {61, 62}, - {62, 62}, - }, - { - {62, 62}, - {62, 62}, - }, - { - {62, 62}, - {63, 62}, - }, - { - {62, 63}, - {63, 62}, - }, - { - {62, 63}, - {63, 63}, - }, - { - {63, 63}, - {63, 63}, - }, +static const uint8_t dither_g2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, + { + {31, 31}, + {32, 31}, + }, + { + {31, 32}, + {32, 31}, + }, + { + {31, 32}, + {32, 32}, + }, + { + {32, 32}, + {32, 32}, + }, + { + {32, 32}, + {33, 32}, + }, + { + {32, 33}, + {33, 32}, + }, + { + {32, 33}, + {33, 33}, + }, + { + {33, 33}, + {33, 33}, + }, + { + {33, 33}, + {34, 33}, + }, + { + {33, 34}, + {34, 33}, + }, + { + {33, 34}, + {34, 34}, + }, + { + {34, 34}, + {34, 34}, + }, + { + {34, 34}, + {35, 34}, + }, + { + {34, 35}, + {35, 34}, + }, + { + {34, 35}, + {35, 35}, + }, + { + {35, 35}, + {35, 35}, + }, + { + {35, 35}, + {36, 35}, + }, + { + {35, 36}, + {36, 35}, + }, + { + {35, 36}, + {36, 35}, + }, + { + {35, 36}, + {36, 36}, + }, + { + {36, 36}, + {36, 36}, + }, + { + {36, 36}, + {37, 36}, + }, + { + {36, 37}, + {37, 36}, + }, + { + {36, 37}, + {37, 37}, + }, + { + {37, 37}, + {37, 37}, + }, + { + {37, 37}, + {38, 37}, + }, + { + {37, 38}, + {38, 37}, + }, + { + {37, 38}, + {38, 38}, + }, + { + {38, 38}, + {38, 38}, + }, + { + {38, 38}, + {39, 38}, + }, + { + {38, 39}, + {39, 38}, + }, + { + {38, 39}, + {39, 39}, + }, + { + {39, 39}, + {39, 39}, + }, + { + {39, 39}, + {40, 39}, + }, + { + {39, 40}, + {40, 39}, + }, + { + {39, 40}, + {40, 40}, + }, + { + {40, 40}, + {40, 40}, + }, + { + {40, 40}, + {41, 40}, + }, + { + {40, 41}, + {41, 40}, + }, + { + {40, 41}, + {41, 41}, + }, + { + {41, 41}, + {41, 41}, + }, + { + {41, 41}, + {42, 41}, + }, + { + {41, 42}, + {42, 41}, + }, + { + {41, 42}, + {42, 42}, + }, + { + {42, 42}, + {42, 42}, + }, + { + {42, 42}, + {43, 42}, + }, + { + {42, 43}, + {43, 42}, + }, + { + {42, 43}, + {43, 43}, + }, + { + {43, 43}, + {43, 43}, + }, + { + {43, 43}, + {44, 43}, + }, + { + {43, 44}, + {44, 43}, + }, + { + {43, 44}, + {44, 44}, + }, + { + {44, 44}, + {44, 44}, + }, + { + {44, 44}, + {45, 44}, + }, + { + {44, 45}, + {45, 44}, + }, + { + {44, 45}, + {45, 45}, + }, + { + {45, 45}, + {45, 45}, + }, + { + {45, 45}, + {46, 45}, + }, + { + {45, 46}, + {46, 45}, + }, + { + {45, 46}, + {46, 46}, + }, + { + {46, 46}, + {46, 46}, + }, + { + {46, 46}, + {47, 46}, + }, + { + {46, 47}, + {47, 46}, + }, + { + {46, 47}, + {47, 47}, + }, + { + {47, 47}, + {47, 47}, + }, + { + {47, 47}, + {48, 47}, + }, + { + {47, 48}, + {48, 47}, + }, + { + {47, 48}, + {48, 48}, + }, + { + {48, 48}, + {48, 48}, + }, + { + {48, 48}, + {49, 48}, + }, + { + {48, 49}, + {49, 48}, + }, + { + {48, 49}, + {49, 49}, + }, + { + {49, 49}, + {49, 49}, + }, + { + {49, 49}, + {50, 49}, + }, + { + {49, 50}, + {50, 49}, + }, + { + {49, 50}, + {50, 50}, + }, + { + {50, 50}, + {50, 50}, + }, + { + {50, 50}, + {51, 50}, + }, + { + {50, 51}, + {51, 50}, + }, + { + {50, 51}, + {51, 51}, + }, + { + {51, 51}, + {51, 51}, + }, + { + {51, 51}, + {52, 51}, + }, + { + {51, 52}, + {52, 51}, + }, + { + {51, 52}, + {52, 52}, + }, + { + {52, 52}, + {52, 52}, + }, + { + {52, 52}, + {53, 52}, + }, + { + {52, 53}, + {53, 52}, + }, + { + {52, 53}, + {53, 53}, + }, + { + {53, 53}, + {53, 53}, + }, + { + {53, 53}, + {54, 53}, + }, + { + {53, 54}, + {54, 53}, + }, + { + {53, 54}, + {54, 54}, + }, + { + {54, 54}, + {54, 54}, + }, + { + {54, 54}, + {55, 54}, + }, + { + {54, 55}, + {55, 54}, + }, + { + {54, 55}, + {55, 55}, + }, + { + {55, 55}, + {55, 55}, + }, + { + {55, 55}, + {56, 55}, + }, + { + {55, 55}, + {56, 55}, + }, + { + {55, 56}, + {56, 55}, + }, + { + {55, 56}, + {56, 56}, + }, + { + {56, 56}, + {56, 56}, + }, + { + {56, 56}, + {57, 56}, + }, + { + {56, 57}, + {57, 56}, + }, + { + {56, 57}, + {57, 57}, + }, + { + {57, 57}, + {57, 57}, + }, + { + {57, 57}, + {58, 57}, + }, + { + {57, 58}, + {58, 57}, + }, + { + {57, 58}, + {58, 58}, + }, + { + {58, 58}, + {58, 58}, + }, + { + {58, 58}, + {59, 58}, + }, + { + {58, 59}, + {59, 58}, + }, + { + {58, 59}, + {59, 59}, + }, + { + {59, 59}, + {59, 59}, + }, + { + {59, 59}, + {60, 59}, + }, + { + {59, 60}, + {60, 59}, + }, + { + {59, 60}, + {60, 60}, + }, + { + {60, 60}, + {60, 60}, + }, + { + {60, 60}, + {61, 60}, + }, + { + {60, 61}, + {61, 60}, + }, + { + {60, 61}, + {61, 61}, + }, + { + {61, 61}, + {61, 61}, + }, + { + {61, 61}, + {62, 61}, + }, + { + {61, 62}, + {62, 61}, + }, + { + {61, 62}, + {62, 62}, + }, + { + {62, 62}, + {62, 62}, + }, + { + {62, 62}, + {63, 62}, + }, + { + {62, 63}, + {63, 62}, + }, + { + {62, 63}, + {63, 63}, + }, + { + {63, 63}, + {63, 63}, + }, }; /* Dither subtraction */ -static const uint8_t dithersub_rb[256][4][4] = -{ +static const uint8_t dithersub_rb[256][4][4] = { { {0, 0, 0, 0}, {0, 0, 0, 0}, @@ -6696,8 +6691,7 @@ static const uint8_t dithersub_rb[256][4][4] = }, }; -static const uint8_t dithersub_g[256][4][4] = -{ +static const uint8_t dithersub_g[256][4][4] = { { {0, 0, 0, 0}, {0, 0, 0, 0}, @@ -8236,8 +8230,7 @@ static const uint8_t dithersub_g[256][4][4] = }, }; -static const uint8_t dithersub_g2x2[256][2][2] = -{ +static const uint8_t dithersub_g2x2[256][2][2] = { { {0, 0}, {0, 0}, @@ -9264,8 +9257,7 @@ static const uint8_t dithersub_g2x2[256][2][2] = }, }; -static const uint8_t dithersub_rb2x2[256][2][2] = -{ +static const uint8_t dithersub_rb2x2[256][2][2] = { { {0, 0}, {0, 0}, diff --git a/src/include/86box/vid_voodoo_fb.h b/src/include/86box/vid_voodoo_fb.h index 2138e83da7..8a59b30efb 100644 --- a/src/include/86box/vid_voodoo_fb.h +++ b/src/include/86box/vid_voodoo_fb.h @@ -19,9 +19,9 @@ #ifndef VIDEO_VOODOO_FB_H #define VIDEO_VOODOO_FB_H -uint16_t voodoo_fb_readw(uint32_t addr, void *p); -uint32_t voodoo_fb_readl(uint32_t addr, void *p); -void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p); -void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p); +uint16_t voodoo_fb_readw(uint32_t addr, void *priv); +uint32_t voodoo_fb_readl(uint32_t addr, void *priv); +void voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv); +void voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv); #endif /*VIDEO_VOODOO_FB_H*/ diff --git a/src/include/86box/vid_voodoo_fifo.h b/src/include/86box/vid_voodoo_fifo.h index 0073a295c8..e78d0dd6b0 100644 --- a/src/include/86box/vid_voodoo_fifo.h +++ b/src/include/86box/vid_voodoo_fifo.h @@ -21,7 +21,7 @@ void voodoo_wake_fifo_thread(voodoo_t *voodoo); void voodoo_wake_fifo_thread_now(voodoo_t *voodoo); -void voodoo_wake_timer(void *p); +void voodoo_wake_timer(void *priv); void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val); void voodoo_flush(voodoo_t *voodoo); void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo); diff --git a/src/include/86box/vid_voodoo_reg.h b/src/include/86box/vid_voodoo_reg.h index 62738a8c5f..3dff4498c5 100644 --- a/src/include/86box/vid_voodoo_reg.h +++ b/src/include/86box/vid_voodoo_reg.h @@ -19,6 +19,6 @@ #ifndef VIDEO_VOODOO_REG_H #define VIDEO_VOODOO_REG_H -void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p); +void voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv); #endif /*VIDEO_VOODOO_REG_H*/ diff --git a/src/include/86box/vid_voodoo_texture.h b/src/include/86box/vid_voodoo_texture.h index 65eec54e4d..6f325426a0 100644 --- a/src/include/86box/vid_voodoo_texture.h +++ b/src/include/86box/vid_voodoo_texture.h @@ -36,7 +36,7 @@ static const uint32_t texture_offset[LOD_MAX + 3] = { void voodoo_recalc_tex12(voodoo_t *voodoo, int tmu); void voodoo_recalc_tex3(voodoo_t *voodoo, int tmu); void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu); -void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p); +void voodoo_tex_writel(uint32_t addr, uint32_t val, void *priv); void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu); #endif /* VIDEO_VOODOO_TEXTURE_H*/ diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 069718b9fa..e5248b309a 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -14,13 +14,12 @@ * * Copyright 2022 TheCollector1995. */ - #ifndef VIDEO_XGA_H #define VIDEO_XGA_H #include <86box/rom.h> -typedef struct { +typedef struct xga_hwcursor_t { int ena; int x; int y; @@ -36,11 +35,16 @@ typedef struct xga_t { mem_mapping_t linear_mapping; mem_mapping_t video_mapping; rom_t bios_rom; - xga_hwcursor_t hwcursor, hwcursor_latch; + rom_t vga_bios_rom; + xga_hwcursor_t hwcursor; + xga_hwcursor_t hwcursor_latch; PALETTE extpal; - uint8_t test, atest[2], testpixel; - ; + uint8_t test; + uint8_t test2; + uint8_t atest[2]; + uint8_t testpixel; + uint8_t pos_regs[8]; uint8_t disp_addr; uint8_t cfg_reg; @@ -53,31 +57,44 @@ typedef struct xga_t { uint8_t regs_idx; uint8_t hwc_hotspot_x; uint8_t hwc_hotspot_y; - uint8_t disp_cntl_1, disp_cntl_2; - uint8_t clk_sel_1, clk_sel_2; + uint8_t disp_cntl_1; + uint8_t disp_cntl_2; + uint8_t clk_sel_1; + uint8_t clk_sel_2; uint8_t hwc_control; uint8_t bus_arb; - uint8_t select_pos_isa; + uint8_t isa_pos_enable; uint8_t hwcursor_oddeven; uint8_t cfg_reg_instance; uint8_t rowcount; - uint8_t pal_idx, pal_idx_prefetch; + uint8_t pal_idx; + uint8_t pal_idx_prefetch; uint8_t pal_seq; uint8_t pal_mask; - uint8_t pal_r, pal_r_prefetch; - uint8_t pal_g, pal_g_prefetch; - uint8_t pal_b, pal_b_prefetch; + uint8_t pal_r; + uint8_t pal_r_prefetch; + uint8_t pal_g; + uint8_t pal_g_prefetch; + uint8_t pal_b; + uint8_t pal_b_prefetch; uint8_t sprite_data[1024]; uint8_t scrollcache; + uint8_t border_color; uint8_t direct_color; - uint8_t *vram, *changedvram; + uint8_t dma_channel; + uint8_t instance_isa; + uint8_t instance_num; + uint8_t ext_mem_addr; + uint8_t *vram; + uint8_t *changedvram; int16_t hwc_pos_x; int16_t hwc_pos_y; uint16_t pos_idx; uint16_t htotal; - uint16_t sprite_idx, sprite_idx_prefetch; + uint16_t sprite_idx; + uint16_t sprite_idx_prefetch; uint16_t hdisp; uint16_t vtotal; uint16_t vdispend; @@ -85,41 +102,74 @@ typedef struct xga_t { uint16_t vsyncstart; uint16_t linecmp; uint16_t pix_map_width; - uint16_t sprite_pal_addr_idx, old_pal_addr_idx; + uint16_t sprite_pal_addr_idx; + uint16_t old_pal_addr_idx; uint16_t sprite_pal_addr_idx_prefetch; - int v_total, dispend, v_syncstart, split, v_blankstart, - h_disp, h_disp_old, h_total, h_disp_time, rowoffset, - dispon, h_disp_on, vc, sc, linepos, oddeven, firstline, lastline, - firstline_draw, lastline_draw, displine, fullchange, interlace, - char_width, hwcursor_on; - int pal_pos, pal_pos_prefetch; + int v_total; + int dispend; + int v_syncstart; + int split; + int v_blankstart; + int h_disp; + int h_disp_old; + int h_total; + int h_disp_time; + int rowoffset; + int dispon; + int h_disp_on; + int vc; + int sc; + int linepos; + int oddeven; + int firstline; + int lastline; + int firstline_draw; + int lastline_draw; + int displine; + int fullchange; + int interlace; + int char_width; + int hwcursor_on; + int pal_pos; + int pal_pos_prefetch; int on; - int op_mode_reset, linear_endian_reverse; - int sprite_pos, sprite_pos_prefetch, cursor_data_on; - int pal_test, a5_test; - int type, bus; - - uint32_t linear_base, linear_size, banked_mask; + int op_mode_reset; + int linear_endian_reverse; + int sprite_pos; + int sprite_pos_prefetch; + int cursor_data_on; + int pal_test; + int a5_test; + int type; + int bus; + + uint32_t linear_base; + uint32_t linear_size; + uint32_t banked_mask; uint32_t base_addr_1mb; - uint32_t hwc_color0, hwc_color1; + uint32_t hwc_color0; + uint32_t hwc_color1; uint32_t disp_start_addr; uint32_t ma_latch; uint32_t vram_size; uint32_t vram_mask; uint32_t rom_addr; - uint32_t ma, maback; - uint32_t extpallook[256]; - uint32_t read_bank, write_bank; + uint32_t ma; + uint32_t maback; + uint32_t read_bank; + uint32_t write_bank; uint32_t px_map_base; + uint32_t pallook[512]; - uint64_t dispontime, dispofftime; + uint64_t dispontime; + uint64_t dispofftime; - struct - { + struct { uint8_t control; uint8_t px_map_idx; - uint8_t frgd_mix, bkgd_mix; + uint8_t frgd_mix; + uint8_t bkgd_mix; uint8_t cc_cond; uint8_t octant; uint8_t draw_mode; @@ -130,15 +180,19 @@ typedef struct xga_t { uint8_t short_stroke_vector4; int16_t bres_err_term; - int16_t bres_k1, bres_k2; + int16_t bres_k1; + int16_t bres_k2; uint16_t blt_width; uint16_t blt_height; uint16_t mask_map_origin_x_off; uint16_t mask_map_origin_y_off; - uint16_t src_map_x, src_map_y; - uint16_t dst_map_x, dst_map_y; - uint16_t pat_map_x, pat_map_y; + uint16_t src_map_x; + uint16_t src_map_y; + uint16_t dst_map_x; + uint16_t dst_map_y; + uint16_t pat_map_x; + uint16_t pat_map_y; int ssv_state; int pat_src; @@ -146,15 +200,26 @@ typedef struct xga_t { int dst_map; int bkgd_src; int fore_src; - int x, y, sx, sy, dx, dy, px, py; + int oldx; + int oldy; + int x; + int y; + int sx; + int sy; + int dx; + int dy; + int px; + int py; int pattern; int command_len; + int filling; uint32_t short_stroke; uint32_t color_cmp; uint32_t carry_chain; uint32_t plane_mask; - uint32_t frgd_color, bkgd_color; + uint32_t frgd_color; + uint32_t bkgd_color; uint32_t command; uint32_t dir_cmd; @@ -164,6 +229,7 @@ typedef struct xga_t { uint32_t px_map_base[4]; } accel; - volatile int force_busy; + int big_endian_linear; } xga_t; + #endif /*VIDEO_XGA_H*/ diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h index a92c6d3c6e..e337ef9d3a 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -17,6 +17,10 @@ #ifndef VIDEO_XGA_DEVICE_H #define VIDEO_XGA_DEVICE_H + +#ifdef EMU_DEVICE_H extern const device_t xga_device; extern const device_t xga_isa_device; +extern const device_t inmos_isa_device; +#endif #endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index f83bc8f896..ded49fcd80 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -32,6 +32,9 @@ using atomic_int = std::atomic_int; #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) +#define getcolr(color) (((color) >> 16) & 0xFF) +#define getcolg(color) (((color) >> 8) & 0xFF) +#define getcolb(color) ((color) & 0xFF) enum { VID_NONE = 0, @@ -42,7 +45,8 @@ enum { FULLSCR_SCALE_FULL = 0, FULLSCR_SCALE_43, FULLSCR_SCALE_KEEPRATIO, - FULLSCR_SCALE_INT + FULLSCR_SCALE_INT, + FULLSCR_SCALE_INT43 }; #ifdef __cplusplus @@ -60,50 +64,59 @@ enum { #define VIDEO_FLAG_TYPE_CGA 0 #define VIDEO_FLAG_TYPE_MDA 1 #define VIDEO_FLAG_TYPE_SPECIAL 2 -#define VIDEO_FLAG_TYPE_NONE 3 -#define VIDEO_FLAG_TYPE_MASK 3 +#define VIDEO_FLAG_TYPE_8514 3 +#define VIDEO_FLAG_TYPE_XGA 4 +#define VIDEO_FLAG_TYPE_NONE 5 +#define VIDEO_FLAG_TYPE_MASK 7 -typedef struct { +typedef struct video_timings_t { int type; - int write_b, write_w, write_l; - int read_b, read_w, read_l; + int write_b; + int write_w; + int write_l; + int read_b; + int read_w; + int read_l; } video_timings_t; -typedef struct { - int w, h; +typedef struct bitmap_t { + int w; + int h; uint32_t *dat; uint32_t *line[2112]; } bitmap_t; -typedef struct { - uint8_t r, g, b; +typedef struct rgb_t { + uint8_t r; + uint8_t g; + uint8_t b; } rgb_t; -typedef struct { +typedef struct dbcs_font_t { uint8_t chr[32]; } dbcs_font_t; struct blit_data_struct; typedef struct monitor_t { - char name[512]; - int mon_xsize; - int mon_ysize; - int mon_scrnsz_x; - int mon_scrnsz_y; - int mon_efscrnsz_y; - int mon_unscaled_size_x; - int mon_unscaled_size_y; - int mon_res_x; - int mon_res_y; - int mon_bpp; - bitmap_t *target_buffer; - int mon_video_timing_read_b, - mon_video_timing_read_w, - mon_video_timing_read_l; - int mon_video_timing_write_b, - mon_video_timing_write_w, - mon_video_timing_write_l; + char name[512]; + int mon_xsize; + int mon_ysize; + int mon_scrnsz_x; + int mon_scrnsz_y; + int mon_efscrnsz_y; + int mon_unscaled_size_x; + int mon_unscaled_size_y; + double mon_res_x; + double mon_res_y; + int mon_bpp; + bitmap_t *target_buffer; + int mon_video_timing_read_b; + int mon_video_timing_read_w; + int mon_video_timing_read_l; + int mon_video_timing_write_b; + int mon_video_timing_write_w; + int mon_video_timing_write_l; int mon_overscan_x; int mon_overscan_y; int mon_force_resize; @@ -137,10 +150,14 @@ extern int video_fullscreen_scale_maximized; typedef rgb_t PALETTE[256]; -// extern int changeframecount; +#if 0 +extern int changeframecount; +#endif extern volatile int screenshots; -// extern bitmap_t *buffer32; +#if 0 +extern bitmap_t *buffer32; +#endif #define buffer32 (monitors[monitor_index_global].target_buffer) #define pal_lookup (monitors[monitor_index_global].mon_pal_lookup) #define overscan_x (monitors[monitor_index_global].mon_overscan_x) @@ -163,36 +180,42 @@ extern volatile int screenshots; #define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y) #define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x) #define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y) -extern PALETTE cgapal; -extern PALETTE cgapal_mono[6]; -// extern uint32_t pal_lookup[256]; -extern int video_fullscreen; -extern int video_fullscreen_scale; -extern int video_fullscreen_first; +extern PALETTE cgapal; +extern PALETTE cgapal_mono[6]; +#if 0 +extern uint32_t pal_lookup[256]; +#endif +extern int video_fullscreen; +extern int video_fullscreen_scale; +extern int video_fullscreen_first; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; +extern uint8_t fontdat2[2048][8]; +extern uint8_t fontdatm2[2048][16]; extern uint8_t fontdatw[512][32]; extern uint8_t fontdat8x12[256][16]; extern uint8_t fontdat12x18[256][36]; extern dbcs_font_t *fontdatksc5601; extern dbcs_font_t *fontdatksc5601_user; -extern uint32_t *video_6to8, - *video_8togs, - *video_8to32, - *video_15to32, - *video_16to32; -extern int enable_overscan; -extern int force_43; -extern int vid_resize; -extern int herc_blend; -extern int vid_cga_contrast; -extern int video_grayscale; -extern int video_graytype; +extern uint32_t *video_6to8; +extern uint32_t *video_8togs; +extern uint32_t *video_8to32; +extern uint32_t *video_15to32; +extern uint32_t *video_16to32; +extern int enable_overscan; +extern int force_43; +extern int vid_resize; +extern int herc_blend; +extern int vid_cga_contrast; +extern int video_grayscale; +extern int video_graytype; extern double cpuclock; extern int emu_fps; extern int frames; extern int readflash; +extern int ibm8514_active; +extern int xga_active; /* Function handler pointers. */ extern void (*video_recalctimings)(void); @@ -212,15 +235,17 @@ extern int video_card_available(int card); #ifdef EMU_DEVICE_H extern const device_t *video_card_getdevice(int card); #endif -extern int video_card_has_config(int card); -extern char *video_get_internal_name(int card); -extern int video_get_video_from_internal_name(char *s); -extern int video_card_get_flags(int card); -extern int video_is_mda(void); -extern int video_is_cga(void); -extern int video_is_ega_vga(void); -extern void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index); -extern int video_get_type_monitor(int monitor_index); +extern int video_card_has_config(int card); +extern const char *video_get_internal_name(int card); +extern int video_get_video_from_internal_name(char *s); +extern int video_card_get_flags(int card); +extern int video_is_mda(void); +extern int video_is_cga(void); +extern int video_is_ega_vga(void); +extern int video_is_8514(void); +extern int video_is_xga(void); +extern void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index); +extern int video_get_type_monitor(int monitor_index); extern void video_setblit(void (*blit)(int, int, int, int, int)); extern void video_blend(int x, int y); @@ -245,6 +270,8 @@ extern void video_close(void); extern void video_reset_close(void); extern void video_pre_reset(int card); extern void video_reset(int card); +extern void video_post_reset(void); +extern void video_voodoo_init(void); extern uint8_t video_force_resize_get_monitor(int monitor_index); extern void video_force_resize_set_monitor(uint8_t res, int monitor_index); extern void video_update_timing(void); @@ -277,8 +304,14 @@ extern uint32_t video_color_transform(uint32_t color); /* IBM XGA */ extern void xga_device_add(void); -/* IBM 8514/A and generic clones*/ +/* IBM 8514/A and clones*/ extern void ibm8514_device_add(void); +extern const device_t mach8_vga_isa_device; +extern const device_t mach32_isa_device; +extern const device_t mach32_vlb_device; +extern const device_t mach32_mca_device; +extern const device_t mach32_pci_device; +extern const device_t mach32_onboard_pci_device; /* ATi Mach64 */ extern const device_t mach64gx_isa_device; @@ -315,6 +348,7 @@ extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device; extern const device_t gd5426_vlb_device; extern const device_t gd5426_onboard_device; extern const device_t gd5428_isa_device; +extern const device_t gd5428_vlb_onboard_device; extern const device_t gd5428_vlb_device; extern const device_t gd5428_diamond_speedstar_pro_b1_vlb_device; extern const device_t gd5428_boca_isa_device; @@ -325,15 +359,18 @@ extern const device_t gd5429_isa_device; extern const device_t gd5429_vlb_device; extern const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device; extern const device_t gd5430_vlb_device; +extern const device_t gd5430_onboard_vlb_device; extern const device_t gd5430_pci_device; +extern const device_t gd5430_onboard_pci_device; extern const device_t gd5434_isa_device; extern const device_t gd5434_diamond_speedstar_64_a3_isa_device; extern const device_t gd5434_onboard_pci_device; extern const device_t gd5434_vlb_device; extern const device_t gd5434_pci_device; extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; +extern const device_t gd5436_onboard_pci_device; extern const device_t gd5440_pci_device; +extern const device_t gd5440_onboard_pci_device; extern const device_t gd5446_pci_device; extern const device_t gd5446_stb_pci_device; extern const device_t gd5480_pci_device; @@ -399,12 +436,12 @@ extern const device_t ht216_32_standalone_device; extern const device_t im1024_device; extern const device_t pgc_device; -# if defined(DEV_BRANCH) && defined(USE_MGA) /* Matrox MGA */ extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; -# endif +extern const device_t millennium_ii_device; +extern const device_t productiva_g100_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; @@ -423,6 +460,7 @@ extern const device_t paradise_wd90c11_device; extern const device_t paradise_wd90c30_device; /* Realtek (S)VGA */ +extern const device_t realtek_rtg3105_device; extern const device_t realtek_rtg3106_device; /* S3 9XX/8XX/Vision/Trio */ @@ -443,7 +481,9 @@ extern const device_t s3_bahamas64_vlb_device; extern const device_t s3_bahamas64_pci_device; extern const device_t s3_9fx_vlb_device; extern const device_t s3_9fx_pci_device; +extern const device_t s3_phoenix_trio32_onboard_vlb_device; extern const device_t s3_phoenix_trio32_vlb_device; +extern const device_t s3_phoenix_trio32_onboard_pci_device; extern const device_t s3_phoenix_trio32_pci_device; extern const device_t s3_diamond_stealth_se_vlb_device; extern const device_t s3_diamond_stealth_se_pci_device; @@ -451,8 +491,10 @@ extern const device_t s3_spea_mirage_p64_vlb_device; extern const device_t s3_phoenix_trio64_vlb_device; extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_stb_powergraph_64_video_vlb_device; extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; +extern const device_t s3_cardex_trio64vplus_pci_device; extern const device_t s3_mirocrystal_20sv_964_vlb_device; extern const device_t s3_mirocrystal_20sv_964_pci_device; extern const device_t s3_mirocrystal_20sd_864_vlb_device; @@ -499,6 +541,7 @@ extern const device_t tgui9440_vlb_device; extern const device_t tgui9440_pci_device; extern const device_t tgui9440_onboard_pci_device; extern const device_t tgui9660_pci_device; +extern const device_t tgui9660_onboard_pci_device; extern const device_t tgui9680_pci_device; /* IBM PS/1 (S)VGA */ @@ -540,6 +583,10 @@ extern const device_t wy700_device; /* SiS 6202 */ extern const device_t sis_6202_device; +/* Chips & Technologies */ +extern const device_t chips_69000_device; +extern const device_t chips_69000_onboard_device; + #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 99620cbeb4..35f6688ad3 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -103,17 +103,21 @@ extern "C" { #endif extern HINSTANCE hinstance; -extern HWND hwndMain, - hwndRender, - hwndRender2; -extern HANDLE ghMutex; -extern HICON hIcon[256]; -extern int dpi; -extern RECT oldclip; -extern int sbar_height, tbar_height, user_resize; -extern int acp_utf8; - -// extern int status_is_open; +extern HWND hwndMain; +extern HWND hwndRender; +extern HWND hwndRender2; +extern HANDLE ghMutex; +extern HICON hIcon[256]; +extern int dpi; +extern RECT oldclip; +extern int sbar_height; +extern int tbar_height; +extern int user_resize; +extern int acp_utf8; + +#if 0 +extern int status_is_open; +#endif extern char openfilestring[512]; extern WCHAR wopenfilestring[512]; diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index 3981465ce0..a4a4c341f4 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -29,63 +29,93 @@ #define ZIP_250_SECTORS (489532) +#define ZIP_IMAGE_HISTORY 4 + enum { ZIP_BUS_DISABLED = 0, ZIP_BUS_ATAPI = 5, - ZIP_BUS_SCSI, - ZIP_BUS_USB + ZIP_BUS_SCSI = 6, + ZIP_BUS_USB = 7 }; -typedef struct { +typedef struct zip_drive_t { uint8_t id; union { - uint8_t res, res0, /* Reserved for other ID's. */ - res1, - ide_channel, scsi_device_id; + uint8_t res; + uint8_t res0; /* Reserved for other ID's. */ + uint8_t res1; + uint8_t ide_channel; + uint8_t scsi_device_id; }; - uint8_t bus_type, /* 0 = ATAPI, 1 = SCSI */ - bus_mode, /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - read_only, /* Struct variable reserved for - media status. */ - pad, pad0; + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + uint8_t read_only; /* Struct variable reserved for + media status. */ + uint8_t pad; + uint8_t pad0; - FILE *f; + FILE *fp; void *priv; - char image_path[1024], - prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; + + char *image_history[ZIP_IMAGE_HISTORY]; - uint32_t is_250, medium_size, - base; + uint32_t is_250; + uint32_t medium_size; + uint32_t base; } zip_drive_t; -typedef struct { +typedef struct zip_t { mode_sense_pages_t ms_pages_saved; zip_drive_t *drv; +#ifdef EMU_IDE_H + ide_tf_t * tf; +#else + void * tf; +#endif - uint8_t *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; - - uint8_t status, phase, - error, id, - features, cur_lun, - pad0, pad1; - - uint16_t request_length, max_transfer_len; - - int requested_blocks, packet_status, - total_length, do_page_save, - unit_attention, request_pos, - old_len, pad3; + uint8_t *buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; + +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; + uint8_t phase; + uint16_t request_length; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif - uint32_t sector_pos, sector_len, - packet_len, pos; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; + + uint16_t max_transfer_len; + uint16_t pad2; + + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int pad3; + + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; double callback; } zip_t; diff --git a/src/include/tinyglib.h b/src/include/tinyglib.h deleted file mode 100644 index 9edd5986ac..0000000000 --- a/src/include/tinyglib.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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. - * - * Minimal reimplementation of GLib for libslirp. - * - * - * - * Authors: RichardG, - * - * Copyright 2020 RichardG. - */ -#ifndef TINYGLIB_H -#define TINYGLIB_H - -/* Define this to bypass TinyGLib and use full GLib instead. */ -#ifdef TINYGLIB_USE_GLIB -# include -#else - -# include -# include -# include -# include -# define HAVE_STDARG_H -# include <86box/86box.h> - -/* Definitions */ - -# define G_LITTLE_ENDIAN 1234 -# define G_BIG_ENDIAN 4321 -# define G_PDP_ENDIAN 3412 -# ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define G_BYTE_ORDER G_BIG_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ -# define G_BYTE_ORDER G_PDP_ENDIAN -# endif -# endif -# ifndef G_BYTE_ORDER -/* Safe to assume LE for MSVC, as Windows is LE on all architectures. */ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -# endif - -# ifdef _WIN32 -# define G_OS_WIN32 1 -# else -# define G_OS_UNIX 1 -# endif - -# define G_SPAWN_SEARCH_PATH 0 - -# if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_VOID_P 8 -# if defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_LONG 4 -# else -# define GLIB_SIZEOF_LONG 8 -# endif -# define GLIB_SIZEOF_SIZE_T 8 -# define GLIB_SIZEOF_SSIZE_T 8 -# else -# define GLIB_SIZEOF_VOID_P 4 -# define GLIB_SIZEOF_LONG 4 -# define GLIB_SIZEOF_SIZE_T 4 -# define GLIB_SIZEOF_SSIZE_T 4 -# endif - -/* Types */ - -/* Windows does not define ssize_t, so we need to define it here. */ -# ifndef _SSIZE_T_DEFINED -# define _SSIZE_T_DEFINED -# undef ssize_t -# ifdef _WIN64 -# define ssize_t int64_t -# else -# define ssize_t int32_t -# endif -# endif - -# define gboolean int -# define gchar char -# define gint int -# define gint16 int16_t -# define gint32 int32_t -# define gint64 int64_t -# define glong long -# define GPid void * -# define gpointer void * -# define gsize size_t -# define GSpawnFlags void * -# define GSpawnChildSetupFunc void * -# define gssize ssize_t -# define GString char -# define GStrv char ** -# define guint unsigned int -# define guint16 uint16_t -# define guint32 uint32_t -# define guint64 uint64_t - -typedef struct _GDebugKey { - char key[32]; - int val; -} GDebugKey; - -typedef struct _GError { - char message[1]; -} GError; - -typedef struct _GRand { - uint8_t dummy; -} GRand; - -/* Functions */ -extern gboolean g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, - gchar **envp, GSpawnFlags flags, - GSpawnChildSetupFunc child_setup, - gpointer user_data, GPid *child_pid, gint stdin_fd, - gint stdout_fd, gint stderr_fd, GError **error); -extern gboolean g_str_has_prefix (const gchar *str, - const gchar *prefix); -extern GString *g_string_new(gchar *base); -extern gchar *g_string_free(GString *string, gboolean free_segment); -extern gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle); -extern guint g_strv_length(gchar **str_array); - -/* Macros */ -# define tinyglib_pclog(f, s, ...) pclog("TinyGLib " f "(): " s "\n", ##__VA_ARGS__) - -# define GLIB_CHECK_VERSION(a, b, c) 1 -# ifdef __GNUC__ -# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__(__printf__, format_idx, arg_idx))) -# else -# define G_GNUC_PRINTF(format_idx, arg_idx) -# endif -# define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) -# define G_STATIC_ASSERT(e) /* this should probably do something */ -# define G_UNLIKELY(e) (e) - -# define g_assert(e) \ - do { \ - if (!(e)) \ - fatal("TinyGLib g_assert(" #e ")\n"); \ - } while (0) -# ifdef __GNUC__ -# define g_assert_not_reached __builtin_unreachable -# else -# ifdef _MSC_VER -# define g_assert_not_reached() __assume(0) -# else -# define g_assert_not_reached() -# endif -# endif -# define g_critical(s, ...) fatal("TinyGLib g_critical(): " s "\n", ##__VA_ARGS__) -# ifdef TINYGLIB_DEBUG -# define g_debug(s, ...) tinyglib_pclog("g_debug", s, ##__VA_ARGS__) -# else -# define g_debug(s, ...) -# endif -# define g_error(s, ...) tinyglib_pclog("g_error", s, ##__VA_ARGS__) -# define g_error_free(err) -# define g_malloc0(s) calloc(1, s) -# define g_new(t, n) (t *) malloc(sizeof(t) * n) -# define g_new0(t, n) (t *) calloc(n, sizeof(t)) -# ifdef TINYGLIB_DEBUG -# define g_parse_debug_string(s, k, n) ((!!sizeof(k)) * -1) /* unimplemented; always enables all debug flags */ -# else -# define g_parse_debug_string(s, k, n) (!sizeof(k)) -# endif -# define g_rand_int_range(r, min, max) (rand() % (max + 1 - min) + min) -# define g_rand_new() calloc(1, sizeof(GRand)) -# define g_return_val_if_fail(e, v) \ - if (!(e)) \ - return (v) -# define g_shell_parse_argv(a, b, c, d) !!(sizeof(b)) /* unimplemented */ -# define g_strdup(str) ((str) ? strdup(str) : NULL) -# define g_warn_if_fail(e) \ - do { \ - if (!(e)) \ - pclog("TinyGLib g_warn_if_fail(" #e ")\n"); \ - } while (0) -# define g_warn_if_reached() pclog("TinyGLib g_warn_if_reached()\n") -# define g_warning(s, ...) tinyglib_pclog("g_warning", s, ##__VA_ARGS__) - -/* Remapped functions */ -# define g_free free -# define g_getenv getenv -# define g_malloc malloc -# define g_rand_free free -# define g_realloc realloc -# define g_snprintf snprintf -# define g_strerror strerror -# define g_strfreev free -# define g_string_append_printf sprintf /* unimplemented */ -# define g_vsnprintf vsnprintf - -#endif - -#endif diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 96e81ce5f0..4bb6c71d7a 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -22,19 +22,19 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "4.0" +#define EMU_VERSION "4.1.1" #define EMU_VERSION_W LSTR(EMU_VERSION) #define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 4 -#define EMU_VERSION_MIN 0 -#define EMU_VERSION_PATCH 0 +#define EMU_VERSION_MIN 1 +#define EMU_VERSION_PATCH 1 #define EMU_BUILD_NUM 0 #define EMU_VERSION_FULL EMU_VERSION #define EMU_VERSION_FULL_W EMU_VERSION_W -#define COPYRIGHT_YEAR "2022" +#define COPYRIGHT_YEAR "2024" /* Web URL info. */ #define EMU_SITE "86box.net" @@ -42,7 +42,7 @@ #define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" #define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) #ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v4.0/" +# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v4.1/" #else # define EMU_DOCS_URL "https://86box.readthedocs.io" #endif diff --git a/src/ini.c b/src/ini.c index 0921b61ffc..a792d356bb 100644 --- a/src/ini.c +++ b/src/ini.c @@ -42,7 +42,7 @@ typedef struct _list_ { struct _list_ *next; } list_t; -typedef struct { +typedef struct section_t { list_t list; char name[128]; @@ -50,7 +50,7 @@ typedef struct { list_t entry_head; } section_t; -typedef struct { +typedef struct entry_t { list_t list; char name[128]; @@ -266,22 +266,22 @@ ini_close(ini_t ini) static int ini_detect_bom(const char *fn) { - FILE *f; + FILE *fp; unsigned char bom[4] = { 0, 0, 0, 0 }; #if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, "rt"); + fp = plat_fopen(fn, "rt"); #else - f = plat_fopen(fn, "rt, ccs=UTF-8"); + fp = plat_fopen(fn, "rt, ccs=UTF-8"); #endif - if (f == NULL) + if (fp == NULL) return 0; - (void) !fread(bom, 1, 3, f); + (void) !fread(bom, 1, 3, fp); if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) { - fclose(f); + fclose(fp); return 1; } - fclose(f); + fclose(fp); return 0; } @@ -323,16 +323,16 @@ ini_read(const char *fn) int c; int d; int bom; - FILE *f; + FILE *fp; list_t *head; bom = ini_detect_bom(fn); #if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, "rt"); + fp = plat_fopen(fn, "rt"); #else - f = plat_fopen(fn, "rt, ccs=UTF-8"); + fp = plat_fopen(fn, "rt, ccs=UTF-8"); #endif - if (f == NULL) + if (fp == NULL) return NULL; head = malloc(sizeof(list_t)); @@ -343,16 +343,16 @@ ini_read(const char *fn) list_add(&sec->list, head); if (bom) - fseek(f, 3, SEEK_SET); + fseek(fp, 3, SEEK_SET); while (1) { memset(buff, 0x00, sizeof(buff)); #ifdef __HAIKU__ - ini_fgetws(buff, sizeof_w(buff), f); + ini_fgetws(buff, sizeof_w(buff), fp); #else - (void) !fgetws(buff, sizeof_w(buff), f); + (void) !fgetws(buff, sizeof_w(buff), fp); #endif - if (feof(f)) + if (feof(fp)) break; /* Make sure there are no stray newlines or hard-returns in there. */ @@ -436,7 +436,7 @@ ini_read(const char *fn) list_add(&ne->list, &sec->entry_head); } - (void) fclose(f); + (void) fclose(fp); return (ini_t) head; } @@ -448,7 +448,7 @@ ini_write(ini_t ini, const char *fn) wchar_t wtemp[512]; list_t *list = (list_t *) ini; section_t *sec; - FILE *f; + FILE *fp; int fl = 0; if (list == NULL) @@ -457,11 +457,11 @@ ini_write(ini_t ini, const char *fn) sec = (section_t *) list->next; #if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, "wt"); + fp = plat_fopen(fn, "wt"); #else - f = plat_fopen(fn, "wt, ccs=UTF-8"); + fp = plat_fopen(fn, "wt, ccs=UTF-8"); #endif - if (f == NULL) + if (fp == NULL) return; while (sec != NULL) { @@ -470,9 +470,9 @@ ini_write(ini_t ini, const char *fn) if (sec->name[0]) { mbstowcs(wtemp, sec->name, strlen(sec->name) + 1); if (fl) - fwprintf(f, L"\n[%ls]\n", wtemp); + fwprintf(fp, L"\n[%ls]\n", wtemp); else - fwprintf(f, L"[%ls]\n", wtemp); + fwprintf(fp, L"[%ls]\n", wtemp); fl++; } @@ -481,9 +481,9 @@ ini_write(ini_t ini, const char *fn) if (ent->name[0] != '\0') { mbstowcs(wtemp, ent->name, 128); if (ent->wdata[0] == L'\0') - fwprintf(f, L"%ls = \n", wtemp); + fwprintf(fp, L"%ls = \n", wtemp); else - fwprintf(f, L"%ls = %ls\n", wtemp, ent->wdata); + fwprintf(fp, L"%ls = %ls\n", wtemp, ent->wdata); fl++; } @@ -493,7 +493,7 @@ ini_write(ini_t ini, const char *fn) sec = (section_t *) sec->list.next; } - (void) fclose(f); + (void) fclose(fp); } ini_t @@ -544,9 +544,9 @@ ini_section_delete_var(ini_section_t self, const char *name) int ini_section_get_int(ini_section_t self, const char *name, int def) { - section_t *section = (section_t *) self; - entry_t *entry; - int value; + section_t *section = (section_t *) self; + const entry_t *entry; + int value; if (section == NULL) return def; @@ -560,12 +560,52 @@ ini_section_get_int(ini_section_t self, const char *name, int def) return value; } +uint32_t +ini_section_get_uint(ini_section_t self, const char *name, uint32_t def) +{ + section_t *section = (section_t *) self; + const entry_t *entry; + uint32_t value; + + if (section == NULL) + return def; + + entry = find_entry(section, name); + if (entry == NULL) + return def; + + sscanf(entry->data, "%u", &value); + + return value; +} + +#if 0 +float +ini_section_get_float(ini_section_t self, const char *name, float def) +{ + section_t *section = (section_t *) self; + const entry_t *entry; + float value; + + if (section == NULL) + return def; + + entry = find_entry(section, name); + if (entry == NULL) + return def; + + sscanf(entry->data, "%g", &value); + + return value; +} +#endif + double ini_section_get_double(ini_section_t self, const char *name, double def) { - section_t *section = (section_t *) self; - entry_t *entry; - double value; + section_t *section = (section_t *) self; + const entry_t *entry; + double value; if (section == NULL) return def; @@ -582,9 +622,9 @@ ini_section_get_double(ini_section_t self, const char *name, double def) int ini_section_get_hex16(ini_section_t self, const char *name, int def) { - section_t *section = (section_t *) self; - entry_t *entry; - unsigned int value; + section_t *section = (section_t *) self; + const entry_t *entry; + unsigned int value; if (section == NULL) return def; @@ -601,9 +641,9 @@ ini_section_get_hex16(ini_section_t self, const char *name, int def) int ini_section_get_hex20(ini_section_t self, const char *name, int def) { - section_t *section = (section_t *) self; - entry_t *entry; - unsigned int value; + section_t *section = (section_t *) self; + const entry_t *entry; + unsigned int value; if (section == NULL) return def; @@ -620,11 +660,11 @@ ini_section_get_hex20(ini_section_t self, const char *name, int def) int ini_section_get_mac(ini_section_t self, const char *name, int def) { - section_t *section = (section_t *) self; - entry_t *entry; - unsigned int val0 = 0; - unsigned int val1 = 0; - unsigned int val2 = 0; + section_t *section = (section_t *) self; + const entry_t *entry; + unsigned int val0 = 0; + unsigned int val1 = 0; + unsigned int val2 = 0; if (section == NULL) return def; @@ -687,6 +727,42 @@ ini_section_set_int(ini_section_t self, const char *name, int val) mbstowcs(ent->wdata, ent->data, 512); } +void +ini_section_set_uint(ini_section_t self, const char *name, uint32_t val) +{ + section_t *section = (section_t *) self; + entry_t *ent; + + if (section == NULL) + return; + + ent = find_entry(section, name); + if (ent == NULL) + ent = create_entry(section, name); + + sprintf(ent->data, "%i", val); + mbstowcs(ent->wdata, ent->data, 512); +} + +#if 0 +void +ini_section_set_float(ini_section_t self, const char *name, float val) +{ + section_t *section = (section_t *) self; + entry_t *ent; + + if (section == NULL) + return; + + ent = find_entry(section, name); + if (ent == NULL) + ent = create_entry(section, name); + + sprintf(ent->data, "%g", val); + mbstowcs(ent->wdata, ent->data, 512); +} +#endif + void ini_section_set_double(ini_section_t self, const char *name, double val) { diff --git a/src/io.c b/src/io.c index 99b4954f85..0e68049c36 100644 --- a/src/io.c +++ b/src/io.c @@ -29,6 +29,7 @@ #include <86box/timer.h> #include "cpu.h" #include <86box/m_amstrad.h> +#include <86box/pci.h> #define NPORTS 65536 /* PC/AT supports 64K ports */ @@ -47,10 +48,11 @@ typedef struct _io_ { } io_t; typedef struct { - uint8_t enable; - uint16_t base, size; - void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), - *priv; + uint8_t enable; + uint16_t base; + uint16_t size; + void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv); + void *priv; } io_trap_t; int initialized = 0; @@ -284,17 +286,35 @@ inb(uint16_t port) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - p = io[port]; - while (p) { - q = p->next; - if (p->inb) { - ret &= p->inb(port, p->priv); - found |= 1; - qfound++; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + ret = pci_read(port, NULL); + found = 1; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + ret = pci_read(port, NULL); + found = 1; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; + while (p) { + q = p->next; + if (p->inb) { + ret &= p->inb(port, p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; } if (amstrad_latch & 0x80000000) { @@ -310,8 +330,10 @@ inb(uint16_t port) cycles -= io_delay; /* TriGem 486-BIOS MHz output. */ - /* if (port == 0x1ed) - ret = 0xfe; */ +#if 0 + if (port == 0x1ed) + ret = 0xfe; +#endif io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); @@ -324,17 +346,35 @@ outb(uint16_t port, uint8_t val) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - p = io[port]; - while (p) { - q = p->next; - if (p->outb) { - p->outb(port, val, p->priv); - found |= 1; - qfound++; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + pci_write(port, val, NULL); + found = 1; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + pci_write(port, val, NULL); + found = 1; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; + while (p) { + q = p->next; + if (p->outb) { + p->outb(port, val, p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; } if (!found) { @@ -357,35 +397,55 @@ inw(uint16_t port) io_t *q; uint16_t ret = 0xffff; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif uint8_t ret8[2]; - p = io[port]; - while (p) { - q = p->next; - if (p->inw) { - ret &= p->inw(port, p->priv); - found |= 2; - qfound++; - } - p = q; - } - - ret8[0] = ret & 0xff; - ret8[1] = (ret >> 8) & 0xff; - for (uint8_t i = 0; i < 2; i++) { - p = io[(port + i) & 0xffff]; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + ret = pci_readw(port, NULL); + found = 2; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + ret = pci_readw(port, NULL); + found = 2; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; while (p) { q = p->next; - if (p->inb && !p->inw) { - ret8[i] &= p->inb(port + i, p->priv); - found |= 1; + if (p->inw) { + ret &= p->inw(port, p->priv); + found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } + + ret8[0] = ret & 0xff; + ret8[1] = (ret >> 8) & 0xff; + for (uint8_t i = 0; i < 2; i++) { + p = io[(port + i) & 0xffff]; + while (p) { + q = p->next; + if (p->inb && !p->inw) { + ret8[i] &= p->inb(port + i, p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; + } + } + ret = (ret8[1] << 8) | ret8[0]; } - ret = (ret8[1] << 8) | ret8[0]; if (amstrad_latch & 0x80000000) { if (port & 0x80) @@ -410,30 +470,50 @@ outw(uint16_t port, uint16_t val) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - p = io[port]; - while (p) { - q = p->next; - if (p->outw) { - p->outw(port, val, p->priv); - found |= 2; - qfound++; - } - p = q; - } - - for (uint8_t i = 0; i < 2; i++) { - p = io[(port + i) & 0xffff]; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + pci_writew(port, val, NULL); + found = 2; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + pci_writew(port, val, NULL); + found = 2; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; while (p) { q = p->next; - if (p->outb && !p->outw) { - p->outb(port + i, val >> (i << 3), p->priv); - found |= 1; + if (p->outw) { + p->outw(port, val, p->priv); + found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } + + for (uint8_t i = 0; i < 2; i++) { + p = io[(port + i) & 0xffff]; + while (p) { + q = p->next; + if (p->outb && !p->outw) { + p->outb(port + i, val >> (i << 3), p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; + } + } } if (!found) { @@ -458,61 +538,85 @@ inl(uint16_t port) uint16_t ret16[2]; uint8_t ret8[4]; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - p = io[port]; - while (p) { - q = p->next; - if (p->inl) { - ret &= p->inl(port, p->priv); - found |= 4; - qfound++; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + ret = pci_readl(port, NULL); + found = 4; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + ret = pci_readl(port, NULL); + found = 4; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; + while (p) { + q = p->next; + if (p->inl) { + ret &= p->inl(port, p->priv); + found |= 4; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; - } - ret16[0] = ret & 0xffff; - ret16[1] = (ret >> 16) & 0xffff; - p = io[port & 0xffff]; - while (p) { - q = p->next; - if (p->inw && !p->inl) { - ret16[0] &= p->inw(port, p->priv); - found |= 2; - qfound++; + ret16[0] = ret & 0xffff; + ret16[1] = (ret >> 16) & 0xffff; + p = io[port & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[0] &= p->inw(port, p->priv); + found |= 2; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; - } - p = io[(port + 2) & 0xffff]; - while (p) { - q = p->next; - if (p->inw && !p->inl) { - ret16[1] &= p->inw(port + 2, p->priv); - found |= 2; - qfound++; - } - p = q; - } - ret = (ret16[1] << 16) | ret16[0]; - - ret8[0] = ret & 0xff; - ret8[1] = (ret >> 8) & 0xff; - ret8[2] = (ret >> 16) & 0xff; - ret8[3] = (ret >> 24) & 0xff; - for (uint8_t i = 0; i < 4; i++) { - p = io[(port + i) & 0xffff]; + p = io[(port + 2) & 0xffff]; while (p) { q = p->next; - if (p->inb && !p->inw && !p->inl) { - ret8[i] &= p->inb(port + i, p->priv); - found |= 1; + if (p->inw && !p->inl) { + ret16[1] &= p->inw(port + 2, p->priv); + found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } + ret = (ret16[1] << 16) | ret16[0]; + + ret8[0] = ret & 0xff; + ret8[1] = (ret >> 8) & 0xff; + ret8[2] = (ret >> 16) & 0xff; + ret8[3] = (ret >> 24) & 0xff; + for (uint8_t i = 0; i < 4; i++) { + p = io[(port + i) & 0xffff]; + while (p) { + q = p->next; + if (p->inb && !p->inw && !p->inl) { + ret8[i] &= p->inb(port + i, p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; + } + } + ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; } - ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; if (amstrad_latch & 0x80000000) { if (port & 0x80) @@ -537,45 +641,67 @@ outl(uint16_t port, uint32_t val) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif int i = 0; - p = io[port]; - if (p) { - while (p) { - q = p->next; - if (p->outl) { - p->outl(port, val, p->priv); - found |= 4; - qfound++; + if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { + pci_writel(port, val, NULL); + found = 4; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) { + pci_writel(port, val, NULL); + found = 4; +#ifdef ENABLE_IO_LOG + qfound = 1; +#endif + } else { + p = io[port]; + if (p) { + while (p) { + q = p->next; + if (p->outl) { + p->outl(port, val, p->priv); + found |= 4; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; } - } - for (i = 0; i < 4; i += 2) { - p = io[(port + i) & 0xffff]; - while (p) { - q = p->next; - if (p->outw && !p->outl) { - p->outw(port + i, val >> (i << 3), p->priv); - found |= 2; - qfound++; + for (i = 0; i < 4; i += 2) { + p = io[(port + i) & 0xffff]; + while (p) { + q = p->next; + if (p->outw && !p->outl) { + p->outw(port + i, val >> (i << 3), p->priv); + found |= 2; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; } - } - for (i = 0; i < 4; i++) { - p = io[(port + i) & 0xffff]; - while (p) { - q = p->next; - if (p->outb && !p->outw && !p->outl) { - p->outb(port + i, val >> (i << 3), p->priv); - found |= 1; - qfound++; + for (i = 0; i < 4; i++) { + p = io[(port + i) & 0xffff]; + while (p) { + q = p->next; + if (p->outb && !p->outw && !p->outl) { + p->outb(port + i, val >> (i << 3), p->priv); + found |= 1; +#ifdef ENABLE_IO_LOG + qfound++; +#endif + } + p = q; } - p = q; } } diff --git a/src/ioapic.c b/src/ioapic.c index 1fed642205..c3939f2491 100644 --- a/src/ioapic.c +++ b/src/ioapic.c @@ -27,8 +27,9 @@ #include <86box/machine.h> #include <86box/mem.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct ioapic_t { uint8_t dummy; } ioapic_t; @@ -51,7 +52,7 @@ ioapic_log(const char *fmt, ...) #endif static void -ioapic_write(uint16_t port, uint8_t val, void *priv) +ioapic_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { uint32_t pcmp; @@ -83,8 +84,9 @@ ioapic_write(uint16_t port, uint8_t val, void *priv) } static void -ioapic_reset(ioapic_t *dev) +ioapic_reset(UNUSED(ioapic_t *dev)) { + // } static void @@ -99,7 +101,7 @@ ioapic_close(void *priv) } static void * -ioapic_init(const device_t *info) +ioapic_init(UNUSED(const device_t *info)) { ioapic_t *dev = (ioapic_t *) malloc(sizeof(ioapic_t)); memset(dev, 0, sizeof(ioapic_t)); diff --git a/src/log.c b/src/log.c index 02bb6132e0..b5267d70b4 100644 --- a/src/log.c +++ b/src/log.c @@ -35,10 +35,11 @@ #include <86box/log.h> #ifndef RELEASE_BUILD -typedef struct -{ - char buff[1024], *dev_name; - int seen, suppr_seen; +typedef struct log_t { + char buff[1024]; + char *dev_name; + int seen; + int suppr_seen; } log_t; extern FILE *stdlog; /* file to log output to */ diff --git a/src/lpt.c b/src/lpt.c index f4d2ad67c1..419e5ad3d5 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -11,7 +11,10 @@ #include <86box/pic.h> #include <86box/sound.h> #include <86box/prt_devs.h> -#include <86box/net_plip.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/network.h> lpt_port_t lpt_ports[PARALLEL_MAX]; @@ -45,22 +48,22 @@ static const struct { // clang-format on }; -char * +const char * lpt_device_get_name(int id) { - if (strlen((char *) lpt_devices[id].internal_name) == 0) + if (strlen(lpt_devices[id].internal_name) == 0) return NULL; if (!lpt_devices[id].device) return "None"; - return (char *) lpt_devices[id].device->name; + return lpt_devices[id].device->name; } -char * +const char * lpt_device_get_internal_name(int id) { - if (strlen((char *) lpt_devices[id].internal_name) == 0) + if (strlen(lpt_devices[id].internal_name) == 0) return NULL; - return (char *) lpt_devices[id].internal_name; + return lpt_devices[id].internal_name; } int @@ -68,7 +71,7 @@ lpt_device_get_from_internal_name(char *s) { int c = 0; - while (strlen((char *) lpt_devices[c].internal_name) != 0) { + while (strlen(lpt_devices[c].internal_name) != 0) { if (strcmp(lpt_devices[c].internal_name, s) == 0) return c; c++; @@ -124,6 +127,9 @@ lpt_write(uint16_t port, uint8_t val, void *priv) dev->ctrl = val; dev->enable_irq = val & 0x10; break; + + default: + break; } } @@ -154,15 +160,41 @@ lpt_read(uint16_t port, void *priv) else ret = 0xe0 | dev->ctrl | dev->enable_irq; break; + + default: + break; } return ret; } +uint8_t +lpt_read_port(int port, uint16_t reg) +{ + lpt_port_t *dev = &(lpt_ports[port]); + uint8_t ret = lpt_read(reg, dev); + + return ret; +} + +uint8_t +lpt_read_status(int port) +{ + lpt_port_t *dev = &(lpt_ports[port]); + uint8_t ret = 0xff; + + if (dev->dt && dev->dt->read_status && dev->priv) + ret = dev->dt->read_status(dev->priv) | 0x07; + else + ret = 0xdf; + + return ret; +} + void lpt_irq(void *priv, int raise) { - lpt_port_t *dev = (lpt_port_t *) priv; + const lpt_port_t *dev = (lpt_port_t *) priv; if (dev->enable_irq && (dev->irq != 0xff)) { if (raise) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 17caf61413..dfeb1fa0f2 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -74,6 +74,7 @@ #include <86box/vid_mda.h> #include <86box/machine.h> #include <86box/m_amstrad.h> +#include <86box/plat_unused.h> #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 @@ -84,60 +85,64 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -typedef struct { - rom_t bios_rom; /* 1640 */ - cga_t cga; /* 1640/200 */ - mda_t mda; /* 1512/200/PPC512/640*/ - ega_t ega; /* 1640 */ - uint8_t emulation; /* Which display are we emulating? */ - uint8_t dipswitches; /* DIP switches 1-3 */ - uint8_t crtc_index; /* CRTC index readback - * Bit 7: CGA control port written - * Bit 6: Operation control port written - * Bit 5: CRTC register written - * Bits 0-4: Last CRTC register selected */ - uint8_t operation_ctrl; - uint8_t reg_3df, type; - uint8_t crtc[32]; - int crtcreg; - int cga_enabled; /* 1640 */ - uint8_t cgacol, - cgamode, - stat; - uint8_t plane_write, /* 1512/200 */ - plane_read, /* 1512/200 */ - border, /* 1512/200 */ - invert; /* 512/640 */ - int fontbase; /* 1512/200 */ - int linepos, - displine; - int sc, vc; - int cgadispon; - int con, coff, - cursoron, - cgablink; - int vsynctime; - int fullchange; - int vadj; - uint16_t ma, maback; - int dispon; - int blink; - uint64_t dispontime, /* 1512/1640 */ - dispofftime; /* 1512/1640 */ - pc_timer_t timer; /* 1512/1640 */ - int firstline, - lastline; - uint8_t *vram; - void *ams; +typedef struct amsvid_t { + rom_t bios_rom; /* 1640 */ + cga_t cga; /* 1640/200 */ + mda_t mda; /* 1512/200/PPC512/640*/ + ega_t ega; /* 1640 */ + uint8_t emulation; /* Which display are we emulating? */ + uint8_t dipswitches; /* DIP switches 1-3 */ + uint8_t crtc_index; /* CRTC index readback + * Bit 7: CGA control port written + * Bit 6: Operation control port written + * Bit 5: CRTC register written + * Bits 0-4: Last CRTC register selected */ + uint8_t operation_ctrl; + uint8_t reg_3df; + uint8_t type; + uint8_t crtc[32]; + int crtcreg; + int cga_enabled; /* 1640 */ + uint8_t cgacol; + uint8_t cgamode; + uint8_t stat; + uint8_t plane_write; /* 1512/200 */ + uint8_t plane_read; /* 1512/200 */ + uint8_t border; /* 1512/200 */ + uint8_t invert; /* 512/640 */ + int fontbase; /* 1512/200 */ + int linepos; + int displine; + int sc; + int vc; + int cgadispon; + int con; + int coff; + int cursoron; + int cgablink; + int vsynctime; + int fullchange; + int vadj; + uint16_t ma; + uint16_t maback; + int dispon; + int blink; + uint64_t dispontime; /* 1512/1640 */ + uint64_t dispofftime; /* 1512/1640 */ + pc_timer_t timer; /* 1512/1640 */ + int firstline; + int lastline; + uint8_t *vram; + void *ams; } amsvid_t; -typedef struct { +typedef struct amstrad_t { /* Machine stuff. */ uint8_t dead; - uint8_t stat1, - stat2; - uint8_t type, - language; + uint8_t stat1; + uint8_t stat2; + uint8_t type; + uint8_t language; /* Keyboard stuff. */ int8_t wantirq; @@ -147,8 +152,6 @@ typedef struct { pc_timer_t send_delay_timer; /* Mouse stuff. */ - uint8_t mousex, - mousey; int oldb; /* Video stuff. */ @@ -160,7 +163,7 @@ uint32_t amstrad_latch; static uint8_t key_queue[16]; static int key_queue_start = 0; -static int key_queue_end = 0; +static int key_queue_end = 0; static uint8_t crtc_mask[32] = { 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, @@ -263,14 +266,17 @@ vid_out_1512(uint16_t addr, uint8_t val, void *priv) case 0x03df: vid->border = val; return; + + default: + return; } } static uint8_t vid_in_1512(uint16_t addr, void *priv) { - amsvid_t *vid = (amsvid_t *) priv; - uint8_t ret = 0xff; + const amsvid_t *vid = (amsvid_t *) priv; + uint8_t ret = 0xff; if ((addr >= 0x3d0) && (addr <= 0x3d7)) addr = (addr & 0xff9) | 0x004; @@ -287,6 +293,9 @@ vid_in_1512(uint16_t addr, void *priv) case 0x03da: ret = vid->stat; break; + + default: + break; } return ret; @@ -316,7 +325,7 @@ vid_write_1512(uint32_t addr, uint8_t val, void *priv) static uint8_t vid_read_1512(uint32_t addr, void *priv) { - amsvid_t *vid = (amsvid_t *) priv; + const amsvid_t *vid = (amsvid_t *) priv; cycles -= 12; addr &= 0x3fff; @@ -780,9 +789,15 @@ vid_out_1640(uint16_t addr, uint8_t val, void *priv) mem_mapping_set_addr(&vid->ega.mapping, 0xb8000, 0x08000); break; + + default: + break; } } return; + + default: + break; } if (vid->cga_enabled) @@ -924,6 +939,9 @@ ams_inform(amsvid_t *vid) case PC200_LCDM: video_inform(VIDEO_FLAG_TYPE_MDA, &timing_pc200); break; + + default: + break; } } @@ -990,7 +1008,7 @@ static unsigned char mapping2[256] = { static void set_lcd_cols(uint8_t mode_reg) { - unsigned char *mapping = (mode_reg & 0x80) ? mapping2 : mapping1; + const unsigned char *mapping = (mode_reg & 0x80) ? mapping2 : mapping1; for (uint16_t c = 0; c < 256; c++) { switch (mapping[c]) { @@ -1013,6 +1031,9 @@ set_lcd_cols(uint8_t mode_reg) lcdcols[c][0][0] = lcdcols[c][1][0] = blue; lcdcols[c][0][1] = lcdcols[c][1][1] = blue; break; + + default: + break; } } } @@ -1043,6 +1064,9 @@ vid_in_200(uint16_t addr, void *priv) case 0x03df: return (vid->reg_3df); + + default: + break; } if (addr >= 0x3D0 && addr <= 0x3DF) @@ -1176,6 +1200,9 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) mem_mapping_enable(&vid->cga.mapping); } return; + + default: + break; } if (addr >= 0x3D0 && addr <= 0x3DF) @@ -1272,7 +1299,7 @@ lcdm_poll(amsvid_t *vid) drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(vid, &((uint32_t *) (buffer32->line[mda->displine]))[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl); + lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl); mda->ma++; } } @@ -1422,7 +1449,7 @@ lcdc_poll(amsvid_t *vid) dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; cga->ma++; for (uint8_t c = 0; c < 16; c++) { - buffer32->line[(cga->displine << 1)][(x << 4) + c] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c] = (dat & 0x8000) ? blue : green; + buffer32->line[cga->displine << 1][(x << 4) + c] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c] = (dat & 0x8000) ? blue : green; dat <<= 1; } } @@ -1568,9 +1595,9 @@ lcdc_poll(amsvid_t *vid) } static void -vid_poll_200(void *p) +vid_poll_200(void *priv) { - amsvid_t *vid = (amsvid_t *) p; + amsvid_t *vid = (amsvid_t *) priv; switch (vid->emulation) { case PC200_LCDM: @@ -1579,6 +1606,9 @@ vid_poll_200(void *p) case PC200_LCDC: lcdc_poll(vid); return; + + default: + break; } } @@ -1614,6 +1644,9 @@ vid_init_200(amstrad_t *ams) break; /* The other combination is 'IDA disabled' (0x20) - see * m_amstrad.c */ + + default: + break; } else switch (vid->emulation) { @@ -1635,6 +1668,9 @@ vid_init_200(amstrad_t *ams) case PC200_LCDM: vid->dipswitches = 0x10; break; + + default: + break; } cga = &vid->cga; @@ -1654,6 +1690,7 @@ vid_init_200(amstrad_t *ams) mda_setcol(0xC0, 0, 1, 0); cga->fontbase = (device_get_config_int("codepage") & 3) * 256; + mda->fontbase = cga->fontbase; timer_add(&vid->timer, vid_poll_200, vid, 1); mem_mapping_add(&vid->mda.mapping, 0xb0000, 0x08000, @@ -1969,40 +2006,38 @@ const device_t vid_pc3086_device = { }; static void -ms_write(uint16_t addr, uint8_t val, void *priv) +ms_write(uint16_t addr, UNUSED(uint8_t val), UNUSED(void *priv)) { - amstrad_t *ams = (amstrad_t *) priv; - if ((addr == 0x78) || (addr == 0x79)) - ams->mousex = 0; + mouse_clear_x(); else - ams->mousey = 0; + mouse_clear_y(); } static uint8_t -ms_read(uint16_t addr, void *priv) +ms_read(uint16_t addr, UNUSED(void *priv)) { - amstrad_t *ams = (amstrad_t *) priv; - uint8_t ret; + uint8_t ret; + int delta = 0; if ((addr == 0x78) || (addr == 0x79)) { - ret = ams->mousex; - ams->mousex = 0; + mouse_subtract_x(&delta, NULL, -128, 127, 0); + mouse_clear_x(); } else { - ret = ams->mousey; - ams->mousey = 0; + mouse_subtract_y(&delta, NULL, -128, 127, 1, 0); + mouse_clear_y(); } + ret = (uint8_t) (int8_t) delta; + return ret; } static int -ms_poll(int x, int y, int z, int b, void *priv) +ms_poll(void *priv) { amstrad_t *ams = (amstrad_t *) priv; - - ams->mousex += x; - ams->mousey -= y; + int b = mouse_get_buttons_ex(); if ((b & 1) && !(ams->oldb & 1)) keyboard_send(0x7e); @@ -2089,7 +2124,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x66: softresetx86(); - cpu_set_edx(); break; default: @@ -2222,6 +2256,9 @@ ams_write(uint16_t port, uint8_t val, void *priv) case 0xdead: ams->dead = val; break; + + default: + break; } } @@ -2285,6 +2322,9 @@ ams_read(uint16_t port, void *priv) case AMSTRAD_SW10: ret |= 0x20; break; + + default: + break; } break; @@ -2300,6 +2340,9 @@ ams_read(uint16_t port, void *priv) case 0xdead: ret = ams->dead; break; + + default: + break; } return ret; @@ -2482,6 +2525,9 @@ machine_amstrad_init(const machine_t *model, int type) case AMS_PC3086: ams->fdc = device_add(&fdc_at_actlow_device); break; + + default: + break; } ams->language = 7; @@ -2539,6 +2585,9 @@ machine_amstrad_init(const machine_t *model, int type) device_context_restore(); device_add(¶dise_pvga1a_pc3086_device); break; + + default: + break; } else if ((type == AMS_PC200) || (type == AMS_PPC512)) io_sethandler(0x03de, 1, @@ -2549,10 +2598,10 @@ machine_amstrad_init(const machine_t *model, int type) io_sethandler(0x0060, 7, kbd_read, NULL, NULL, kbd_write, NULL, NULL, ams); timer_add(&ams->send_delay_timer, kbd_poll, ams, 1); - if (type == AMS_PC200) - keyboard_set_table(scancode_pc200); - else + if (type == AMS_PC1512) keyboard_set_table(scancode_xt); + else + keyboard_set_table(scancode_pc200); keyboard_send = kbd_adddata_ex; keyboard_scan = 1; keyboard_set_is_amstrad(((type == AMS_PC1512) || (type == AMS_PC1640)) ? 0 : 1); diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 92f8c0f5fa..9fc53ebcd0 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -246,7 +246,14 @@ machine_at_siemens_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_ibm_common_init(model); + machine_at_common_init_ex(model, 1); + + device_add(&keyboard_at_siemens_device); + + mem_remap_top(384); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); return ret; } diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 54e7d6b9e9..a688181b44 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -10,11 +10,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * EngiNerd * - * Copyright 2010-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. * Copyright 2020 EngiNerd. */ @@ -306,6 +304,8 @@ machine_at_award286_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -350,6 +350,29 @@ machine_at_gw286ct_init(const machine_t *model) return ret; } +int +machine_at_super286c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/super286c/hyundai_award286.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&neat_device); + + return ret; +} + int machine_at_super286tr_init(const machine_t *model) { @@ -385,6 +408,8 @@ machine_at_spc4200p_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -428,6 +453,8 @@ machine_at_spc4620p_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + device_add(&ide_isa_device); + return ret; } @@ -462,6 +489,8 @@ machine_at_deskmaster286_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); + + device_add(&ide_isa_device); return ret; } @@ -525,7 +554,7 @@ machine_at_wd76c10_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); if (gfxcard[0] == VID_INTERNAL) device_add(¶dise_wd90c11_megapc_device); @@ -690,7 +719,7 @@ machine_at_sbc350a_init(const machine_t *model) device_add(&ali1217_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_at_device); + device_add(&keyboard_ps2_ami_device); return ret; } @@ -714,7 +743,27 @@ machine_at_flytech386_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&tvga8900d_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_at_ami_device); + + return ret; +} + +int +machine_at_325ax_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/325ax/M27C512.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -730,11 +779,11 @@ machine_at_mr1217_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&ali1217_device); device_add(&fdc_at_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -807,10 +856,6 @@ machine_at_pc8_init(const machine_t *model) return ret; } -/* - * Current bugs: - * - ctrl-alt-del produces an 8042 error - */ int machine_at_3302_init(const machine_t *model) { @@ -820,8 +865,8 @@ machine_at_3302_init(const machine_t *model) 0x000f0000, 65536, 0); if (ret) { - bios_load_aux_linear("roms/machines/3302/f800-setup_ncr3.5-013190.bin", - 0x000f8000, 32768, 0); + ret &= bios_load_aux_linear("roms/machines/3302/f800-setup_ncr3.5-013190.bin", + 0x000f8000, 32768, 0); } if (bios_only || !ret) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index deaa540c4b..1dd63ce32a 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -10,10 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2010-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ #include @@ -48,6 +46,7 @@ #include <86box/scsi_ncr53c8xx.h> #include <86box/hwm.h> #include <86box/machine.h> +#include <86box/plat_unused.h> int machine_at_acc386_init(const machine_t *model) @@ -94,7 +93,7 @@ machine_at_asus386_init(const machine_t *model) static void machine_at_sis401_common_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&sis_85c401_device); device_add(&keyboard_at_ami_device); @@ -145,7 +144,7 @@ machine_at_av4_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&sis_85c460_device); device_add(&keyboard_at_ami_device); @@ -225,6 +224,27 @@ machine_at_spc6000a_init(const machine_t *model) return ret; } +int +machine_at_ecs386v_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ecs386v/PANDA_386V.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ali1429_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_rycleopardlx_init(const machine_t *model) { @@ -382,10 +402,9 @@ machine_at_acera1g_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_isa_2ch_device); - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&ali5105_device); + device_add(&ide_ali5213_device); return ret; } @@ -405,7 +424,7 @@ machine_at_acerv10_init(const machine_t *model) device_add(&sis_85c461_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_isa_2ch_device); + device_add(&ide_isa_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); @@ -442,7 +461,7 @@ machine_at_decpclpv_init(const machine_t *model) static void machine_at_ali1429_common_init(const machine_t *model, int is_green) { - machine_at_common_ide_init(model); + machine_at_common_init(model); if (is_green) device_add(&ali1429g_device); @@ -498,7 +517,7 @@ machine_at_opti495_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&opti495_device); @@ -513,7 +532,7 @@ machine_at_opti495_init(const machine_t *model) static void machine_at_opti495_ami_common_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_init(model); device_add(&opti495_device); @@ -555,6 +574,27 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } +int +machine_at_exp4349_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/exp4349/biosdump.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1429g_device); + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + return ret; +} + static void machine_at_403tg_common_init(const machine_t *model, int nvr_hack) { @@ -621,11 +661,11 @@ machine_at_403tg_d_mr_init(const machine_t *model) } int -machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse */ +machine_at_pb450_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", + ret = bios_load_linear("roms/machines/pb450/OPTI802.BIN", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -635,14 +675,56 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 5, 4, 3, 2); + pci_register_slot(0x12, PCI_CARD_NORMAL, 9, 8, 7, 6); - device_add(&opti802g_pci_device); + device_add(&opti895_device); device_add(&opti822_device); - device_add(&keyboard_ps2_device); - device_add(&fdc37c665_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c661_ide_device); + device_add(&ide_opti611_vlb_sec_device); + device_add(&ide_vlb_2ch_device); + device_add(&intel_flash_bxt_device); + device_add(&phoenix_486_jumper_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5428_vlb_onboard_device); + + return ret; +} + +int +machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse */ +{ + int ret; + + ret = bios_load_linear("roms/machines/pc330_6573/$IMAGES.USF", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ide_vlb_2ch_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 5, 6, 7, 8); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 9, 10, 11, 12); + /* This is a guess because the BIOS always gives it a video BIOS + and never gives it an IRQ, so it is impossible to known for + certain until we obtain PCI readouts from the real machine. */ + pci_register_slot(0x0E, PCI_CARD_VIDEO, 13, 14, 15, 16); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_onboard_vlb_device); + + device_add(&opti602_device); + device_add(&opti802g_device); + device_add(&opti822_device); + device_add(&keyboard_ps2_ami_device); + device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); @@ -692,7 +774,6 @@ machine_at_ami471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; @@ -710,8 +791,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_2ch_device); - device_add(&keyboard_ps2_ami_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -728,7 +808,6 @@ machine_at_dtk486_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_device); return ret; @@ -764,12 +843,44 @@ machine_at_win471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; } +int +machine_at_pci400ca_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pci400ca/486-AA008851.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SCSI, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_device); + device_add(&sio_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420tx_device); + device_add(&ncr53c810_onboard_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_vi15g_init(const machine_t *model) { @@ -782,7 +893,6 @@ machine_at_vi15g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&ide_vlb_device); device_add(&keyboard_at_ami_device); return ret; @@ -811,8 +921,31 @@ machine_at_greenb_init(const machine_t *model) return ret; } +int +machine_at_4gpv5_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/4gpv5/4GPV5.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&contaq_82c596a_device); + + device_add(&keyboard_at_device); + + return ret; +} + static void -machine_at_sis_85c496_common_init(const machine_t *model) +machine_at_sis_85c496_common_init(UNUSED(const machine_t *model)) { device_add(&ide_pci_2ch_device); @@ -931,6 +1064,33 @@ machine_at_4dps_init(const machine_t *model) return ret; } +int +machine_at_ms4144_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms4144/ms-4144-1.4.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + machine_at_sis_85c496_common_init(model); + device_add(&sis_85c496_ls486e_device); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&w83787f_device); + device_add(&keyboard_at_ami_device); + + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_486sp3c_init(const machine_t *model) { @@ -998,7 +1158,7 @@ machine_at_alfredo_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1030,7 +1190,7 @@ machine_at_ninja_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); @@ -1044,6 +1204,86 @@ machine_at_ninja_init(const machine_t *model) return ret; } +int +machine_at_bat4ip3e_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/bat4ip3e/404C.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0xfe, 0xff, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 2, 1); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 1, 2, 1, 2); + + device_add(&phoenix_486_jumper_pci_device); + device_add(&keyboard_ps2_pci_device); + device_add(&i420ex_device); + device_add(&ide_cmd640_pci_device); + device_add(&fdc37c665_device); + + return ret; +} + +int +machine_at_486pi_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/486pi/486pi.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&i420ex_device); + + return ret; +} + +int +machine_at_sb486p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sb486p/amiboot.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i82091aa_device); + device_add(&i420ex_device); + + return ret; +} + int machine_at_486sp3_init(const machine_t *model) { @@ -1077,6 +1317,36 @@ machine_at_486sp3_init(const machine_t *model) return ret; } +int +machine_at_amis76_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/s76p/s76p.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + // pci_register_slot(0x01, PCI_CARD_IDE, 1, 2, 3 ,4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sio_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420tx_device); + // device_add(&ide_cmd640_pci_device); /* is this actually cmd640? is it single channel? */ + device_add(&ide_pci_device); + + return ret; +} + int machine_at_pci400cb_init(const machine_t *model) { @@ -1090,7 +1360,6 @@ machine_at_pci400cb_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1994_nvr_device); - device_add(&ide_isa_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1122,7 +1391,6 @@ machine_at_g486ip_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&ami_1992_nvr_device); - device_add(&ide_isa_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1184,7 +1452,7 @@ machine_at_486ap4_init(const machine_t *model) machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_1); /* Excluded: 5, 6, 7, 8 */ pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 09 = Slot 1 */ @@ -1281,7 +1549,9 @@ machine_at_abpb4_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83787f_device); device_add(&keyboard_at_device); - // device_add(&intel_flash_bxt_device); +#if 0 + device_add(&intel_flash_bxt_device); +#endif device_add(&sst_flash_29ee010_device); return ret; @@ -1393,6 +1663,29 @@ machine_at_tf486_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83977ef_device); + device_add(&keyboard_at_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_arb1476_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/arb1476/w1476b.v21", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + + device_add(&ali1489_device); + device_add(&fdc37c669_device); device_add(&keyboard_ps2_device); device_add(&sst_flash_29ee010_device); @@ -1482,6 +1775,30 @@ machine_at_arb1479_init(const machine_t *model) return ret; } +int +machine_at_iach488_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/iach488/FH48800B.980", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&w83977f_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&stpc_consumer2_device); + device_add(&sst_flash_29ee020_device); + + return ret; +} + int machine_at_pcm9340_init(const machine_t *model) { @@ -1524,11 +1841,11 @@ machine_at_pcm5330_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE_IDE, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&stpc_serial_device); device_add(&w83977f_370_device); device_add(&keyboard_ps2_ami_pci_device); @@ -1564,13 +1881,13 @@ machine_at_ecs486_init(const machine_t *model) device_add(&ide_cmd640_pci_legacy_only_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_at_ami_device); + device_add(&keyboard_ps2_ami_device); return ret; } int -machine_at_hot433_init(const machine_t *model) +machine_at_hot433a_init(const machine_t *model) { int ret; @@ -1591,7 +1908,7 @@ machine_at_hot433_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&um8669f_device); device_add(&winbond_flash_w29c010_device); device_add(&keyboard_at_ami_device); @@ -1620,7 +1937,7 @@ machine_at_atc1415_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&umc_8886bf_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_at_ami_device); @@ -1644,19 +1961,53 @@ machine_at_actionpc2600_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 3); pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_VIDEO, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&umc_8886bf_device); + device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); device_add(&keyboard_ps2_tg_ami_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&tgui9440_onboard_pci_device); + + return ret; +} + +int +machine_at_actiontower8400_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/actiontower8400/V31C.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x15, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x16, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&umc_hb4_device); + device_add(&umc_8886f_device); + device_add(&fdc37c665_device); + device_add(&ide_cmd640_pci_device); + device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. + device_add(&keyboard_ps2_ami_pci_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_onboard_pci_device); + return ret; } @@ -1681,8 +2032,8 @@ machine_at_m919_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&umc_hb4_device); - device_add(&umc_8886af_device); - device_add(&um8669f_device); + device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */ + device_add(&um8663bf_device); device_add(&sst_flash_29ee010_device); device_add(&keyboard_at_ami_device); @@ -1713,7 +2064,7 @@ machine_at_spc7700plw_init(const machine_t *model) device_add(&umc_8886af_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_at_ami_device); + device_add(&keyboard_ps2_ami_device); return ret; } @@ -1735,7 +2086,7 @@ machine_at_ms4134_init(const machine_t *model) device_add(&fdc37c665_ide_pri_device); - pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); + pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0B, PCI_CARD_SCSI, 4, 1, 2, 3); @@ -1769,7 +2120,7 @@ machine_at_tg486gp_init(const machine_t *model) device_add(&fdc37c665_ide_pri_device); - pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); + pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1788,7 +2139,7 @@ machine_at_tg486gp_init(const machine_t *model) int machine_at_tg486g_init(const machine_t *model) { - int ret, i; + int ret; ret = bios_load_linear("roms/machines/tg486g/tg486g.bin", 0x000c0000, 262144, 0); @@ -1803,7 +2154,7 @@ machine_at_tg486g_init(const machine_t *model) device_add(&keyboard_ps2_tg_ami_pci_device); if (gfxcard[0] != VID_INTERNAL) { - for (i = 0; i < 32768; i++) + for (uint16_t i = 0; i < 32768; i++) rom[i] = mem_readb_phys(0x000c0000 + i); } mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); @@ -1811,3 +2162,92 @@ machine_at_tg486g_init(const machine_t *model) return ret; } + +int +machine_at_dvent4xx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dvent4xx/Venturis466_BIOS.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&sis_85c471_device); + device_add(&ide_cmd640_vlb_pri_device); + device_add(&fdc37c665_ide_device); + device_add(&keyboard_ps2_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&s3_phoenix_trio32_onboard_vlb_device); + + return ret; +} + +int +machine_at_ecsal486_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ecsal486/ECS_AL486.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_ap4100aa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap4100aa/M27C512DIP28.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + device_add(&ami_1994_nvr_device); + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_vlb_device); + device_add(&um8663bf_device); + + return ret; +} + +int +machine_at_atc1762_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/atc1762/atc1762.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ali1429g_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + + return ret; +} \ No newline at end of file diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 3587db44ad..a0b522371d 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -52,11 +52,12 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> +#include <86box/plat_unused.h> static serial_t *cmd_uart; static void -cbm_io_write(uint16_t port, uint8_t val, void *p) +cbm_io_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { lpt1_remove(); lpt2_remove(); @@ -71,6 +72,9 @@ cbm_io_write(uint16_t port, uint8_t val, void *p) case 3: lpt1_init(LPT2_ADDR); break; + + default: + break; } switch (val & 0xc) { @@ -80,6 +84,9 @@ cbm_io_write(uint16_t port, uint8_t val, void *p) case 0x8: serial_setup(cmd_uart, COM1_ADDR, COM1_IRQ); break; + + default: + break; } } diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index dd8370a4fa..428199de74 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -31,6 +31,8 @@ #include <86box/mem.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/chipset.h> +#include <86box/keyboard.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> @@ -40,23 +42,30 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> + + +static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; enum { COMPAQ_PORTABLEII = 0, COMPAQ_PORTABLEIII, COMPAQ_PORTABLEIII386, - COMPAQ_DESKPRO386 + COMPAQ_DESKPRO386, + COMPAQ_DESKPRO386_05_1988 }; #define CGA_RGB 0 #define CGA_COMPOSITE 1 -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 - /*Very rough estimate*/ #define VID_CLOCK (double) (651 * 416 * 60) +static uint8_t cga_crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + /* Mapping of attributes to colours */ static uint32_t amber; static uint32_t black; @@ -72,6 +81,8 @@ static uint32_t normcols[256][2]; */ static int8_t cpq_st_display_internal = -1; +static uint8_t mdaattr[256][2][2]; + static void compaq_plasma_display_set(uint8_t internal) { @@ -85,21 +96,13 @@ compaq_plasma_display_get(void) } typedef struct compaq_plasma_t { - mem_mapping_t plasma_mapping; cga_t cga; uint8_t port_23c6; uint8_t internal_monitor; - uint8_t attrmap; /* Attribute mapping register */ - int linepos, displine; - uint8_t *vram; - uint64_t dispontime, dispofftime; - int dispon, fullchange; + uint8_t attrmap; } compaq_plasma_t; -static uint8_t cga_crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +static int compaq_machine_type = 0; /* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */ static mem_mapping_t ram_mapping; @@ -121,8 +124,18 @@ compaq_plasma_recalctimings(compaq_plasma_t *self) disptime = 651; _dispontime = 640; _dispofftime = disptime - _dispontime; - self->dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); - self->dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); + self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); + self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); +} + +static void +compaq_plasma_waitstates(UNUSED(void *priv)) +{ + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; + int ws; + + ws = ws_array[cycles & 0xf]; + sub_cycles(ws); } static void @@ -130,7 +143,8 @@ compaq_plasma_write(uint32_t addr, uint8_t val, void *priv) { compaq_plasma_t *self = (compaq_plasma_t *) priv; - self->vram[addr & 0x7fff] = val; + self->cga.vram[addr & 0x7fff] = val; + compaq_plasma_waitstates(&self->cga); } static uint8_t @@ -139,206 +153,12 @@ compaq_plasma_read(uint32_t addr, void *priv) compaq_plasma_t *self = (compaq_plasma_t *) priv; uint8_t ret; - ret = (self->vram[addr & 0x7fff]); + compaq_plasma_waitstates(&self->cga); + ret = (self->cga.vram[addr & 0x7fff]); return ret; } -/* Draw a row of text in 80-column mode */ -static void -compaq_plasma_text80(compaq_plasma_t *self) -{ - uint32_t cols[2]; - int c; - uint8_t chr; - uint8_t attr; - int drawcursor; - int cursorline; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - - sc = (self->displine) & 15; - addr = ((ma & ~1) + (self->displine >> 4) * 80) * 2; - ma += (self->displine >> 4) * 80; - - if ((self->cga.crtc[10] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc); - - for (uint8_t x = 0; x < 80; x++) { - chr = self->vram[(addr + 2 * x) & 0x7FFF]; - attr = self->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - - if (self->cga.cgamode & 0x20) { /* Blink */ - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } else { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -static void -compaq_plasma_text40(compaq_plasma_t *self) -{ - uint32_t cols[2]; - int c; - uint8_t chr; - uint8_t attr; - int drawcursor; - int cursorline; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - - sc = (self->displine) & 15; - addr = ((ma & ~1) + (self->displine >> 4) * 40) * 2; - ma += (self->displine >> 4) * 40; - - if ((self->cga.crtc[10] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc); - - for (uint8_t x = 0; x < 40; x++) { - chr = self->vram[(addr + 2 * x) & 0x7FFF]; - attr = self->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - - if (self->cga.cgamode & 0x20) { /* Blink */ - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } else { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - -/* Draw a line in CGA 640x200 or Compaq Plasma 640x400 mode */ -static void -compaq_plasma_cgaline6(compaq_plasma_t *self) -{ - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (self->cga.cgacol & 0x0F) ? amber : black; - uint32_t bg = black; - - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - - if ((self->cga.crtc[9] == 3) || (self->port_23c6 & 1)) /* 640*400 */ { - addr = ((self->displine) & 1) * 0x2000 + ((self->displine >> 1) & 1) * 0x4000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - } else { - addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - } - for (uint8_t x = 0; x < 80; x++) { - dat = self->vram[addr & 0x7FFF]; - addr++; - - for (uint8_t c = 0; c < 8; c++) { - ink = (dat & 0x80) ? fg : bg; - if (!(self->cga.cgamode & 8)) - ink = black; - ((uint32_t *) buffer32->line[self->displine])[x * 8 + c] = ink; - dat <<= 1; - } - } -} - -/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to - * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ -static void -compaq_plasma_cgaline4(compaq_plasma_t *self) -{ - uint8_t dat; - uint8_t pattern; - uint32_t ink0 = 0; - uint32_t ink1 = 0; - uint16_t addr; - - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - - /* 320*200 */ - addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - - for (uint8_t x = 0; x < 80; x++) { - dat = self->vram[addr & 0x7FFF]; - addr++; - - for (uint8_t c = 0; c < 4; c++) { - pattern = (dat & 0xC0) >> 6; - if (!(self->cga.cgamode & 8)) - pattern = 0; - - switch (pattern & 3) { - case 0: - ink0 = ink1 = black; - break; - case 1: - if (self->displine & 1) { - ink0 = black; - ink1 = black; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 2: - if (self->displine & 1) { - ink0 = black; - ink1 = amber; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 3: - ink0 = ink1 = amber; - break; - } - ((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c] = ink0; - ((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c + 1] = ink1; - dat <<= 2; - } - } -} - static void compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) { @@ -348,7 +168,7 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { /* Emulated CRTC, register select */ case 0x3d4: - self->cga.crtcreg = val & 31; + cga_out(addr, val, &self->cga); break; /* Emulated CRTC, value */ @@ -366,33 +186,29 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) if (old != val) { if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) { - self->fullchange = changeframecount; + self->cga.fullchange = changeframecount; compaq_plasma_recalctimings(self); } } break; - case 0x3d8: - self->cga.cgamode = val; - break; - case 0x3d9: - self->cga.cgacol = val; + cga_out(addr, val, &self->cga); break; case 0x13c6: - if (val & 8) - compaq_plasma_display_set(1); - else - compaq_plasma_display_set(0); + compaq_plasma_display_set((val & 8) ? 1 : 0); break; case 0x23c6: self->port_23c6 = val; if (val & 8) /* Disable internal CGA */ - mem_mapping_disable(&self->plasma_mapping); + mem_mapping_disable(&self->cga.mapping); else - mem_mapping_enable(&self->plasma_mapping); + mem_mapping_enable(&self->cga.mapping); + break; + + default: break; } } @@ -405,31 +221,41 @@ compaq_plasma_in(uint16_t addr, void *priv) switch (addr) { case 0x3d4: - ret = self->cga.crtcreg; + case 0x3da: + ret = cga_in(addr, &self->cga); break; case 0x3d5: if (self->cga.crtcreg == 0x12) { - ret = self->attrmap & 0x0F; + ret = self->attrmap & 0x0f; if (self->internal_monitor) ret |= 0x30; /* Plasma / CRT */ } else - ret = self->cga.crtc[self->cga.crtcreg]; + ret = cga_in(addr, &self->cga); break; - case 0x3da: - ret = self->cga.cgastat; + case 0x13c6: + ret = compaq_plasma_display_get() ? 8 : 0; + ret |= 4; break; - case 0x13c6: - if (compaq_plasma_display_get()) - ret = 8; - else - ret = 0; + case 0x1bc6: + ret = 0; + if (compaq_plasma_display_get()) { + if ((self->cga.cgamode & 0x12) == 0x12) { + if (self->port_23c6 & 8) + ret |= 0x40; + else + ret |= 0x20; + } + } break; case 0x23c6: - ret = self->port_23c6; + ret = 0; + break; + + default: break; } @@ -437,59 +263,230 @@ compaq_plasma_in(uint16_t addr, void *priv) } static void -compaq_plasma_poll(void *p) +compaq_plasma_poll(void *priv) { - compaq_plasma_t *self = (compaq_plasma_t *) p; + compaq_plasma_t *self = (compaq_plasma_t *) priv; + uint8_t chr; + uint8_t attr; + uint8_t sc; + uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; + uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; + uint16_t addr; + int drawcursor; + int cursorline; + int blink = 0; + int underline = 0; + uint32_t ink = 0; + uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; + uint32_t bg = black; + uint32_t cols[2]; + uint8_t dat; + uint8_t pattern; + uint32_t ink0 = 0; + uint32_t ink1 = 0; /* Switch between internal plasma and external CRT display. */ - if (cpq_st_display_internal != -1 && cpq_st_display_internal != self->internal_monitor) { + if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) { self->internal_monitor = cpq_st_display_internal; compaq_plasma_recalctimings(self); } + /* graphic mode and not mode 40h */ if (!self->internal_monitor && !(self->port_23c6 & 1)) { cga_poll(&self->cga); return; } - if (!self->linepos) { - timer_advance_u64(&self->cga.timer, self->dispofftime); + /* mode 40h or text mode */ + if (!self->cga.linepos) { + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); self->cga.cgastat |= 1; - self->linepos = 1; - if (self->dispon) { - if (self->displine == 0) + self->cga.linepos = 1; + if (self->cga.cgadispon) { + if (self->cga.displine == 0) { video_wait_for_buffer(); + } + if (self->cga.cgamode & 2) { + if (self->cga.cgamode & 0x10) { + /* 640x400 mode */ + if (self->port_23c6 & 1) /* 640*400 */ { + addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + } + for (uint8_t x = 0; x < 80; x++) { + dat = self->cga.vram[addr & 0x7FFF]; + addr++; + + for (uint8_t c = 0; c < 8; c++) { + ink = (dat & 0x80) ? fg : bg; + if (!(self->cga.cgamode & 8)) + ink = black; + (buffer32->line[self->cga.displine])[x * 8 + c] = ink; + dat <<= 1; + } + } + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + for (uint8_t x = 0; x < 80; x++) { + dat = self->cga.vram[addr & 0x7fff]; + addr++; + + for (uint8_t c = 0; c < 4; c++) { + pattern = (dat & 0xC0) >> 6; + if (!(self->cga.cgamode & 8)) + pattern = 0; + + switch (pattern & 3) { + case 0: + ink0 = ink1 = black; + break; + case 1: + if (self->cga.displine & 1) { + ink0 = black; + ink1 = black; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 2: + if (self->cga.displine & 1) { + ink0 = black; + ink1 = amber; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 3: + ink0 = ink1 = amber; + break; + + default: + break; + } + buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0; + buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1; + dat <<= 2; + } + } + } + } else if (self->cga.cgamode & 1) { + /* 80-col */ + sc = self->cga.displine & 0x0f; + addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) * 2; + ma += (self->cga.displine >> 4) * 80; + + if ((self->cga.crtc[0x0a] & 0x60) == 0x20) + cursorline = 0; + else + cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); + + /* for each text column */ + for (uint8_t x = 0; x < 80; x++) { + /* video output enabled */ + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); + /* blink active */ + if (self->cga.cgamode & 0x20) { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if (blink) { + /* set blinking */ + cols[1] = cols[0]; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (sc == 7)) { + /* for each pixel in character width */ + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } else { + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } - /* Graphics */ - if (self->cga.cgamode & 0x02) { - if (self->cga.cgamode & 0x10) - compaq_plasma_cgaline6(self); + ++ma; + } + } else { /* 40-col */ + sc = self->cga.displine & 0x0f; + addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) * 2; + ma += (self->cga.displine >> 4) * 40; + + if ((self->cga.crtc[0x0a] & 0x60) == 0x20) + cursorline = 0; else - compaq_plasma_cgaline4(self); - } else if (self->cga.cgamode & 0x01) /* High-res text */ - compaq_plasma_text80(self); - else - compaq_plasma_text40(self); + cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); + + for (uint8_t x = 0; x < 40; x++) { + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); + /* blink active */ + if (self->cga.cgamode & 0x20) { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if (blink) { + /* set blinking */ + cols[1] = cols[0]; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (sc == 7)) { + /* for each pixel in character width */ + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } else { + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + ++ma; + } + } } - self->displine++; + self->cga.displine++; /* Hardcode a fixed refresh rate and VSYNC timing */ - if (self->displine == 400) { /* Start of VSYNC */ + if (self->cga.displine == 400) { /* Start of VSYNC */ self->cga.cgastat |= 8; - self->dispon = 0; + self->cga.cgadispon = 0; } - if (self->displine == 416) { /* End of VSYNC */ - self->displine = 0; + if (self->cga.displine == 416) { /* End of VSYNC */ + self->cga.displine = 0; self->cga.cgastat &= ~8; - self->dispon = 1; + self->cga.cgadispon = 1; } } else { - if (self->dispon) + if (self->cga.cgadispon) self->cga.cgastat &= ~1; - timer_advance_u64(&self->cga.timer, self->dispontime); - self->linepos = 0; + timer_advance_u64(&self->cga.timer, self->cga.dispontime); + self->cga.linepos = 0; - if (self->displine == 400) { + if (self->cga.displine == 400) { /* Hardcode 640x400 window size */ if ((640 != xsize) || (400 != ysize) || video_force_resize_get()) { xsize = 640; @@ -515,14 +512,39 @@ compaq_plasma_poll(void *p) video_bpp = 1; else video_bpp = 2; - } else video_bpp = 0; + self->cga.cgablink++; } } } +static void +compaq_plasma_mdaattr_rebuild(void) +{ + for (uint16_t c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } + + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; +} + static void compaq_plasma_recalcattrs(compaq_plasma_t *self) { @@ -537,10 +559,10 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self) * are bold */ /* Set up colours */ - amber = makecol(0xff, 0x7D, 0x00); - black = makecol(0x64, 0x19, 0x00); + amber = makecol(0xff, 0x7d, 0x00); + black = makecol(0x64, 0x0c, 0x00); - /* Initialise the attribute mapping. Start by defaulting everything + /* Initialize the attribute mapping. Start by defaulting everything * to black on amber, and with bold set by bit 3 */ for (n = 0; n < 256; n++) { blinkcols[n][0] = normcols[n][0] = amber; @@ -605,90 +627,62 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self) } static void * -compaq_plasma_init(const device_t *info) +compaq_plasma_init(UNUSED(const device_t *info)) { - int display_type; compaq_plasma_t *self = malloc(sizeof(compaq_plasma_t)); memset(self, 0, sizeof(compaq_plasma_t)); - display_type = device_get_config_int("display_type"); - self->cga.composite = (display_type != CGA_RGB); - self->cga.revision = device_get_config_int("composite_type"); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); + loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); + + self->cga.composite = 0; + self->cga.revision = 0; - self->vram = malloc(0x8000); + self->cga.vram = malloc(0x8000); self->internal_monitor = 1; cga_comp_init(self->cga.revision); timer_add(&self->cga.timer, compaq_plasma_poll, self, 1); - mem_mapping_add(&self->plasma_mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); + mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); io_sethandler(0x13c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + io_sethandler(0x1bc6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); io_sethandler(0x23c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); /* Default attribute mapping is 4 */ self->attrmap = 4; compaq_plasma_recalcattrs(self); - self->cga.cgastat = 0xF4; - self->cga.vram = self->vram; - + self->cga.cgastat = 0xf4; overscan_x = overscan_y = 16; self->cga.rgb_type = device_get_config_int("rgb_type"); cga_palette = (self->cga.rgb_type << 1); cgapal_rebuild(); + compaq_plasma_mdaattr_rebuild(); return self; } static void -compaq_plasma_close(void *p) +compaq_plasma_close(void *priv) { - compaq_plasma_t *self = (compaq_plasma_t *) p; - - free(self->vram); + compaq_plasma_t *self = (compaq_plasma_t *) priv; + free(self->cga.vram); free(self); } static void -compaq_plasma_speed_changed(void *p) +compaq_plasma_speed_changed(void *priv) { - compaq_plasma_t *self = (compaq_plasma_t *) p; + compaq_plasma_t *self = (compaq_plasma_t *) priv; compaq_plasma_recalctimings(self); } const device_config_t compaq_plasma_config[] = { // clang-format off - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = CGA_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "RGB", .value = CGA_RGB }, - { .description = "Composite", .value = CGA_COMPOSITE }, - { .description = "" } - } - }, - { - .name = "composite_type", - .description = "Composite type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = COMPOSITE_OLD, - .file_filter = "", - .spinner = { 0 }, - { - { .description = "Old", .value = COMPOSITE_OLD }, - { .description = "New", .value = COMPOSITE_NEW }, - { .description = "" } - } - }, { .name = "rgb_type", .description = "RGB type", @@ -702,7 +696,6 @@ const device_config_t compaq_plasma_config[] = { { .description = "Green Monochrome", .value = 1 }, { .description = "Amber Monochrome", .value = 2 }, { .description = "Gray Monochrome", .value = 3 }, - { .description = "Color (no brown)", .value = 4 }, { .description = "" } } }, @@ -725,7 +718,7 @@ const device_t compaq_plasma_device = { }; static uint8_t -read_ram(uint32_t addr, void *priv) +read_ram(uint32_t addr, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addreadlookup(mem_logical_addr, addr); @@ -734,7 +727,7 @@ read_ram(uint32_t addr, void *priv) } static uint16_t -read_ramw(uint32_t addr, void *priv) +read_ramw(uint32_t addr, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addreadlookup(mem_logical_addr, addr); @@ -743,7 +736,7 @@ read_ramw(uint32_t addr, void *priv) } static uint32_t -read_raml(uint32_t addr, void *priv) +read_raml(uint32_t addr, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addreadlookup(mem_logical_addr, addr); @@ -752,7 +745,7 @@ read_raml(uint32_t addr, void *priv) } static void -write_ram(uint32_t addr, uint8_t val, void *priv) +write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addwritelookup(mem_logical_addr, addr); @@ -761,7 +754,7 @@ write_ram(uint32_t addr, uint8_t val, void *priv) } static void -write_ramw(uint32_t addr, uint16_t val, void *priv) +write_ramw(uint32_t addr, uint16_t val, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addwritelookup(mem_logical_addr, addr); @@ -770,7 +763,7 @@ write_ramw(uint32_t addr, uint16_t val, void *priv) } static void -write_raml(uint32_t addr, uint32_t val, void *priv) +write_raml(uint32_t addr, uint32_t val, UNUSED(void *priv)) { addr = (addr & 0x7ffff) + 0x80000; addwritelookup(mem_logical_addr, addr); @@ -781,42 +774,45 @@ write_raml(uint32_t addr, uint32_t val, void *priv) static void machine_at_compaq_init(const machine_t *model, int type) { - if (type != COMPAQ_DESKPRO386) - mem_remap_top(384); + compaq_machine_type = type; if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, - read_ram, read_ramw, read_raml, - write_ram, write_ramw, write_raml, - 0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL); + if (type < COMPAQ_PORTABLEIII386) { + mem_remap_top(384); + mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, + read_ram, read_ramw, read_raml, + write_ram, write_ramw, write_raml, + 0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL); + } video_reset(gfxcard[0]); switch (type) { case COMPAQ_PORTABLEII: + machine_at_init(model); break; case COMPAQ_PORTABLEIII: - if (gfxcard[0] == VID_INTERNAL) - device_add(&compaq_plasma_device); - break; - case COMPAQ_PORTABLEIII386: if (hdc_current == 1) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); + machine_at_init(model); break; case COMPAQ_DESKPRO386: - if (hdc_current == 1) - device_add(&ide_isa_device); + case COMPAQ_DESKPRO386_05_1988: + device_add(&compaq_386_device); + machine_at_common_init(model); + device_add(&keyboard_at_compaq_device); break; - } - machine_at_init(model); + default: + break; + } } int @@ -841,9 +837,9 @@ machine_at_portableiii_init(const machine_t *model) { int ret; - ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin", - "roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", + 0x000f8000, 65536, 0); + if (bios_only || !ret) return ret; @@ -858,9 +854,8 @@ machine_at_portableiii386_init(const machine_t *model) { int ret; - ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin", - "roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", + 0x000f8000, 65536, 0); if (bios_only || !ret) return ret; @@ -870,14 +865,13 @@ machine_at_portableiii386_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) int machine_at_deskpro386_init(const machine_t *model) { int ret; ret = bios_load_linearr("roms/machines/deskpro386/1986-09-04-HI.json.bin", - 0x000fc000, 65536, 0); + 0x000f8000, 65536, 0); if (bios_only || !ret) return ret; @@ -886,4 +880,19 @@ machine_at_deskpro386_init(const machine_t *model) return ret; } -#endif + +int +machine_at_deskpro386_05_1988_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linearr("roms/machines/deskpro386/1988-05-10.json.bin", + 0x000f8000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_compaq_init(model, COMPAQ_DESKPRO386_05_1988); + + return ret; +} diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index 71c9d2ab79..d4264f07e7 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -1,74 +1,74 @@ -/* - * 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. - * - * Implementation of Miscellaneous, Fake, Hypervisor machines. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include "cpu.h" -#include <86box/machine.h> -#include <86box/sound.h> - -int -machine_at_vpc2007_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/vpc2007/13500.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - is_vpc = 1; - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440bx_no_agp_device); - device_add(&piix4e_device); - device_add(&w83977f_370_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ - - return ret; -} +/* + * 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. + * + * Implementation of Miscellaneous, Fake, Hypervisor machines. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/sound.h> + +int +machine_at_vpc2007_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/vpc2007/13500.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + is_vpc = 1; + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_no_agp_device); + device_add(&piix4e_device); + device_add(&w83977f_370_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ + + return ret; +} diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 3cedb669ac..d31d763d48 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -152,6 +152,42 @@ machine_at_spitfire_init(const machine_t *model) return ret; } +int +machine_at_ma30d_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ma30d/BIOS.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); +#ifdef UNKNOWN_SLOT + pci_register_slot(0x0A, PCI_CARD_NETWORK, 2, 3, 4, 1); /* ???? device - GPIO? */ +#endif + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 3, 0, 0, 0); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&nec_mate_unk_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + int machine_at_p6i440e2_init(const machine_t *model) { @@ -200,8 +236,8 @@ machine_at_p2bls_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* SCSI */ - pci_register_slot(0x07, PCI_CARD_NORMAL, 3, 4, 1, 2); /* LAN */ + pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); @@ -211,7 +247,9 @@ machine_at_p2bls_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977ef_device); - // device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */ +#if 0 + device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */ +#endif device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ @@ -221,6 +259,37 @@ machine_at_p2bls_init(const machine_t *model) return ret; } +int +machine_at_lgibmx7g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + int machine_at_p3bf_init(const machine_t *model) { @@ -738,3 +807,37 @@ machine_at_m729_init(const machine_t *model) return ret; } + +int +machine_at_p6f99_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6f99/99-8.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_SOUND, 2, 3, 4, 1); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5600_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8661f_device); + device_add(&winbond_flash_w29c020_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&es1371_onboard_device); + + return ret; +} + diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index fd91067aee..da160c138b 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -1,153 +1,153 @@ -/* - * 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. - * - * Implementation of Slot 2 machines. - * - * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include <86box/clock.h> -#include "cpu.h" -#include <86box/machine.h> - -int -machine_at_6gxu_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/6gxu/6gxu.f1c", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* On-Board SCSI. Not emulated at the moment */ - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); - device_add(&w83977ef_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ - hwm_values.temperatures[2] = 0; /* unused */ - hwm_values.voltages[1] = 1500; /* VGTL */ - - return ret; -} - -int -machine_at_s2dge_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s2dge/2gu7301.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977tf_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ - hwm_values.fans[1] = 0; /* no CPU2 fan */ - hwm_values.temperatures[0] = 0; /* unused */ - hwm_values.temperatures[2] = 0; /* CPU2? */ - - return ret; -} - -int -machine_at_fw6400gx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/fw6400gx/FWGX1211.ROM", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87309_15c_device); - device_add(ics9xxx_get(ICS9250_08)); - device_add(&sst_flash_29ee020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ - hwm_values.temperatures[3] = 0; /* unused */ - hwm_values.voltages[1] = 1500; /* Vtt */ - - return ret; -} +/* + * 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. + * + * Implementation of Slot 2 machines. + * + * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include <86box/clock.h> +#include "cpu.h" +#include <86box/machine.h> + +int +machine_at_6gxu_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/6gxu/6gxu.f1c", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* On-Board SCSI. Not emulated at the moment */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977ef_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ + hwm_values.temperatures[2] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* VGTL */ + + return ret; +} + +int +machine_at_s2dge_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s2dge/2gu7301.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ + hwm_values.fans[1] = 0; /* no CPU2 fan */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* CPU2? */ + + return ret; +} + +int +machine_at_fw6400gx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/fw6400gx/FWGX1211.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87309_15c_device); + device_add(ics9xxx_get(ICS9250_08)); + device_add(&sst_flash_29ee020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ + hwm_values.temperatures[3] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* Vtt */ + + return ret; +} diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index b8cc437a11..dce0034ffc 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -1,458 +1,503 @@ -/* - * 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. - * - * Implementation of Socket 370(PGA370) machines. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include "cpu.h" -#include <86box/machine.h> -#include <86box/clock.h> -#include <86box/sound.h> -#include <86box/snd_ac97.h> - -int -machine_at_s370slm_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s370slm/3LM1202.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440lx_device); - device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ - hwm_values.temperatures[0] = 0; /* unused */ - hwm_values.temperatures[2] = 0; /* unused */ - - return ret; -} - -int -machine_at_s1857_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s1857/BX57200A.ROM", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 0, 0, 0); - pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977ef_370_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); - device_add(&cs4297_device); /* found on other Tyan boards around the same time */ - } - - return ret; -} - -int -machine_at_p6bap_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p6bap/bapa14a.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); - device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ - device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - return ret; -} - -int -machine_at_p6bat_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p6bat/bata+56.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); - device_add(&via_apro133_device); - device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&cmi8738_onboard_device); - } - - return ret; -} - -int -machine_at_cubx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/cubx/1008cu.004", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_IDE, 2, 3, 4, 1); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977ef_device); - device_add(ics9xxx_get(ICS9250_08)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ - - return ret; -} - -int -machine_at_atc7020bxii_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/atc7020bxii/7020s102.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&slc90e66_device); - device_add(&keyboard_ps2_pci_device); - device_add(&w83977ef_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - return ret; -} - -int -machine_at_ambx133_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ambx133/mkbx2vg2.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */ - hwm_values.fans[1] += 500; - hwm_values.temperatures[0] += 4; /* CPU offset */ - hwm_values.voltages[1] = RESISTOR_DIVIDER(12000, 10, 2); /* different 12V divider in BIOS (10K/2K?) */ - - return ret; -} - -int -machine_at_awo671r_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/awo671r/a08139c.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add_inst(&w83977ef_device, 1); - device_add_inst(&w83977ef_device, 2); - device_add(&keyboard_ps2_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); - - return ret; -} - -int -machine_at_63a1_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/63a1/63a-q3.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Integrated Sound? */ - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440zx_device); - device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); - - return ret; -} - -int -machine_at_apas3_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/apas3/V0218SAG.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro_device); - device_add(&via_vt82c586b_device); - device_add(&fdc37c669_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - return ret; -} - -int -machine_at_cuv4xls_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/cuv4xls/1005LS.001", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x04, PCI_CARD_SOUTHBRIDGE, 4, 1, 2, 3); - pci_register_slot(0x05, PCI_CARD_SOUND, 3, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 0, 0); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro133a_device); - device_add(&via_vt82c686b_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(ics9xxx_get(ICS9250_18)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 1024); - device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ - - if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&cmi8738_onboard_device); - - return ret; -} - -int -machine_at_6via90ap_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/6via90ap/90ap10.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro133a_device); - device_add(&via_vt82c686b_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ - device_add(&keyboard_ps2_ami_pci_device); - device_add(ics9xxx_get(ICS9250_18)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 1024); - hwm_values.temperatures[0] += 2; /* CPU offset */ - hwm_values.temperatures[1] += 2; /* System offset */ - hwm_values.temperatures[2] = 0; /* unused */ - - if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&alc100_device); /* ALC100P identified on similar Acorp boards (694TA, 6VIA90A1) */ - - return ret; -} +/* + * 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. + * + * Implementation of Socket 370(PGA370) machines. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/clock.h> +#include <86box/sound.h> +#include <86box/snd_ac97.h> + +int +machine_at_s370slm_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s370slm/3LM1202.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ + + return ret; +} + +int +machine_at_s1857_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s1857/BX57200A.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977ef_370_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(&es1371_onboard_device); + device_add(&cs4297_device); /* found on other Tyan boards around the same time */ + } + + return ret; +} + +int +machine_at_p6bap_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6bap/bapa14a.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ + device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + +int +machine_at_p6bat_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6bat/bata+56.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + device_add(&via_apro133_device); + device_add(&via_vt82c596b_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + +int +machine_at_cubx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cubx/1008cu.004", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_IDE, 2, 3, 4, 1); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977ef_device); + device_add(ics9xxx_get(ICS9250_08)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + return ret; +} + +int +machine_at_atc7020bxii_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/atc7020bxii/7020s102.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&slc90e66_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977ef_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + + return ret; +} + +int +machine_at_m773_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m773/010504s.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUND, 4, 3, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&slc90e66_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8671f_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */ + hwm_values.temperatures[0] += 2; /* System offset */ + hwm_values.temperatures[1] += 2; /* CPU offset */ + hwm_values.voltages[0] = 3300; /* Vcore and 3.3V are swapped */ + hwm_values.voltages[2] = hwm_get_vcore(); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + +int +machine_at_ambx133_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ambx133/mkbx2vg2.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */ + hwm_values.fans[1] += 500; + hwm_values.temperatures[0] += 4; /* CPU offset */ + hwm_values.voltages[1] = RESISTOR_DIVIDER(12000, 10, 2); /* different 12V divider in BIOS (10K/2K?) */ + + return ret; +} + +int +machine_at_awo671r_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/awo671r/a08139c.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add_inst(&w83977ef_device, 1); + device_add_inst(&w83977ef_device, 2); + device_add(&keyboard_ps2_pci_device); + device_add(&sst_flash_39sf020_device); + if (gfxcard[0] == VID_INTERNAL) { + device_add(&chips_69000_onboard_device); + } + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + return ret; +} + +int +machine_at_63a1_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/63a1/63a-q3.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Integrated Sound? */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440zx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + return ret; +} + +int +machine_at_apas3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/apas3/V0218SAG.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro_device); + device_add(&via_vt82c586b_device); + device_add(&fdc37c669_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + +int +machine_at_cuv4xls_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cuv4xls/1005LS.001", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x04, PCI_CARD_SOUTHBRIDGE, 4, 1, 2, 3); + pci_register_slot(0x05, PCI_CARD_SOUND, 3, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(ics9xxx_get(ICS9250_18)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 1024); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + +int +machine_at_6via90ap_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/6via90ap/90ap10.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ + device_add(&keyboard_ps2_ami_pci_device); + device_add(ics9xxx_get(ICS9250_18)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); + hwm_values.temperatures[0] += 2; /* CPU offset */ + hwm_values.temperatures[1] += 2; /* System offset */ + hwm_values.temperatures[2] = 0; /* unused */ + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&alc100_device); /* ALC100P identified on similar Acorp boards (694TA, 6VIA90A1) */ + + return ret; +} diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index ef745d0886..02018949c8 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -10,10 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2010-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ #include @@ -47,7 +45,7 @@ void machine_at_premiere_common_init(const machine_t *model, int pci_switch) { machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | pci_switch); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -62,29 +60,6 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) device_add(&intel_flash_bxt_ami_device); } -void -machine_at_award_common_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&ide_pci_2ch_device); - - pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ - pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - - // device_add(&keyboard_ps2_pci_device); - device_add(&keyboard_ps2_ami_pci_device); -} - void machine_at_sp4_common_init(const machine_t *model) { @@ -181,7 +156,7 @@ machine_at_dellxp60_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -267,6 +242,7 @@ machine_at_valuepointp60_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_VIDEO, 3, 3, 3, 3); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); @@ -278,6 +254,9 @@ machine_at_valuepointp60_init(const machine_t *model) device_add(&i430lx_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&mach32_onboard_pci_device); + return ret; } @@ -286,8 +265,8 @@ machine_at_revenge_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined("roms/machines/revenge/1009af2_.bio", - "roms/machines/revenge/1009af2_.bi1", + ret = bios_load_linear_combined("roms/machines/revenge/1013af2_.bio", + "roms/machines/revenge/1013af2_.bi1", 0x1c000, 128); if (bios_only || !ret) @@ -300,12 +279,34 @@ machine_at_revenge_init(const machine_t *model) return ret; } +void +machine_at_award_common_init(const machine_t *model) +{ + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ + pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sio_zb_device); + device_add(&intel_flash_bxt_device); +} + int -machine_at_586mc1_init(const machine_t *model) +machine_at_586is_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/586mc1/IS.34", + ret = bios_load_linear("roms/machines/586is/IS.34", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -313,8 +314,6 @@ machine_at_586mc1_init(const machine_t *model) machine_at_award_common_init(model); - device_add(&sio_device); - device_add(&intel_flash_bxt_device); device_add(&i430lx_device); return ret; diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 9a45e71bf0..916f8490b9 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -10,10 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2010-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ #include @@ -61,6 +59,25 @@ machine_at_plato_init(const machine_t *model) return ret; } +int +machine_at_dellplato_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/dellplato/1016AX1J.bio", + "roms/machines/dellplato/1016AX1J.bi1", + 0x1d000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE); + + device_add(&i430nx_device); + + return ret; +} + int machine_at_ambradp90_init(const machine_t *model) { @@ -81,11 +98,11 @@ machine_at_ambradp90_init(const machine_t *model) } int -machine_at_430nx_init(const machine_t *model) +machine_at_586ip_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/430nx/IP.20", + ret = bios_load_linear("roms/machines/586ip/IP.20", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -93,13 +110,41 @@ machine_at_430nx_init(const machine_t *model) machine_at_award_common_init(model); - device_add(&sio_device); - device_add(&intel_flash_bxt_device); device_add(&i430nx_device); return ret; } +int +machine_at_tek932_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tek932/B932_019.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430nx_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_ide_device); + device_add(&ide_vlb_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_acerv30_init(const machine_t *model) { @@ -160,6 +205,39 @@ machine_at_apollo_init(const machine_t *model) return ret; } +static void +machine_at_zappa_gpio_init(void) +{ + uint32_t gpio = 0xffffe6ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: No Connect. */ + /* Bit 1: No Connect. */ + /* Bit 0: 2x multiplier, 1 = 1.5x multiplier (Switch 6). */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff00ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff08ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff10ff; + + if (cpu_dmulti <= 1.5) + gpio |= 0xffff01ff; + else + gpio |= 0xffff00ff; + + machine_set_gpio_default(gpio); +} + int machine_at_zappa_init(const machine_t *model) { @@ -172,7 +250,8 @@ machine_at_zappa_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_zappa_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -246,6 +325,35 @@ machine_at_hawk_init(const machine_t *model) return ret; } +int +machine_at_pt2000_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ficpt2000/PT2000_v1.01.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87332_398_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_pat54pv_init(const machine_t *model) { @@ -298,6 +406,36 @@ machine_at_hot543_init(const machine_t *model) return ret; } +int +machine_at_ncselp90_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ncselp90/elegancep90.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&opti5x7_pci_device); + device_add(&opti822_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_opti611_vlb_device); + device_add(&fdc37c665_ide_sec_device); + device_add(&ide_vlb_2ch_device); + + return ret; +} + int machine_at_p54sp4_init(const machine_t *model) { @@ -373,3 +511,99 @@ machine_at_p54sps_init(const machine_t *model) return ret; } + +int +machine_at_ms5109_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5109/A778.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 3, 2, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_550x_85c503_device); + device_add(&ide_w83769f_pci_device); + device_add(&keyboard_ps2_ami_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_torino_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/torino/PER113.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_1994_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&sis_550x_85c503_device); + device_add(&ide_um8673f_device); + device_add(&keyboard_ps2_tg_ami_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_hot539_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hot539/539_R17.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x15, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x16, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&umc_8890_device); + device_add(&umc_8886af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&um8663af_device); + + return ret; +} diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 3c0f0481a5..9ab24b7c26 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -10,11 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, * - * Copyright 2010-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * */ @@ -46,6 +43,8 @@ #include <86box/fdc.h> #include <86box/nvr.h> #include <86box/scsi_ncr53c8xx.h> +#include <86box/thread.h> +#include <86box/network.h> int machine_at_acerv35n_init(const machine_t *model) @@ -174,6 +173,42 @@ machine_at_m7shi_init(const machine_t *model) return ret; } +/* The Sony VAIO is an AG430HX, I'm assuming it has the same configuration bits + as the TC430HX, hence the #define. */ +#define machine_at_ag430hx_gpio_init machine_at_tc430hx_gpio_init + +/* The PB680 is a NV430VX, I'm assuming it has the same configuration bits as + the TC430HX, hence the #define. */ +#define machine_at_nv430vx_gpio_init machine_at_tc430hx_gpio_init + +static void +machine_at_tc430hx_gpio_init(void) +{ + uint32_t gpio = 0xffffe1ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ + /* Bit 0: 0 = Reserved. */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff10ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff18ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff00ff; + + machine_set_gpio_default(gpio); +} + int machine_at_tc430hx_init(const machine_t *model) { @@ -189,7 +224,8 @@ machine_at_tc430hx_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_tc430hx_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -199,7 +235,10 @@ machine_at_tc430hx_init(const machine_t *model) 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&s3_virge_375_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -224,7 +263,8 @@ machine_at_infinia7200_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_tc430hx_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -234,7 +274,10 @@ machine_at_infinia7200_init(const machine_t *model) 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&s3_virge_375_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -244,37 +287,99 @@ machine_at_infinia7200_init(const machine_t *model) return ret; } -/* Information about that machine on machine.h */ -int -machine_at_equium5200_init(const machine_t *model) +static void +machine_at_cu430hx_gpio_init(void) { - int ret; - - ret = bios_load_linear_combined2("roms/machines/equium5200/1003DK08.BIO", - "roms/machines/equium5200/1003DK08.BI1", - "roms/machines/equium5200/1003DK08.BI2", - "roms/machines/equium5200/1003DK08.BI3", - "roms/machines/equium5200/1003DK08.RCV", - 0x3a000, 128); - - if (bios_only || !ret) - return ret; + uint32_t gpio = 0xffffe1ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ + /* Bit 0: 0 = Reserved. */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff10ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff18ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff00ff; + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)->available()) + gpio |= 0xffff04ff; + + machine_set_gpio_default(gpio); +} - machine_at_common_init(model); +static void +machine_at_cu430hx_common_init(const machine_t *model) +{ + machine_at_common_init_ex(model, 2); + machine_at_cu430hx_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); // ATI VGA Graphics + pci_register_slot(0x0C, PCI_CARD_NETWORK, 4, 0, 0, 0); // Intel 82557 Ethernet Network pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)->available()) + machine_snd = device_add(machine_get_snd_device(machine)); + device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87306_device); device_add(&intel_flash_bxt_ami_device); +} + +int +machine_at_cu430hx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/cu430hx/1006DK0_.BIO", + "roms/machines/cu430hx/1006DK0_.BI1", + "roms/machines/cu430hx/1006DK0_.BI2", + "roms/machines/cu430hx/1006DK0_.BI3", + "roms/machines/cu430hx/1006DK0_.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_cu430hx_common_init(model); + + return ret; +} + +int +machine_at_equium5200_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/equium5200/1003DK08.BIO", + "roms/machines/equium5200/1003DK08.BI1", + "roms/machines/equium5200/1003DK08.BI2", + "roms/machines/equium5200/1003DK08.BI3", + "roms/machines/equium5200/1003DK08.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_cu430hx_common_init(model); return ret; } @@ -294,7 +399,8 @@ machine_at_pcv90_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_ag430hx_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -329,6 +435,35 @@ machine_at_p65up5_cp55t2d_init(const machine_t *model) return ret; } +int +machine_at_epc2102_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/epc2102/P5000HX.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + 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, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&i82091aa_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p55tvp4_init(const machine_t *model) { @@ -428,7 +563,7 @@ machine_at_presario2240_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_NO_BRIDGES); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); @@ -459,7 +594,7 @@ machine_at_presario4500_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_NO_BRIDGES); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); @@ -550,7 +685,8 @@ machine_at_pb680_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_nv430vx_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -559,6 +695,10 @@ machine_at_pb680_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -905,6 +1045,80 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } +int +machine_at_richmond_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/richmond/RICHMOND.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8671f_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + return ret; +} + +int +machine_at_tomahawk_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tomahawk/0AAGT046.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_VIDEO, 3, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NETWORK, 4, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&amd_flash_29f020a_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + if ((gfxcard[0] == VID_INTERNAL) && machine_get_vid_device(machine)) + device_add(machine_get_vid_device(machine)); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)) + device_add(machine_get_snd_device(machine)); + + if ((net_cards_conf[0].device_num == NET_INTERNAL) && machine_get_net_device(machine)) + device_add(machine_get_net_device(machine)); + + return ret; +} + int machine_at_ficva502_init(const machine_t *model) { @@ -978,9 +1192,9 @@ machine_at_r534f_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1007,9 +1221,9 @@ machine_at_ms5146_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -1025,6 +1239,119 @@ machine_at_ms5146_init(const machine_t *model) return ret; } +int +machine_at_cb52xsi_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cb52xsi/CD5205S.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_370_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_sp97xv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sp97xv/0109XVJ2.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */ + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_sq578_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sq578/578b03.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&sis_5581_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_ms5172_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5172/A572MS15.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_m560_init(const machine_t *model) { @@ -1088,3 +1415,33 @@ machine_at_ms5164_init(const machine_t *model) return ret; } + +int +machine_at_thunderbolt_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/thunderbolt/tbolt-01.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 1, 2, 3); /* PIIX4 */ + pci_register_slot(0x11, PCI_CARD_NORMAL, 0, 1, 2, 3); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 0); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 0, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 0, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c935_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index d8be38bb1b..676f50fb1f 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -10,11 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, * - * Copyright 2010-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ #include @@ -43,11 +40,59 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/nvr.h> +#include <86box/plat_unused.h> +#include <86box/sound.h> static void -machine_at_thor_common_init(const machine_t *model, int mr) +machine_at_thor_gpio_init(void) { - machine_at_common_init_ex(model, mr); + uint32_t gpio = 0xffffe1cf; + + /* Register 0x0078 (Undocumented): */ + /* Bit 5: 0 = Multiplier. */ + /* Bit 4: 0 = Multiplier. */ + /* 1.5: 0, 0. */ + /* 3.0: 0, 1. */ + /* 2.0: 1, 0. */ + /* 2.5: 1, 1. */ + /* Bit 1: 0 = Error beep, 1 = No error. */ + if (cpu_dmulti <= 1.5) + gpio |= 0xffff0000; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + gpio |= 0xffff0020; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + gpio |= 0xffff0030; + else if (cpu_dmulti > 2.5) + gpio |= 0xffff0010; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ + /* Bit 0: 0 = Reserved. */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff0000; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff0800; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff1000; + + machine_set_gpio_default(gpio); +} + +static void +machine_at_thor_common_init(const machine_t *model, int has_video) +{ + machine_at_common_init_ex(model, 2); + machine_at_thor_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -58,10 +103,9 @@ machine_at_thor_common_init(const machine_t *model, int mr) pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_phoenix_trio64vplus_onboard_pci_device); + if (has_video && (gfxcard[0] == VID_INTERNAL)) + device_add(machine_get_vid_device(machine)); - // device_add(&keyboard_ps2_ami_pci_device); device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -178,7 +222,7 @@ machine_at_thor_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_thor_common_init(model, 0); + machine_at_thor_common_init(model, 1); return ret; } @@ -194,7 +238,93 @@ machine_at_mrthor_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_thor_common_init(model, 1); + machine_at_thor_common_init(model, 0); + + return ret; +} + +static void +machine_at_endeavor_gpio_init(void) +{ + uint32_t gpio = 0xffffe0cf; + uint16_t addr; + + /* Register 0x0078 (Undocumented): */ + /* Bit 5,4: Vibra 16S base address: 0 = 220h, 1 = 260h, 2 = 240h, 3 = 280h. */ + device_context(machine_get_snd_device(machine)); + addr = device_get_config_hex16("base"); + switch (addr) { + case 0x0220: + gpio |= 0xffff00cf; + break; + case 0x0240: + gpio |= 0xffff00ef; + break; + case 0x0260: + gpio |= 0xffff00df; + break; + case 0x0280: + gpio |= 0xffff00ff; + break; + } + device_context_restore(); + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ + /* Bit 0: 0 = 2x multiplier, 1 = 1.5x multiplier (Switch 6). */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff0000; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff0800; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff1000; + + if (sound_card_current[0] == SOUND_INTERNAL) + gpio |= 0xffff0400; + + if (cpu_dmulti <= 1.5) + gpio |= 0xffff0100; + else + gpio |= 0xffff0000; + + machine_set_gpio_default(gpio); +} + +uint32_t +machine_at_endeavor_gpio_handler(uint8_t write, uint32_t val) +{ + uint32_t ret = machine_get_gpio_default(); + + if (write) { + ret &= ((val & 0xffffffcf) | 0xffff0000); + ret |= (val & 0x00000030); + if (machine_snd != NULL) switch ((val >> 4) & 0x03) { + case 0x00: + sb_vibra16s_onboard_relocate_base(0x0220, machine_snd); + break; + case 0x01: + sb_vibra16s_onboard_relocate_base(0x0260, machine_snd); + break; + case 0x02: + sb_vibra16s_onboard_relocate_base(0x0240, machine_snd); + break; + case 0x03: + sb_vibra16s_onboard_relocate_base(0x0280, machine_snd); + break; + } + machine_set_gpio(ret); + } else + ret = machine_get_gpio(); return ret; } @@ -211,7 +341,8 @@ machine_at_endeavor_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_endeavor_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -223,7 +354,10 @@ machine_at_endeavor_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_phoenix_trio64_onboard_pci_device); + device_add(machine_get_vid_device(machine)); + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430fx_device); @@ -239,7 +373,7 @@ machine_at_ms5119_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/ms5119/A37E.ROM", + ret = bios_load_linear("roms/machines/ms5119/A37EB.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -263,6 +397,39 @@ machine_at_ms5119_init(const machine_t *model) return ret; } +static void +machine_at_pb640_gpio_init(void) +{ + uint32_t gpio = 0xffffe6ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: No Connect. */ + /* Bit 1: No Connect. */ + /* Bit 0: 2x multiplier, 1 = 1.5x multiplier (Switch 6). */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff00ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff08ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff10ff; + + if (cpu_dmulti <= 1.5) + gpio |= 0xffff01ff; + else + gpio |= 0xffff00ff; + + machine_set_gpio_default(gpio); +} + int machine_at_pb640_init(const machine_t *model) { @@ -274,7 +441,8 @@ machine_at_pb640_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + machine_at_pb640_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -379,7 +547,7 @@ machine_at_acerm3a_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c932fr_device); + device_add(&fdc37c935_device); device_add(&sst_flash_29ee010_device); @@ -456,7 +624,7 @@ machine_at_p55t2s_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -503,6 +671,40 @@ machine_at_p5vxb_init(const machine_t *model) return ret; } +int +machine_at_dellhannibalp_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dellhannibalp/1003DY0J.BIO", + "roms/machines/dellhannibalp/1003DY0J.BI1", + "roms/machines/dellhannibalp/1003DY0J.BI2", + "roms/machines/dellhannibalp/1003DY0J.BI3", + "roms/machines/dellhannibalp/1003DY0J.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_gw2kte_init(const machine_t *model) { @@ -526,7 +728,7 @@ machine_at_gw2kte_init(const machine_t *model) 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, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); @@ -548,18 +750,18 @@ machine_at_ap5s_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); device_add(&fdc37c665_device); device_add(&sst_flash_29ee010_device); @@ -577,24 +779,53 @@ machine_at_ms5124_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0xFE, 0xFF, 0, 0); - pci_register_slot(0x10, PCI_CARD_NORMAL, 0x41, 0x42, 0x43, 0x44); - pci_register_slot(0x11, PCI_CARD_NORMAL, 0x44, 0x41, 0x42, 0x43); - pci_register_slot(0x12, PCI_CARD_NORMAL, 0x43, 0x44, 0x41, 0x42); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 0x42, 0x43, 0x44, 0x41); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83787f_device); + device_add(&keyboard_ps2_ami_device); + device_add(&w83787f_88h_device); device_add(&sst_flash_29ee010_device); return ret; } +int +machine_at_amis727_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/amis727/S727p.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5511_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_vectra54_init(const machine_t *model) { @@ -627,3 +858,31 @@ machine_at_vectra54_init(const machine_t *model) return ret; } + +int +machine_at_5sbm2_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sbm2/5SBM0717.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&keyboard_at_ami_device); + device_add(&sis_550x_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index c1c95f197e..e1dad68e75 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -39,6 +39,39 @@ #include "cpu.h" #include <86box/machine.h> +int +machine_at_ap61_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap61/ap61r120.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i450kx_device); + device_add(&sio_zb_device); + device_add(&ide_cmd646_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + device_add(&sst_flash_29ee010_device); + // device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_p6rp4_init(const machine_t *model) { @@ -54,14 +87,14 @@ machine_at_p6rp4_init(const machine_t *model) device_add(&p6rp4_nvr_device); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i450kx_device); device_add(&sio_zb_device); device_add(&ide_cmd646_device); @@ -161,6 +194,37 @@ machine_at_acerv60n_init(const machine_t *model) return ret; } +int +machine_at_lgibmx61_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibmx61/bios.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i440fx_device); + device_add(&piix3_device); + // device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); + // device_add(&w83787f_device); + device_add(&w83877f_president_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_vs440fx_init(const machine_t *model) { @@ -195,6 +259,40 @@ machine_at_vs440fx_init(const machine_t *model) return ret; } +int +machine_at_gw2kvenus_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/gw2kvenus/1011CS1T.BIO", + "roms/machines/gw2kvenus/1011CS1T.BI1", + "roms/machines/gw2kvenus/1011CS1T.BI2", + "roms/machines/gw2kvenus/1011CS1T.BI3", + "roms/machines/gw2kvenus/1011CS1T.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&pc87307_device); + + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_ap440fx_init(const machine_t *model) { diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index dab5447078..32319e160d 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -10,13 +10,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, * - * Copyright 2010-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. */ #include #include @@ -110,6 +106,38 @@ machine_at_m579_init(const machine_t *model) return ret; } +int +machine_at_gwlucas_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/gwlucas/gw2kboot.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 2, 3, 4); // ES1373 + pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&ali1541_device); + device_add(&ali1543c_device); /* +0 */ + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); + + return ret; +} + int machine_at_5aa_init(const machine_t *model) { @@ -309,3 +337,32 @@ machine_at_5emapro_init(const machine_t *model) return ret; } + +int +machine_at_5sg100_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/5sg100/5sg.20g", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); + device_add(&sis_5591_1997_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index b1f8d10f60..e3e24cf2c5 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -121,11 +121,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2017-2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. + * Copyright 2008-2018 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -166,6 +166,7 @@ #include <86box/fdc_ext.h> #include <86box/machine.h> #include <86box/m_at_t3100e.h> +#include <86box/plat_unused.h> extern uint8_t *ram; /* Physical RAM */ @@ -191,12 +192,12 @@ static unsigned t3100e_ems_page_reg[] = { 0x4208, 0x8208, 0xc208, /* The first four map the first 2Mb */ - /* of RAM into the page frame */ + /* of RAM into the page frame */ 0x218, 0x4218, 0x8218, 0xc218, /* The next four map the next 2Mb */ - /* of RAM */ + /* of RAM */ 0x258, 0x4258, 0x8258, @@ -221,7 +222,7 @@ struct t3100e_ems_regs { /* Bit 0 is 0 for colour, 1 for mono */ } t3100e_ems; -void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); +void t3100e_ems_out(uint16_t addr, uint8_t val, void *priv); #ifdef ENABLE_T3100E_LOG int t3100e_do_log = ENABLE_T3100E_LOG; @@ -331,11 +332,15 @@ port_to_page(uint16_t addr) return 14; case 0xC268: return 15; + + default: + break; } return -1; } -/* Used to dump the memory mapping table, for debugging +/* Used to dump the memory mapping table, for debugging */ +#if 0 void dump_mappings(void) { mem_mapping_t *mm = base_mapping.next; @@ -377,7 +382,8 @@ void dump_mappings(void) mm = mm->next; } -}*/ +} +#endif void t3100e_map_ram(uint8_t val) @@ -437,7 +443,9 @@ t3100e_map_ram(uint8_t val) &t3100e_ems); } - // dump_mappings(); +#if 0 + dump_mappings(); +#endif } void @@ -470,9 +478,9 @@ t3100e_turbo_set(uint8_t value) } uint8_t -t3100e_sys_in(uint16_t addr, void *p) +t3100e_sys_in(UNUSED(uint16_t addr), void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) p; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; /* The low 4 bits always seem to be 0x0C. The high 4 are a * notification sent by the keyboard controller when it detects @@ -483,9 +491,11 @@ t3100e_sys_in(uint16_t addr, void *p) /* Handle writes to the T3100e system control port at 0x8084 */ void -t3100e_sys_out(uint16_t addr, uint8_t val, void *p) +t3100e_sys_out(UNUSED(uint16_t addr), uint8_t val, UNUSED(void *priv)) { - // struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; +#if 0 + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; +#endif switch (val & 0xE0) { case 0x00: /* Set serial port IRQs. Not implemented */ @@ -551,6 +561,9 @@ t3100e_config_get(void) value |= 0x10; break; /* Tri-mode */ /* All others will be treated as 1.4M */ + + default: + break; } break; case 4: @@ -574,7 +587,11 @@ t3100e_config_get(void) prt_switch = 0; /* No external drive */ } break; + + default: + break; } /* End switch */ + switch (prt_switch) { case 0: value |= 4; @@ -585,15 +602,18 @@ t3100e_config_get(void) case 2: value |= 6; break; /* External floppy is B: */ + + default: + break; } return value; } /* Read EMS page register */ uint8_t -t3100e_ems_in(uint16_t addr, void *p) +t3100e_ems_in(uint16_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) p; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; int page = port_to_page(addr); if (page >= 0) @@ -606,9 +626,9 @@ t3100e_ems_in(uint16_t addr, void *p) /* Write EMS page register */ void -t3100e_ems_out(uint16_t addr, uint8_t val, void *p) +t3100e_ems_out(uint16_t addr, uint8_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) p; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; int pg = port_to_page(addr); if (pg == -1) @@ -637,8 +657,8 @@ t3100e_ems_out(uint16_t addr, uint8_t val, void *p) static uint8_t ems_read_ram(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return 0xFF; @@ -649,22 +669,26 @@ ems_read_ram(uint32_t addr, void *priv) static uint16_t ems_read_ramw(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return 0xFFFF; - // t3100e_log("ems_read_ramw addr=%05x ", addr); +#if 0 + t3100e_log("ems_read_ramw addr=%05x ", addr); +#endif addr = regs->page_exec[pg] + (addr & 0x3FFF); - // t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); +#if 0 + // t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *) &ram[addr]); +#endif return *(uint16_t *) &ram[addr]; } static uint32_t ems_read_raml(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return 0xFFFFFFFF; @@ -676,8 +700,8 @@ ems_read_raml(uint32_t addr, void *priv) static void ems_write_ram(uint32_t addr, uint8_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; @@ -688,14 +712,18 @@ ems_write_ram(uint32_t addr, uint8_t val, void *priv) static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; - // t3100e_log("ems_write_ramw addr=%05x ", addr); +#if 0 + t3100e_log("ems_write_ramw addr=%05x ", addr); +#endif addr = regs->page_exec[pg] + (addr & 0x3FFF); - // t3100e_log("-> %06x val=%04x\n", addr, val); +#if 0 + t3100e_log("-> %06x val=%04x\n", addr, val); +#endif *(uint16_t *) &ram[addr] = val; } @@ -703,8 +731,8 @@ ems_write_ramw(uint32_t addr, uint16_t val, void *priv) static void ems_write_raml(uint32_t addr, uint32_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; - int pg = addr_to_page(addr); + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; @@ -717,7 +745,7 @@ ems_write_raml(uint32_t addr, uint32_t val, void *priv) static uint8_t upper_read_ram(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; return ram[addr]; @@ -726,7 +754,7 @@ upper_read_ram(uint32_t addr, void *priv) static uint16_t upper_read_ramw(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; return *(uint16_t *) &ram[addr]; @@ -735,7 +763,7 @@ upper_read_ramw(uint32_t addr, void *priv) static uint32_t upper_read_raml(uint32_t addr, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; return *(uint32_t *) &ram[addr]; @@ -744,7 +772,7 @@ upper_read_raml(uint32_t addr, void *priv) static void upper_write_ram(uint32_t addr, uint8_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; ram[addr] = val; @@ -753,7 +781,7 @@ upper_write_ram(uint32_t addr, uint8_t val, void *priv) static void upper_write_ramw(uint32_t addr, uint16_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; *(uint16_t *) &ram[addr] = val; @@ -762,7 +790,7 @@ upper_write_ramw(uint32_t addr, uint16_t val, void *priv) static void upper_write_raml(uint32_t addr, uint32_t val, void *priv) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; + const struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *) priv; addr = (addr - (1024 * mem_size)) + regs->upper_base; *(uint32_t *) &ram[addr] = val; diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 9602b7b9e7..50c9ec05a7 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -26,11 +26,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2019 Miran Grca. - * Copyright 2008-2019 Sarah Walker. + * Copyright 2008-2019 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,6 +66,7 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/m_at_t3100e.h> +#include <86box/plat_unused.h> #define T3100E_XSIZE 640 #define T3100E_YSIZE 400 @@ -134,14 +135,14 @@ typedef struct t3100e_t { static video_timings_t timing_t3100e = { VIDEO_ISA, 8, 16, 32, 8, 16, 32 }; void t3100e_recalctimings(t3100e_t *t3100e); -void t3100e_write(uint32_t addr, uint8_t val, void *p); -uint8_t t3100e_read(uint32_t addr, void *p); +void t3100e_write(uint32_t addr, uint8_t val, void *priv); +uint8_t t3100e_read(uint32_t addr, void *priv); void t3100e_recalcattrs(t3100e_t *t3100e); void -t3100e_out(uint16_t addr, uint8_t val, void *p) +t3100e_out(uint16_t addr, uint8_t val, void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; switch (addr) { /* Emulated CRTC, register select */ case 0x3d0: @@ -168,21 +169,20 @@ t3100e_out(uint16_t addr, uint8_t val, void *p) t3100e_recalctimings(t3100e); return; - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t3100e->cga); - return; - /* CGA colour register */ - case 0x3D9: + case 0x3D8: /* CGA control register */ + case 0x3D9: /* CGA colour register */ cga_out(addr, val, &t3100e->cga); return; + + default: + break; } } uint8_t -t3100e_in(uint16_t addr, void *p) +t3100e_in(uint16_t addr, void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; uint8_t val; switch (addr) { @@ -196,24 +196,29 @@ t3100e_in(uint16_t addr, void *p) val |= 0x30; /* Plasma / CRT */ return val; } + break; + + default: + break; } return cga_in(addr, &t3100e->cga); } void -t3100e_write(uint32_t addr, uint8_t val, void *p) +t3100e_write(uint32_t addr, uint8_t val, void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; t3100e->vram[addr & 0x7fff] = val; cycles -= 4; } uint8_t -t3100e_read(uint32_t addr, void *p) +t3100e_read(uint32_t addr, void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + const t3100e_t *t3100e = (t3100e_t *) priv; + cycles -= 4; return t3100e->vram[addr & 0x7fff]; @@ -242,7 +247,6 @@ void t3100e_text_row80(t3100e_t *t3100e) { uint32_t cols[2]; - int c; uint8_t chr; uint8_t attr; int drawcursor; @@ -287,12 +291,12 @@ t3100e_text_row80(t3100e_t *t3100e) cols[0] = normcols[attr][0]; } if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + for (uint8_t c = 0; c < 8; c++) { + (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } } else { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + for (uint8_t c = 0; c < 8; c++) + (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; } @@ -349,11 +353,11 @@ t3100e_text_row40(t3100e_t *t3100e) } if (drawcursor) { for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t3100e->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } } else { for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t3100e->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; } } ++ma; @@ -386,8 +390,8 @@ t3100e_cgaline6(t3100e_t *t3100e) ink = (dat & 0x80) ? fg : bg; if (!(t3100e->cga.cgamode & 8)) ink = black; - ((uint32_t *) buffer32->line[t3100e->displine])[x * 8 + c] = ink; - dat = dat << 1; + (buffer32->line[t3100e->displine])[x * 8 + c] = ink; + dat = dat << 1; } } } @@ -445,18 +449,21 @@ t3100e_cgaline4(t3100e_t *t3100e) case 3: ink0 = ink1 = amber; break; + + default: + break; } - ((uint32_t *) buffer32->line[t3100e->displine])[x * 8 + 2 * c] = ink0; - ((uint32_t *) buffer32->line[t3100e->displine])[x * 8 + 2 * c + 1] = ink1; - dat = dat << 2; + (buffer32->line[t3100e->displine])[x * 8 + 2 * c] = ink0; + (buffer32->line[t3100e->displine])[x * 8 + 2 * c + 1] = ink1; + dat = dat << 2; } } } void -t3100e_poll(void *p) +t3100e_poll(void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; if (t3100e->video_options != st_video_options) { t3100e->video_options = st_video_options; @@ -646,7 +653,7 @@ t3100e_recalcattrs(t3100e_t *t3100e) } void * -t3100e_init(const device_t *info) +t3100e_init(UNUSED(const device_t *info)) { t3100e_t *t3100e = malloc(sizeof(t3100e_t)); memset(t3100e, 0, sizeof(t3100e_t)); @@ -680,18 +687,18 @@ t3100e_init(const device_t *info) } void -t3100e_close(void *p) +t3100e_close(void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; free(t3100e->vram); free(t3100e); } void -t3100e_speed_changed(void *p) +t3100e_speed_changed(void *priv) { - t3100e_t *t3100e = (t3100e_t *) p; + t3100e_t *t3100e = (t3100e_t *) priv; t3100e_recalctimings(t3100e); } diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index fb7919f268..a69b621848 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -50,11 +50,14 @@ #include <86box/rom.h> #include <86box/video.h> #include <86box/vid_cga.h> +#include <86box/hdc.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> static void -elt_vid_off_poll(void *p) +elt_vid_off_poll(void *priv) { - cga_t *cga = p; + cga_t *cga = priv; uint8_t hdisp = cga->crtc[1]; /* Don't display anything. @@ -65,9 +68,9 @@ elt_vid_off_poll(void *p) } static void -sysstat_out(uint16_t port, uint8_t val, void *p) +sysstat_out(UNUSED(uint16_t port), uint8_t val, void *priv) { - cga_t *cga = p; + cga_t *cga = priv; switch (val) { case 0: @@ -88,10 +91,10 @@ sysstat_out(uint16_t port, uint8_t val, void *p) } static uint8_t -sysstat_in(uint16_t port, void *p) +sysstat_in(UNUSED(uint16_t port), void *priv) { - cga_t *cga = p; - uint8_t ret = 0x0a; /* No idea what these bits are */ + const cga_t *cga = priv; + uint8_t ret = 0x0a; /* No idea what these bits are */ /* External CRT. We don't emulate the LCD/CRT switching, let's just * frivolously use this bit to indicate we're using the LCD if the @@ -103,9 +106,9 @@ sysstat_in(uint16_t port, void *p) } static void -elt_vid_out(uint16_t addr, uint8_t val, void *p) +elt_vid_out(uint16_t addr, uint8_t val, void *priv) { - cga_t *cga = p; + cga_t *cga = priv; /* The Equity LT chipset's CRTC contains more registers than the * regular CGA. The BIOS writes one of them, register 36 (0x24). @@ -122,22 +125,23 @@ elt_vid_out(uint16_t addr, uint8_t val, void *p) case 0x3d1: if (cga->crtcreg >= 32) return; - /* FALLTHROUGH */ + fallthrough; + default: cga->crtcreg &= 31; - cga_out(addr, val, p); + cga_out(addr, val, priv); } } static uint8_t -elt_vid_in(uint16_t addr, void *p) +elt_vid_in(uint16_t addr, void *priv) { - cga_t *cga = p; + cga_t *cga = priv; /* Just make sure we don't ever let regular CGA code run with crtcreg * pointing out of crtcregs[] bounds. */ cga->crtcreg &= 31; - return cga_in(addr, p); + return cga_in(addr, priv); } static void diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 615d6ff7b3..e541cf7183 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -104,6 +104,7 @@ #include <86box/hdc.h> #include <86box/video.h> #include <86box/machine.h> +#include <86box/plat_unused.h> #define EUROPC_DEBUG 0 /* current debugging level */ @@ -125,7 +126,7 @@ #define MRTC_CHECK_HI 0x0e /* Checksum, high byte */ #define MRTC_CTRLSTAT 0x0f /* RTC control/status, binary */ -typedef struct { +typedef struct europc_t { uint16_t jim; /* JIM base address */ uint8_t regs[16]; /* JIM internal regs (8) */ @@ -372,13 +373,17 @@ jim_set(europc_t *sys, uint8_t reg, uint8_t val) switch (val) { case 0x1f: /* 0001 1111 */ case 0x0b: /* 0000 1011 */ - // europc_jim.mode=AGA_MONO; +#if 0 + europc_jim.mode=AGA_MONO; +#endif europc_log("EuroPC: AGA Monochrome mode!\n"); break; case 0x18: /* 0001 1000 */ case 0x1a: /* 0001 1010 */ - // europc_jim.mode=AGA_COLOR; +#if 0 + europc_jim.mode=AGA_COLOR; +#endif break; case 0x0e: /* 0000 1100 */ @@ -392,7 +397,9 @@ jim_set(europc_t *sys, uint8_t reg, uint8_t val) break; default: - // europc_jim.mode=AGA_OFF; +#if 0 + europc_jim.mode=AGA_OFF; +#endif break; } break; @@ -400,15 +407,21 @@ jim_set(europc_t *sys, uint8_t reg, uint8_t val) case 4: /* CPU Speed control */ switch (val & 0xc0) { case 0x00: /* 4.77 MHz */ - // cpu_set_clockscale(0, 1.0/2); +#if 0 + cpu_set_clockscale(0, 1.0/2); +#endif break; case 0x40: /* 7.16 MHz */ - // cpu_set_clockscale(0, 3.0/4); +#if 0 + cpu_set_clockscale(0, 3.0/4); +#endif break; default: /* 9.54 MHz */ - // cpu_set_clockscale(0, 1);break; +#if 0 + cpu_set_clockscale(0, 1);break; +#endif break; } break; @@ -465,6 +478,9 @@ jim_write(uint16_t addr, uint8_t val, void *priv) sys->nvr_stat = 0; nvr_dosave++; break; + + default: + break; } break; @@ -511,6 +527,9 @@ jim_read(uint16_t addr, void *priv) r = (sys->nvr.regs[sys->nvr_addr] & 0x0f); sys->nvr_stat = 0; break; + + default: + break; } break; @@ -528,7 +547,7 @@ jim_read(uint16_t addr, void *priv) /* Initialize the mainboard 'device' of the machine. */ static void * -europc_boot(const device_t *info) +europc_boot(UNUSED(const device_t *info)) { europc_t *sys = &europc; uint8_t b; @@ -573,6 +592,9 @@ europc_boot(const device_t *info) case 640: b |= 0x00; break; + + default: + break; } sys->nvr.regs[MRTC_CONF_C] = b; @@ -590,6 +612,9 @@ europc_boot(const device_t *info) case 2: /* 8088, 9.56 MHz */ b |= 0x80; break; + + default: + break; } sys->nvr.regs[MRTC_CONF_D] = b; @@ -642,7 +667,7 @@ europc_boot(const device_t *info) } static void -europc_close(void *priv) +europc_close(UNUSED(void *priv)) { nvr_t *nvr = &europc.nvr; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index c2163746b5..80a0ffbc11 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -49,6 +49,7 @@ #include <86box/video.h> #include <86box/vid_cga_comp.h> #include <86box/machine.h> +#include <86box/plat_unused.h> #define PCJR_RGB 0 #define PCJR_COMPOSITE 1 @@ -62,7 +63,7 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -typedef struct { +typedef struct pcjr_t { /* Video Controller stuff. */ mem_mapping_t mapping; uint8_t crtc[32]; @@ -73,20 +74,28 @@ typedef struct { int memctrl; uint8_t stat; int addr_mode; - uint8_t *vram, - *b8000; - int linepos, displine; - int sc, vc; - int dispon; - int con, coff, cursoron, blink; - int vsynctime; - int fullchange; - int vadj; - uint16_t ma, maback; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - int firstline, lastline; - int composite; + uint8_t *vram; + uint8_t *b8000; + int linepos; + int displine; + int sc; + int vc; + int dispon; + int con; + int coff; + int cursoron; + int blink; + int vsynctime; + int fullchange; + int vadj; + uint16_t ma; + uint16_t maback; + uint64_t dispontime; + uint64_t dispofftime; + pc_timer_t timer; + int firstline; + int lastline; + int composite; /* Keyboard Controller stuff. */ int latched; @@ -113,12 +122,20 @@ static int key_queue_end = 0; static void recalc_address(pcjr_t *pcjr) { + uint8_t masked_memctrl = pcjr->memctrl; + + /* According to the Technical Reference, bits 2 and 5 are + ignored if there is only 64k of RAM and there are only + 4 pages. */ + if (mem_size < 128) + masked_memctrl &= ~0x24; + if ((pcjr->memctrl & 0xc0) == 0xc0) { - pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11]; + pcjr->vram = &ram[(masked_memctrl & 0x06) << 14]; + pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11]; } else { - pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11]; + pcjr->vram = &ram[(masked_memctrl & 0x07) << 14]; + pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11]; } } @@ -145,17 +162,23 @@ recalc_timings(pcjr_t *pcjr) } static void -vid_out(uint16_t addr, uint8_t val, void *p) +vid_out(uint16_t addr, uint8_t val, void *priv) { - pcjr_t *pcjr = (pcjr_t *) p; + pcjr_t *pcjr = (pcjr_t *) priv; uint8_t old; switch (addr) { + case 0x3d0: + case 0x3d2: case 0x3d4: + case 0x3d6: pcjr->crtcreg = val & 0x1f; return; + case 0x3d1: + case 0x3d3: case 0x3d5: + case 0x3d7: old = pcjr->crtc[pcjr->crtcreg]; pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; if (old != val) { @@ -181,24 +204,37 @@ vid_out(uint16_t addr, uint8_t val, void *p) case 0x3df: pcjr->memctrl = val; + pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to + then be readable from port 60, others it errors out + with only 64k RAM set (but somehow, still works with + 128k or more RAM). */ pcjr->addr_mode = val >> 6; recalc_address(pcjr); break; + + default: + break; } } static uint8_t -vid_in(uint16_t addr, void *p) +vid_in(uint16_t addr, void *priv) { - pcjr_t *pcjr = (pcjr_t *) p; + pcjr_t *pcjr = (pcjr_t *) priv; uint8_t ret = 0xff; switch (addr) { + case 0x3d0: + case 0x3d2: case 0x3d4: + case 0x3d6: ret = pcjr->crtcreg; break; + case 0x3d1: + case 0x3d3: case 0x3d5: + case 0x3d7: ret = pcjr->crtc[pcjr->crtcreg]; break; @@ -207,15 +243,18 @@ vid_in(uint16_t addr, void *p) pcjr->stat ^= 0x10; ret = pcjr->stat; break; + + default: + break; } return ret; } static void -vid_write(uint32_t addr, uint8_t val, void *p) +vid_write(uint32_t addr, uint8_t val, void *priv) { - pcjr_t *pcjr = (pcjr_t *) p; + pcjr_t *pcjr = (pcjr_t *) priv; if (pcjr->memctrl == -1) return; @@ -224,9 +263,9 @@ vid_write(uint32_t addr, uint8_t val, void *p) } static uint8_t -vid_read(uint32_t addr, void *p) +vid_read(uint32_t addr, void *priv) { - pcjr_t *pcjr = (pcjr_t *) p; + const pcjr_t *pcjr = (pcjr_t *) priv; if (pcjr->memctrl == -1) return 0xff; @@ -235,13 +274,12 @@ vid_read(uint32_t addr, void *p) } static void -vid_poll(void *p) +vid_poll(void *priv) { - pcjr_t *pcjr = (pcjr_t *) p; + pcjr_t *pcjr = (pcjr_t *) priv; uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff; int drawcursor; int x; - int c; int xs_temp; int ys_temp; int oldvc; @@ -268,8 +306,8 @@ vid_poll(void *p) } pcjr->lastline = pcjr->displine; cols[0] = (pcjr->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[pcjr->displine])[c] = cols[0]; + for (uint8_t c = 0; c < 8; c++) { + (buffer32->line[pcjr->displine])[c] = cols[0]; if (pcjr->array[0] & 1) { buffer32->line[pcjr->displine << 1][c + (pcjr->crtc[1] << 3) + 8] = buffer32->line[(pcjr->displine << 1) + 1][c + (pcjr->crtc[1] << 3) + 8] = cols[0]; } else { @@ -288,6 +326,9 @@ vid_poll(void *p) case 3: /*High resolution graphics*/ offset = (pcjr->sc & 3) * 0x2000; break; + + default: + break; } switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { case 0x13: /*320x200x16*/ @@ -314,7 +355,7 @@ vid_poll(void *p) for (x = 0; x < pcjr->crtc[1]; x++) { dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; pcjr->ma++; - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { chr = (dat >> 7) & 1; chr |= ((dat >> 14) & 2); buffer32->line[pcjr->displine << 1][(x << 3) + 8 + c] = buffer32->line[(pcjr->displine << 1) + 1][(x << 3) + 8 + c] = pcjr->array[(chr & pcjr->array[1]) + 16] + 16; @@ -337,16 +378,16 @@ vid_poll(void *p) cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; } if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { buffer32->line[pcjr->displine << 1][(x << 3) + c + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 3) + c + 8] = cols[0]; } } else { - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { buffer32->line[pcjr->displine << 1][(x << 3) + c + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } if (drawcursor) { - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { buffer32->line[pcjr->displine << 1][(x << 3) + c + 8] ^= 15; buffer32->line[(pcjr->displine << 1) + 1][(x << 3) + c + 8] ^= 15; } @@ -370,17 +411,17 @@ vid_poll(void *p) } pcjr->ma++; if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) { - buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[0]; + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[0]; } } else { - for (c = 0; c < 8; c++) { - buffer32->line[(pcjr->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } if (drawcursor) { - for (c = 0; c < 16; c++) { - buffer32->line[(pcjr->displine << 1)][(x << 4) + c + 8] ^= 15; + for (uint8_t c = 0; c < 16; c++) { + buffer32->line[pcjr->displine << 1][(x << 4) + c + 8] ^= 15; buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + c + 8] ^= 15; } } @@ -394,8 +435,8 @@ vid_poll(void *p) for (x = 0; x < pcjr->crtc[1]; x++) { dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; pcjr->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[(pcjr->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[pcjr->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } @@ -406,12 +447,15 @@ vid_poll(void *p) for (x = 0; x < pcjr->crtc[1]; x++) { dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; pcjr->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[(pcjr->displine << 1)][(x << 4) + c + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; + for (uint8_t c = 0; c < 16; c++) { + buffer32->line[pcjr->displine << 1][(x << 4) + c + 8] = buffer32->line[(pcjr->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } break; + + default: + break; } } else { if (pcjr->array[3] & 4) { @@ -438,7 +482,7 @@ vid_poll(void *p) else x = (pcjr->crtc[1] << 4) + 16; if (pcjr->composite) { - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[(pcjr->displine << 1)]); + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine << 1]); Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[(pcjr->displine << 1) + 1]); } else { video_process_8(x, pcjr->displine << 1); @@ -550,7 +594,7 @@ vid_poll(void *p) pcjr->sc &= 31; pcjr->ma = pcjr->maback; } - if ((pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1)))) + if (pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1))) pcjr->con = 1; } } @@ -571,8 +615,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x61: pcjr->pb = val; - timer_process(); - if (cassette != NULL) pc_cas_set_motor(cassette, (pcjr->pb & 0x08) == 0); @@ -591,6 +633,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x60: sn76489_mute = 0; break; + + default: + break; } break; @@ -598,6 +643,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) nmi_mask = val & 0x80; pit_devs[0].set_using_timer(pit_devs[0].data, 1, !(val & 0x20)); break; + + default: + break; } } @@ -621,7 +669,9 @@ kbd_read(uint16_t port, void *priv) case 0x62: ret = (pcjr->latched ? 1 : 0); - ret |= 0x02; /*Modem card not installed*/ + ret |= 0x02; /* Modem card not installed */ + if (mem_size < 128) + ret |= 0x08; /* 64k expansion card not installed */ if ((pcjr->pb & 0x08) || (cassette == NULL)) ret |= (ppispeakon ? 0x10 : 0); else @@ -637,6 +687,9 @@ kbd_read(uint16_t port, void *priv) pcjr->latched = 0; ret = 0; break; + + default: + break; } return ret; @@ -765,7 +818,7 @@ const device_t pcjr_device = { }; int -machine_pcjr_init(const machine_t *model) +machine_pcjr_init(UNUSED(const machine_t *model)) { int display_type; pcjr_t *pcjr; @@ -781,6 +834,8 @@ machine_pcjr_init(const machine_t *model) pcjr = malloc(sizeof(pcjr_t)); memset(pcjr, 0x00, sizeof(pcjr_t)); pcjr->memctrl = -1; + if (mem_size < 128) + pcjr->memctrl &= ~0x24; display_type = machine_get_config_int("display_type"); pcjr->composite = (display_type != PCJR_RGB); @@ -824,7 +879,10 @@ machine_pcjr_init(const machine_t *model) device_add(&ns8250_pcjr_device); serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ - /* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 */ + /* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 + + Note by Miran Grca: Meanwhile, the same Technical Reference clearly says that + the gameport is on ports 201-207. */ standalone_gameport_type = &gameport_201_device; return ret; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index e3675e74b8..e0a15126ee 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -63,6 +63,7 @@ #include <86box/video.h> #include <86box/machine.h> #include <86box/sound.h> +#include <86box/plat_unused.h> typedef struct { int model; @@ -153,6 +154,9 @@ ps1_write(uint16_t port, uint8_t val, void *priv) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps->ps1_102 = val; @@ -174,6 +178,9 @@ ps1_write(uint16_t port, uint8_t val, void *priv) case 0x0190: ps->ps1_190 = val; break; + + default: + break; } } @@ -236,6 +243,56 @@ ps1_read(uint16_t port, void *priv) return ret; } +static const device_config_t ps1_2011_config[] = { + // clang-format off + { + .name = "bios_language", + .description = "BIOS Language", + .type = CONFIG_BIOS, + .default_string = "english_us", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "English (US)", .internal_name = "english_us", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/FC0000_US.BIN", "" } }, + { .name = "English (UK)", .internal_name = "english_uk", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_UK.BIN", "roms/machines/ibmps1es/FC0000_UK.BIN", "" } }, + { .name = "English (Canada)", .internal_name = "english_ca", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_CA.BIN", "roms/machines/ibmps1es/FC0000_CA.BIN", "" } }, + { .name = "Portuguese", .internal_name = "portuguese", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_PT.BIN", "roms/machines/ibmps1es/FC0000_PT.BIN", "" } }, + { .name = "German", .internal_name = "german", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_DE.BIN", "roms/machines/ibmps1es/FC0000_DE.BIN", "" } }, + { .name = "Swedish", .internal_name = "swedish", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_SE.BIN", "roms/machines/ibmps1es/FC0000_SE.BIN", "" } }, + { .name = "French", .internal_name = "french", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/F80000_FR.BIN", "roms/machines/ibmps1es/FC0000_FR.BIN", "" } }, + { .name = "Italian", .internal_name = "italian", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 524288, .files = { "roms/machines/ibmps1es/f80000.bin", "" } }, + { .name = "Spanish", .internal_name = "spanish", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 524288, .files = { "roms/machines/ibmps1es/F80000_ES.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ps1_2011_device = { + .name = "PS/1 2011", + .internal_name = "ps/1_2011", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = &ps1_2011_config[0] +}; + static void ps1_setup(int model) { @@ -267,9 +324,27 @@ ps1_setup(int model) device_add(&ps_nvr_device); if (model == 2011) { - rom_init(&ps->high_rom, - "roms/machines/ibmps1es/f80000.bin", - 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + if (!strcmp("english_us", device_get_config_bios("bios_language"))) { + /* US English */ + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + + } else if ((device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1)) == NULL) { + /* Combined ROM. */ + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + } else { + /* Split ROM. */ + rom_init(&ps->mid_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 0), + 0xf80000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + + rom_init(&ps->high_rom, + device_get_bios_file(device_context_get_device(), device_get_config_bios("bios_language"), 1), + 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + } lpt2_remove(); @@ -333,16 +408,43 @@ int machine_ps1_m2011_init(const machine_t *model) { int ret; + const char* fn; + uint32_t offset; - ret = bios_load_linear("roms/machines/ibmps1es/f80000.bin", - 0x000e0000, 131072, 0x60000); + if (!device_available(model->device)) { + /* No ROMs available. */ + return 0; + } - if (bios_only || !ret) + device_context(model->device); + if ((fn = device_get_bios_file(model->device, device_get_config_bios("bios_language"), 1)) == NULL) { + /* Combined ROM or US English. */ + fn = device_get_bios_file(model->device, device_get_config_bios("bios_language"), 0); + offset = (!strcmp("english_us", device_get_config_bios("bios_language"))) ? 0x20000 : 0x60000; + } else { + /* Separated ROM. */ + offset = 0x20000; + } + + if (!fn) { + fn = device_get_bios_file(model->device, "us_english", 0); + offset = 0x20000; + } + + ret = bios_load_linear(fn, 0x000e0000, 131072, offset); + device_context_restore(); + + if (bios_only || !ret) { return ret; + } ps1_common_init(model); - ps1_setup(2011); + device_context(model->device); + + ps1_setup(2011); + + device_context_restore(); return ret; } diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index bd0c8851df..f35879458b 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -99,7 +99,7 @@ #include <86box/ui.h> #include <86box/machine.h> -#define HDC_TIME (50 * TIMER_USEC) +#define HDC_TIME (250 * TIMER_USEC) #define HDC_TYPE_USER 47 /* user drive type */ enum { @@ -161,54 +161,54 @@ enum { * block is transferred. */ #pragma pack(push, 1) -typedef struct { +typedef struct ssb_t { /* Status byte 0. */ - uint8_t track_0 : 1, /* T0 */ - mbz1 : 1, /* 0 */ - mbz2 : 1, /* 0 */ - cylinder_err : 1, /* CE */ - write_fault : 1, /* WF */ - mbz3 : 1, /* 0 */ - seek_end : 1, /* SE */ - not_ready : 1; /* NR */ + uint8_t track_0 : 1; /* T0 */ + uint8_t mbz1 : 1; /* 0 */ + uint8_t mbz2 : 1; /* 0 */ + uint8_t cylinder_err : 1; /* CE */ + uint8_t write_fault : 1; /* WF */ + uint8_t mbz3 : 1; /* 0 */ + uint8_t seek_end : 1; /* SE */ + uint8_t not_ready : 1; /* NR */ /* Status byte 1. */ - uint8_t id_not_found : 1, /* ID */ - mbz4 : 1, /* 0 */ - mbz5 : 1, /* 0 */ - wrong_cyl : 1, /* WC */ - all_bit_set : 1, /* BT */ - mark_not_found : 1, /* AM */ - ecc_crc_err : 1, /* ET */ - ecc_crc_field : 1; /* EF */ + uint8_t id_not_found : 1; /* ID */ + uint8_t mbz4 : 1; /* 0 */ + uint8_t mbz5 : 1; /* 0 */ + uint8_t wrong_cyl : 1; /* WC */ + uint8_t all_bit_set : 1; /* BT */ + uint8_t mark_not_found : 1; /* AM */ + uint8_t ecc_crc_err : 1; /* ET */ + uint8_t ecc_crc_field : 1; /* EF */ /* Status byte 2. */ - uint8_t headsel_state : 4, /* headsel state[4] */ - defective_sector : 1, /* DS */ - retried_ok : 1, /* RG */ - need_reset : 1, /* RR */ + uint8_t headsel_state : 4; /* headsel state[4] */ + uint8_t defective_sector : 1; /* DS */ + uint8_t retried_ok : 1; /* RG */ + uint8_t need_reset : 1; /* RR */ #if 1 - valid : 1; /* 0 (abused as VALID) */ + uint8_t valid : 1; /* 0 (abused as VALID) */ #else - mbz6 : 1; /* 0 */ + uint8_t mbz6 : 1; /* 0 */ #endif /* Most recent ID field seen. */ - uint8_t last_cyl_low; /* Cyl_Low[8] */ - uint8_t last_head : 4, /* HD[4] */ - mbz7 : 1, /* 0 */ - last_cyl_high : 2, /* Cyl_high[2] */ - last_def_sect : 1; /* DS */ - uint8_t last_sect; /* Sect[8] */ + uint8_t last_cyl_low; /* Cyl_Low[8] */ + uint8_t last_head : 4; /* HD[4] */ + uint8_t mbz7 : 1; /* 0 */ + uint8_t last_cyl_high : 2; /* Cyl_high[2] */ + uint8_t last_def_sect : 1; /* DS */ + uint8_t last_sect; /* Sect[8] */ uint8_t sect_size; /* Size[8] = 02 */ /* Current position. */ - uint8_t curr_cyl_high : 2, /* Cyl_High_[2] */ - mbz8 : 1, /* 0 */ - mbz9 : 1, /* 0 */ - curr_head : 4; /* HD_2[4] */ - uint8_t curr_cyl_low; /* Cyl_Low_2[8] */ + uint8_t curr_cyl_high : 2; /* Cyl_High_[2] */ + uint8_t mbz8 : 1; /* 0 */ + uint8_t mbz9 : 1; /* 0 */ + uint8_t curr_head : 4; /* HD_2[4] */ + uint8_t curr_cyl_low; /* Cyl_Low_2[8] */ uint8_t sect_corr; /* sectors corrected */ @@ -290,21 +290,21 @@ typedef struct { * bits 0. */ #pragma pack(push, 1) -typedef struct { - uint8_t cyl_high : 2, /* cylinder [9:8] bits */ - defective_sector : 1, /* DS */ - mbz1 : 1, /* 0 */ - head : 4; /* head number */ +typedef struct fcb_t { + uint8_t cyl_high : 2; /* cylinder [9:8] bits */ + uint8_t defective_sector : 1; /* DS */ + uint8_t mbz1 : 1; /* 0 */ + uint8_t head : 4; /* head number */ - uint8_t cyl_low; /* cylinder [7:0] bits */ + uint8_t cyl_low; /* cylinder [7:0] bits */ - uint8_t sector; /* sector number */ + uint8_t sector; /* sector number */ - uint8_t mbz2 : 1, /* 0 */ - mbo : 1, /* 1 */ - mbz3 : 6; /* 000000 */ + uint8_t mbz2 : 1; /* 0 */ + uint8_t mbo : 1; /* 1 */ + uint8_t mbz3 : 6; /* 000000 */ - uint8_t fill; /* filler byte */ + uint8_t fill; /* filler byte */ } fcb_t; #pragma pack(pop) @@ -316,31 +316,31 @@ typedef struct { * through a DMA or PIO operation. */ #pragma pack(push, 1) -typedef struct { - uint8_t ec_p : 1, /* EC/P (ecc/park) */ - mbz1 : 1, /* 0 */ - auto_seek : 1, /* AS (auto-seek) */ - no_data : 1, /* ND (no data) */ - cmd : 4; /* command code[4] */ +typedef struct ccb_t{ + uint8_t ec_p : 1; /* EC/P (ecc/park) */ + uint8_t mbz1 : 1; /* 0 */ + uint8_t auto_seek : 1; /* AS (auto-seek) */ + uint8_t no_data : 1; /* ND (no data) */ + uint8_t cmd : 4; /* command code[4] */ - uint8_t cyl_high : 2, /* cylinder [9:8] bits */ - mbz2 : 2, /* 00 */ - head : 4; /* head number */ + uint8_t cyl_high : 2; /* cylinder [9:8] bits */ + uint8_t mbz2 : 2; /* 00 */ + uint8_t head : 4; /* head number */ uint8_t cyl_low; /* cylinder [7:0] bits */ uint8_t sector; /* sector number */ - uint8_t mbz3 : 1, /* 0 */ - mbo1 : 1, /* 1 */ - mbz4 : 6; /* 000000 */ + uint8_t mbz3 : 1; /* 0 */ + uint8_t mbo1 : 1; /* 1 */ + uint8_t mbz4 : 6; /* 000000 */ uint8_t count; /* blk count/interleave */ } ccb_t; #pragma pack(pop) /* Define the hard drive geometry table. */ -typedef struct { +typedef struct geom_t { uint16_t cyl; uint8_t hpc; uint8_t spt; @@ -349,54 +349,53 @@ typedef struct { } geom_t; /* Define an attached drive. */ -typedef struct { - int8_t id, /* drive ID on bus */ - present, /* drive is present */ - hdd_num, /* index to global disk table */ - type; /* drive type ID */ +typedef struct drive_t { + int8_t id; /* drive ID on bus */ + int8_t present; /* drive is present */ + int8_t hdd_num; /* index to global disk table */ + int8_t type; /* drive type ID */ uint16_t cur_cyl; /* last known position of heads */ - uint8_t spt, /* active drive parameters */ - hpc; + uint8_t spt; /* active drive parameters */ + uint8_t hpc; uint16_t tracks; - uint8_t cfg_spt, /* configured drive parameters */ - cfg_hpc; + uint8_t cfg_spt; /* configured drive parameters */ + uint8_t cfg_hpc; uint16_t cfg_tracks; } drive_t; -typedef struct { +typedef struct hdc_t { uint16_t base; /* controller base I/O address */ int8_t irq; /* controller IRQ channel */ int8_t dma; /* controller DMA channel */ /* Registers. */ - uint8_t attn, /* ATTENTION register */ - ctrl, /* Control register (ACR) */ - status, /* Status register (ASR) */ - intstat; /* Interrupt Status register (ISR) */ + uint8_t attn; /* ATTENTION register */ + uint8_t ctrl; /* Control register (ACR) */ + uint8_t status; /* Status register (ASR) */ + uint8_t intstat; /* Interrupt Status register (ISR) */ uint8_t *reg_91; /* handle to system board's register 0x91 */ /* Controller state. */ - uint64_t callback; pc_timer_t timer; - int8_t state, /* controller state */ - reset; /* reset state counter */ + int8_t state; /* controller state */ + int8_t reset; /* reset state counter */ /* Data transfer. */ - int16_t buf_idx, /* buffer index and pointer */ - buf_len; + int16_t buf_idx; /* buffer index and pointer */ + int16_t buf_len; uint8_t *buf_ptr; /* Current operation parameters. */ - ssb_t ssb; /* sense block */ - ccb_t ccb; /* command control block */ - uint16_t track; /* requested track# */ - uint8_t head, /* requested head# */ - sector; /* requested sector# */ - int count; /* requested sector count */ + ssb_t ssb; /* sense block */ + ccb_t ccb; /* command control block */ + uint16_t track; /* requested track# */ + uint8_t head; /* requested head# */ + uint8_t sector; /* requested sector# */ + int count; /* requested sector count */ drive_t drives[XTA_NUM]; /* the attached drive(s) */ @@ -463,6 +462,7 @@ static const geom_t ibm_type_table[] = { // clang-format on }; +#define ENABLE_PS1_HDC_LOG 1 #ifdef ENABLE_PS1_HDC_LOG int ps1_hdc_do_log = ENABLE_PS1_HDC_LOG; @@ -481,22 +481,6 @@ ps1_hdc_log(const char *fmt, ...) # define ps1_hdc_log(fmt, ...) #endif -static void -hdc_set_callback(hdc_t *dev, uint64_t callback) -{ - if (!dev) { - return; - } - - if (callback) { - dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_disable(&dev->timer); - } -} - /* FIXME: we should use the disk/hdd_table.c code with custom tables! */ static int ibm_drive_type(drive_t *drive) @@ -602,8 +586,10 @@ do_seek(hdc_t *dev, drive_t *drive, uint16_t cyl) static void do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) { - int start_cyl, end_cyl; - int intr = 0, val; + int start_cyl; + int end_cyl; + int intr = 0; + int val; off64_t addr; #if 0 fcb_t *fcb; @@ -631,7 +617,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) /* Enable for PIO or DMA, as needed. */ #if NOT_USED if (dev->ctrl & ACR_DMA_EN) - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); else #endif dev->status |= ASR_DATA_REQ; @@ -651,7 +637,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) dev->buf_idx++; } dev->state = STATE_RDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_RDONE: @@ -663,7 +649,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) fcb = (fcb_t *)dev->data; #endif dev->state = STATE_FINIT; - /*FALLTHROUGH*/ + fallthrough; case STATE_FINIT: do_fmt: @@ -697,8 +683,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) /* Done with this track. */ dev->state = STATE_FDONE; - /*FALLTHROUGH*/ - + fallthrough; case STATE_FDONE: /* One more track done. */ if (++start_cyl == end_cyl) { @@ -712,6 +697,9 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) /* This saves us a LOT of code. */ dev->state = STATE_FINIT; goto do_fmt; + + default: + break; } /* If we errored out, go back idle. */ @@ -733,9 +721,7 @@ hdc_callback(void *priv) off64_t addr; int no_data = 0; int val; - - /* Cancel timer. */ - dev->callback = 0; + uint8_t cmd = ccb->cmd & 0x0f; /* Clear the SSB error bits. */ dev->ssb.track_0 = 0; @@ -754,10 +740,12 @@ hdc_callback(void *priv) /* We really only support one drive, but ohwell. */ drive = &dev->drives[0]; + ps1_hdc_log("hdc_callback(): %02X\n", cmd); + switch (ccb->cmd) { case CMD_READ_VERIFY: no_data = 1; - /*FALLTHROUGH*/ + fallthrough; case CMD_READ_SECTORS: if (!drive->present) { @@ -784,7 +772,7 @@ hdc_callback(void *priv) dev->buf_len = (128 << dev->ssb.sect_size); dev->state = STATE_SEND; - /*FALLTHROUGH*/ + fallthrough; case STATE_SEND: /* Activate the status icon. */ @@ -808,12 +796,12 @@ hdc_callback(void *priv) dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->ctrl & ACR_DMA_EN) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->status |= (ASR_DATA_REQ | ASR_DIR); @@ -848,7 +836,7 @@ hdc_callback(void *priv) } } dev->state = STATE_SDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_SDONE: @@ -870,10 +858,12 @@ hdc_callback(void *priv) /* This saves us a LOT of code. */ dev->state = STATE_SEND; goto do_send; + + default: + break; } break; - case CMD_READ_EXT: /* READ_EXT */ case CMD_READ_ID: /* READ_ID */ if (!drive->present) { dev->ssb.not_ready = 1; @@ -881,6 +871,56 @@ hdc_callback(void *priv) return; } + switch (dev->state) { + case STATE_IDLE: + /* Seek to cylinder if requested. */ + if (ccb->auto_seek) { + if (do_seek(dev, drive, + (ccb->cyl_low | (ccb->cyl_high << 8)))) { + do_finish(dev); + return; + } + } + dev->head = ccb->head; + + /* Get sector count and size. */ + dev->count = (int) ccb->count; + dev->buf_len = (128 << dev->ssb.sect_size); + + /* Activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1); + + /* Ready to transfer the data out. */ + dev->state = STATE_SDONE; + dev->buf_idx = 0; + /* Delay a bit, no actual transfer. */ + timer_advance_u64(&dev->timer, HDC_TIME); + break; + + case STATE_SDONE: + dev->buf_idx = 0; + + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); + + if (!(dev->ctrl & ACR_DMA_EN)) + dev->status &= ~(ASR_DATA_REQ | ASR_DIR); + dev->ssb.cmd_syndrome = 0x14; + do_finish(dev); + break; + + default: + break; + } + break; + + case CMD_READ_EXT: /* READ_EXT */ + if (!drive->present) { + dev->ssb.not_ready = 1; + do_finish(dev); + return; + } + dev->intstat |= ISR_INVALID_CMD; do_finish(dev); break; @@ -898,7 +938,7 @@ hdc_callback(void *priv) case CMD_WRITE_VERIFY: no_data = 1; - /*FALLTHROUGH*/ + fallthrough; case CMD_WRITE_SECTORS: if (!drive->present) { @@ -925,7 +965,7 @@ hdc_callback(void *priv) dev->buf_len = (128 << dev->ssb.sect_size); dev->state = STATE_RECV; - /*FALLTHROUGH*/ + fallthrough; case STATE_RECV: /* Activate the status icon. */ @@ -936,12 +976,12 @@ hdc_callback(void *priv) dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->ctrl & ACR_DMA_EN) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->buf_ptr = dev->data; @@ -971,7 +1011,7 @@ hdc_callback(void *priv) } } dev->state = STATE_RDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_RDONE: @@ -1012,6 +1052,9 @@ hdc_callback(void *priv) /* This saves us a LOT of code. */ dev->state = STATE_RECV; goto do_recv; + + default: + break; } break; @@ -1050,7 +1093,7 @@ hdc_callback(void *priv) static void hdc_send_ssb(hdc_t *dev) { - drive_t *drive; + const drive_t *drive; /* We only support one drive, really, but ohwell. */ drive = &dev->drives[0]; @@ -1125,8 +1168,13 @@ hdc_read(uint16_t port, void *priv) ret = dev->intstat; dev->intstat = 0x00; break; + + default: + break; } + ps1_hdc_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + return ret; } @@ -1135,6 +1183,8 @@ hdc_write(uint16_t port, uint8_t val, void *priv) { hdc_t *dev = (hdc_t *) priv; + ps1_hdc_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + /* TRM: tell system board we are alive. */ *dev->reg_91 |= 0x01; @@ -1151,6 +1201,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) /* Store the data into the buffer. */ dev->buf_ptr[dev->buf_idx] = val; + ps1_hdc_log("dev->buf_ptr[%02X] = %02X\n", dev->buf_idx, val); if (++dev->buf_idx == dev->buf_len) { /* We got all the data we need. */ dev->status &= ~ASR_DATA_REQ; @@ -1169,7 +1220,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) dev->status |= ASR_BUSY; /* Schedule command execution. */ - hdc_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } } @@ -1231,11 +1282,14 @@ hdc_write(uint16_t port, uint8_t val, void *priv) set_intr(dev, 1); } break; + + default: + break; } } static void * -ps1_hdc_init(const device_t *info) +ps1_hdc_init(UNUSED(const device_t *info)) { drive_t *drive; hdc_t *dev; @@ -1304,8 +1358,8 @@ ps1_hdc_init(const device_t *info) static void ps1_hdc_close(void *priv) { - hdc_t *dev = (hdc_t *) priv; - drive_t *drive; + hdc_t *dev = (hdc_t *) priv; + const drive_t *drive; /* Remove the I/O handler. */ io_removehandler(dev->base, 5, diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index af4fc58493..fa9c5acc2e 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -72,6 +72,9 @@ ps2_write(uint16_t port, uint8_t val, void *priv) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps2->ps2_102 = val; @@ -93,6 +96,9 @@ ps2_write(uint16_t port, uint8_t val, void *priv) case 0x0190: ps2->ps2_190 = val; break; + + default: + break; } } @@ -131,6 +137,9 @@ ps2_read(uint16_t port, void *priv) case 0x0190: temp = ps2->ps2_190; break; + + default: + break; } return temp; diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index c43f7ef9b6..a6fc30e1cf 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -68,15 +68,16 @@ #include <86box/serial.h> #include <86box/video.h> #include <86box/machine.h> +#include <86box/plat_unused.h> -static struct -{ +static struct ps2_t { uint8_t adapter_setup; uint8_t option[4]; uint8_t pos_vga; uint8_t setup; uint8_t sys_ctrl_port_a; - uint8_t subaddr_lo, subaddr_hi; + uint8_t subaddr_lo; + uint8_t subaddr_hi; uint8_t memory_bank[8]; @@ -88,11 +89,12 @@ static struct mem_mapping_t cache_mapping; uint8_t (*planar_read)(uint16_t port); - void (*planar_write)(uint16_t port, uint8_t val); + void (*planar_write)(uint16_t port, uint8_t val); uint8_t mem_regs[3]; - uint32_t split_addr, split_size; + uint32_t split_addr; + uint32_t split_size; uint32_t split_phys; uint8_t mem_pos_regs[8]; @@ -158,7 +160,7 @@ ps2_mca_log(const char *fmt, ...) #endif static uint8_t -ps2_read_cache_ram(uint32_t addr, void *priv) +ps2_read_cache_ram(uint32_t addr, UNUSED(void *priv)) { ps2_mca_log("ps2_read_cache_ram: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS, cpu_state.pc); if (!ps2_cache_valid[addr >> 3]) { @@ -170,7 +172,7 @@ ps2_read_cache_ram(uint32_t addr, void *priv) return ps2_cache[addr]; } static uint16_t -ps2_read_cache_ramw(uint32_t addr, void *priv) +ps2_read_cache_ramw(uint32_t addr, UNUSED(void *priv)) { ps2_mca_log("ps2_read_cache_ramw: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS, cpu_state.pc); if (!ps2_cache_valid[addr >> 3]) { @@ -182,7 +184,7 @@ ps2_read_cache_ramw(uint32_t addr, void *priv) return *(uint16_t *) &ps2_cache[addr]; } static uint32_t -ps2_read_cache_raml(uint32_t addr, void *priv) +ps2_read_cache_raml(uint32_t addr, UNUSED(void *priv)) { ps2_mca_log("ps2_read_cache_raml: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS, cpu_state.pc); if (!ps2_cache_valid[addr >> 3]) { @@ -194,7 +196,7 @@ ps2_read_cache_raml(uint32_t addr, void *priv) return *(uint32_t *) &ps2_cache[addr]; } static void -ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv) +ps2_write_cache_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) { ps2_mca_log("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS, cpu_state.pc); ps2_cache[addr] = val; @@ -268,6 +270,9 @@ model_50_read(uint16_t port) return ps2.subaddr_lo; case 0x107: return ps2.subaddr_hi; + + default: + break; } return 0xff; } @@ -292,6 +297,9 @@ model_55sx_read(uint16_t port) return ps2.subaddr_lo; case 0x107: return ps2.subaddr_hi; + + default: + break; } return 0xff; } @@ -316,6 +324,9 @@ model_70_type3_read(uint16_t port) return ps2.subaddr_lo; case 0x107: return ps2.subaddr_hi; + + default: + break; } return 0xff; } @@ -340,6 +351,9 @@ model_80_read(uint16_t port) return ps2.subaddr_lo; case 0x107: return ps2.subaddr_hi; + + default: + break; } return 0xff; } @@ -348,11 +362,6 @@ static void model_50_write(uint16_t port, uint8_t val) { switch (port) { - case 0x100: - ps2.io_id = val; - break; - case 0x101: - break; case 0x102: lpt1_remove(); serial_remove(ps2.uart); @@ -373,6 +382,9 @@ model_50_write(uint16_t port, uint8_t val) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps2.option[0] = val; @@ -392,6 +404,9 @@ model_50_write(uint16_t port, uint8_t val) case 0x107: ps2.subaddr_hi = val; break; + + default: + break; } } @@ -458,11 +473,12 @@ model_55sx_mem_recalc(void) mem_set_mem_state(0xe0000, 0x20000, state); - /* if (!(ps2.option[3] & 0x08)) - { +#if 0 + if (!(ps2.option[3] & 0x08)) { ps2_mca_log("Memory not yet configured\n"); return; - } */ + } +#endif ps2_mca_log("Enable shadow mapping at %06X-%06X\n", (mem_size * 1024), (mem_size * 1024) + (remap_size * 1024) - 1); @@ -478,11 +494,6 @@ static void model_55sx_write(uint16_t port, uint8_t val) { switch (port) { - case 0x100: - ps2.io_id = val; - break; - case 0x101: - break; case 0x102: lpt1_remove(); serial_remove(ps2.uart); @@ -503,6 +514,9 @@ model_55sx_write(uint16_t port, uint8_t val) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps2.option[0] = val; @@ -529,6 +543,9 @@ model_55sx_write(uint16_t port, uint8_t val) case 0x107: ps2.subaddr_hi = val; break; + + default: + break; } } @@ -536,10 +553,6 @@ static void model_70_type3_write(uint16_t port, uint8_t val) { switch (port) { - case 0x100: - break; - case 0x101: - break; case 0x102: lpt1_remove(); serial_remove(ps2.uart); @@ -560,6 +573,9 @@ model_70_type3_write(uint16_t port, uint8_t val) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps2.option[0] = val; @@ -581,6 +597,9 @@ model_70_type3_write(uint16_t port, uint8_t val) case 0x107: ps2.subaddr_hi = val; break; + + default: + break; } } @@ -588,10 +607,6 @@ static void model_80_write(uint16_t port, uint8_t val) { switch (port) { - case 0x100: - break; - case 0x101: - break; case 0x102: lpt1_remove(); serial_remove(ps2.uart); @@ -612,6 +627,9 @@ model_80_write(uint16_t port, uint8_t val) case 2: lpt1_init(LPT2_ADDR); break; + + default: + break; } } ps2.option[0] = val; @@ -631,17 +649,22 @@ model_80_write(uint16_t port, uint8_t val) case 0x107: ps2.subaddr_hi = val; break; + + default: + break; } } uint8_t -ps2_mca_read(uint16_t port, void *p) +ps2_mca_read(uint16_t port, UNUSED(void *priv)) { uint8_t temp; switch (port) { case 0x91: - // fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); +#if 0 + fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); +#endif if (!(ps2.setup & PS2_SETUP_IO)) temp = 0x00; else if (!(ps2.setup & PS2_SETUP_VGA)) @@ -740,7 +763,7 @@ ps2_mca_read(uint16_t port, void *p) } static void -ps2_mca_write(uint16_t port, uint8_t val, void *p) +ps2_mca_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { ps2_mca_log("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); @@ -763,7 +786,7 @@ ps2_mca_write(uint16_t port, uint8_t val, void *p) case 0x101: if (!(ps2.setup & PS2_SETUP_IO)) ps2.planar_write(port, val); - else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) mca_write(port, val); break; case 0x102: @@ -804,6 +827,9 @@ ps2_mca_write(uint16_t port, uint8_t val, void *p) else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; + + default: + break; } } @@ -824,13 +850,13 @@ ps2_mca_board_common_init(void) } static uint8_t -ps2_mem_expansion_read(int port, void *p) +ps2_mem_expansion_read(int port, UNUSED(void *priv)) { return ps2.mem_pos_regs[port & 7]; } static void -ps2_mem_expansion_write(int port, uint8_t val, void *p) +ps2_mem_expansion_write(int port, uint8_t val, UNUSED(void *priv)) { if (port < 0x102 || port == 0x104) return; @@ -844,7 +870,7 @@ ps2_mem_expansion_write(int port, uint8_t val, void *p) } static uint8_t -ps2_mem_expansion_feedb(void *p) +ps2_mem_expansion_feedb(UNUSED(void *priv)) { return (ps2.mem_pos_regs[2] & 1); } @@ -888,6 +914,9 @@ ps2_mca_mem_fffc_init(int start_mb) case 8: ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ break; + + default: + break; } mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, ps2_mem_expansion_feedb, NULL, NULL); @@ -938,12 +967,12 @@ ps2_mca_mem_d071_init(int start_mb) } static void -ps2_mca_board_model_50_init(int slots) +ps2_mca_board_model_50_init(void) { ps2_mca_board_common_init(); mem_remap_top(384); - mca_init(slots); + mca_init(4); device_add(&keyboard_ps2_mca_2_device); ps2.planar_read = model_50_read; @@ -958,6 +987,29 @@ ps2_mca_board_model_50_init(int slots) device_add(&ps1vga_mca_device); } +static void +ps2_mca_board_model_60_init(void) +{ + ps2_mca_board_common_init(); + + mem_remap_top(384); + mca_init(8); + device_add(&keyboard_ps2_mca_2_device); + + ps2.planar_read = model_50_read; + ps2.planar_write = model_50_write; + + if (mem_size > 2048) { + /* Only 2 MB supported on planar, create a memory expansion card for the rest */ + ps2_mca_mem_fffc_init(2); + } + + device_add(&ps2_nvr_55ls_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&ps1vga_mca_device); +} + static void ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) { @@ -988,9 +1040,6 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) ps2.memory_bank[1] = 0x61; break; case 6: - ps2.memory_bank[0] = 0x01; - ps2.memory_bank[1] = 0x51; - break; case 7: /*Not supported*/ ps2.memory_bank[0] = 0x01; ps2.memory_bank[1] = 0x51; @@ -999,15 +1048,16 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) ps2.memory_bank[0] = 0x01; ps2.memory_bank[1] = 0x01; break; + + default: + break; } mca_init(slots); device_add(&keyboard_ps2_device); - if (has_sec_nvram == 1) + if (has_sec_nvram) device_add(&ps2_nvr_55ls_device); - else if (has_sec_nvram == 2) - device_add(&ps2_nvr_device); ps2.planar_read = model_55sx_read; ps2.planar_write = model_55sx_write; @@ -1071,18 +1121,21 @@ mem_encoding_update(void) } static uint8_t -mem_encoding_read(uint16_t addr, void *p) +mem_encoding_read(uint16_t addr, UNUSED(void *priv)) { switch (addr) { case 0xe0: return ps2.mem_regs[0]; case 0xe1: return ps2.mem_regs[1]; + + default: + break; } return 0xff; } static void -mem_encoding_write(uint16_t addr, uint8_t val, void *p) +mem_encoding_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { switch (addr) { case 0xe0: @@ -1091,12 +1144,15 @@ mem_encoding_write(uint16_t addr, uint8_t val, void *p) case 0xe1: ps2.mem_regs[1] = val; break; + + default: + break; } mem_encoding_update(); } static uint8_t -mem_encoding_read_cached(uint16_t addr, void *p) +mem_encoding_read_cached(uint16_t addr, UNUSED(void *priv)) { switch (addr) { case 0xe0: @@ -1105,12 +1161,15 @@ mem_encoding_read_cached(uint16_t addr, void *p) return ps2.mem_regs[1]; case 0xe2: return ps2.mem_regs[2]; + + default: + break; } return 0xff; } static void -mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p) +mem_encoding_write_cached(uint16_t addr, uint8_t val, UNUSED(void *priv)) { uint8_t old; @@ -1145,6 +1204,9 @@ mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p) ram_mid_mapping.flags &= ~MEM_MAPPING_ROM_WS; #endif break; + + default: + break; } ps2_mca_log("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS, cpu_state.pc, ps2.mem_regs[1], ps2.mem_regs[2]); mem_encoding_update(); @@ -1253,7 +1315,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots) } static void -ps2_mca_board_model_80_type2_init(int is486) +ps2_mca_board_model_80_type2_init(void) { ps2_mca_board_common_init(); @@ -1313,7 +1375,7 @@ ps2_mca_board_model_80_type2_init(int is486) NULL); mem_mapping_disable(&ps2.split_mapping); - if ((mem_size > 4096) && !is486) { + if (mem_size > 4096) { /* Only 4 MB supported on planar, create a memory expansion card for the rest */ if (mem_size > 12288) ps2_mca_mem_d071_init(4); @@ -1367,7 +1429,7 @@ machine_ps2_model_50_init(const machine_t *model) machine_ps2_common_init(model); ps2.planar_id = 0xfbff; - ps2_mca_board_model_50_init(4); + ps2_mca_board_model_50_init(); return ret; } @@ -1389,8 +1451,8 @@ machine_ps2_model_60_init(const machine_t *model) machine_ps2_common_init(model); - ps2.planar_id = 0xfbff; - ps2_mca_board_model_50_init(8); + ps2.planar_id = 0xf7ff; + ps2_mca_board_model_60_init(); return ret; } @@ -1450,7 +1512,6 @@ machine_ps2_model_70_type3_init(const machine_t *model) machine_ps2_common_init(model); ps2.planar_id = 0xf9ff; - ps2_mca_board_model_70_type34_init(0, 4); return ret; @@ -1471,7 +1532,7 @@ machine_ps2_model_80_init(const machine_t *model) machine_ps2_common_init(model); ps2.planar_id = 0xfdff; - ps2_mca_board_model_80_type2_init(0); + ps2_mca_board_model_80_type2_init(); return ret; } @@ -1491,7 +1552,6 @@ machine_ps2_model_80_axx_init(const machine_t *model) machine_ps2_common_init(model); ps2.planar_id = 0xfff9; - ps2_mca_board_model_70_type34_init(0, 8); return ret; @@ -1512,7 +1572,6 @@ machine_ps2_model_70_type4_init(const machine_t *model) machine_ps2_common_init(model); ps2.planar_id = 0xf9ff; - ps2_mca_board_model_70_type34_init(1, 4); return ret; diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 24ecc654ae..1d4c3303f6 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -43,6 +43,7 @@ #include <86box/video.h> #include <86box/vid_cga_comp.h> #include <86box/machine.h> +#include <86box/plat_unused.h> enum { TANDY_RGB = 0, @@ -62,7 +63,7 @@ enum { EEPROM_WRITE }; -typedef struct { +typedef struct t1kvid_t { mem_mapping_t mapping; mem_mapping_t vram_mapping; @@ -72,36 +73,41 @@ typedef struct { int array_index; uint8_t array[256]; int memctrl; - uint8_t mode, col; + uint8_t mode; + uint8_t col; uint8_t stat; - uint8_t *vram, *b8000; + uint8_t *vram; + uint8_t *b8000; uint32_t b8000_mask; uint32_t b8000_limit; uint8_t planar_ctrl; - int linepos, - displine; - int sc, vc; - int dispon; - int con, coff, - cursoron, - blink; + int linepos; + int displine; + int sc; + int vc; + int dispon; + int con; + int coff; + int cursoron; + int blink; int fullchange; int vsynctime; int vadj; - uint16_t ma, maback; + uint16_t ma; + uint16_t maback; - uint64_t dispontime, - dispofftime; + uint64_t dispontime; + uint64_t dispofftime; pc_timer_t timer; - int firstline, - lastline; + int firstline; + int lastline; int composite; } t1kvid_t; -typedef struct { +typedef struct t1keep_t { char *path; int state; @@ -112,7 +118,7 @@ typedef struct { uint16_t store[64]; } t1keep_t; -typedef struct { +typedef struct tandy_t { mem_mapping_t ram_mapping; mem_mapping_t rom_mapping; /* SL2 */ @@ -122,6 +128,7 @@ typedef struct { int rom_offset; /* SL2 */ uint32_t base; + uint32_t mask; int is_sl2; t1kvid_t *vid; @@ -573,15 +580,18 @@ vid_out(uint16_t addr, uint8_t val, void *priv) vid->planar_ctrl = val; recalc_mapping(dev); break; + + default: + break; } } static uint8_t vid_in(uint16_t addr, void *priv) { - tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; - uint8_t ret = 0xff; + const tandy_t *dev = (tandy_t *) priv; + const t1kvid_t *vid = dev->vid; + uint8_t ret = 0xff; if ((addr >= 0x3d0) && (addr <= 0x3d7)) addr = (addr & 0xff9) | 0x004; @@ -598,6 +608,9 @@ vid_in(uint16_t addr, void *priv) case 0x03da: ret = vid->stat; break; + + default: + break; } return ret; @@ -627,8 +640,8 @@ vid_write(uint32_t addr, uint8_t val, void *priv) static uint8_t vid_read(uint32_t addr, void *priv) { - tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; + const tandy_t *dev = (tandy_t *) priv; + const t1kvid_t *vid = dev->vid; if (vid->memctrl == -1) return 0xff; @@ -696,7 +709,7 @@ vid_poll(void *priv) } else { buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->col & 15) + 16; if (vid->mode & 1) { - buffer32->line[(vid->displine << 1)][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; } else { buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; } @@ -773,7 +786,7 @@ vid_poll(void *priv) } if (drawcursor) { for (c = 0; c < 8; c++) { - buffer32->line[(vid->displine << 1)][(x << 3) + c + 8] ^= 15; + buffer32->line[vid->displine << 1][(x << 3) + c + 8] ^= 15; buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] ^= 15; } } @@ -796,19 +809,19 @@ vid_poll(void *priv) vid->ma++; if (vid->sc & 8) { for (c = 0; c < 8; c++) - buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = cols[0]; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = cols[0]; } else { for (c = 0; c < 8; c++) { if (vid->sc == 8) { - buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; } else { - buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } if (drawcursor) { for (c = 0; c < 16; c++) { - buffer32->line[(vid->displine << 1)][(x << 4) + c + 8] ^= 15; + buffer32->line[vid->displine << 1][(x << 4) + c + 8] ^= 15; buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] ^= 15; } } @@ -837,7 +850,7 @@ vid_poll(void *priv) dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; vid->ma++; for (c = 0; c < 8; c++) { - buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } @@ -848,7 +861,7 @@ vid_poll(void *priv) dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; vid->ma++; for (c = 0; c < 16; c++) { - buffer32->line[(vid->displine << 1)][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; + buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -879,7 +892,7 @@ vid_poll(void *priv) else x = (vid->crtc[1] << 4) + 16; if (!dev->is_sl2 && vid->composite) { - Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1)]); + Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine << 1]); Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1) + 1]); } else { video_process_8(x, vid->displine << 1); @@ -967,7 +980,7 @@ vid_poll(void *priv) if (!enable_overscan) xs_temp -= 16; - if (((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { xsize = xs_temp; ysize = ys_temp; set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); @@ -1021,7 +1034,7 @@ vid_poll(void *priv) vid->sc &= 31; vid->ma = vid->maback; } - if ((vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1)))) + if (vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1))) vid->con = 1; } } @@ -1139,7 +1152,7 @@ const device_t vid_device_sl = { }; static void -eep_write(uint16_t addr, uint8_t val, void *priv) +eep_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { t1keep_t *eep = (t1keep_t *) priv; @@ -1166,6 +1179,9 @@ eep_write(uint16_t addr, uint8_t val, void *priv) eep->state = EEPROM_GET_OPERATION; eep->count = 0; break; + + default: + break; } break; @@ -1211,6 +1227,9 @@ eep_write(uint16_t addr, uint8_t val, void *priv) eep->store[eep->addr] = eep->data; } break; + + default: + break; } eep->clk = val & 4; @@ -1220,7 +1239,7 @@ static void * eep_init(const device_t *info) { t1keep_t *eep; - FILE *f = NULL; + FILE *fp = NULL; eep = (t1keep_t *) malloc(sizeof(t1keep_t)); memset(eep, 0x00, sizeof(t1keep_t)); @@ -1233,13 +1252,16 @@ eep_init(const device_t *info) case TYPE_TANDY1000SL2: eep->path = "tandy1000sl2.bin"; break; + + default: + break; } - f = nvr_fopen(eep->path, "rb"); - if (f != NULL) { - if (fread(eep->store, 1, 128, f) != 128) + fp = nvr_fopen(eep->path, "rb"); + if (fp != NULL) { + if (fread(eep->store, 1, 128, fp) != 128) fatal("eep_init(): Error reading Tandy EEPROM\n"); - (void) fclose(f); + (void) fclose(fp); } else memset(eep->store, 0x00, 128); @@ -1252,12 +1274,12 @@ static void eep_close(void *priv) { t1keep_t *eep = (t1keep_t *) priv; - FILE *f = NULL; + FILE *fp = NULL; - f = nvr_fopen(eep->path, "wb"); - if (f != NULL) { - (void) fwrite(eep->store, 128, 1, f); - (void) fclose(f); + fp = nvr_fopen(eep->path, "wb"); + if (fp != NULL) { + (void) fwrite(eep->store, 128, 1, fp); + (void) fclose(fp); } free(eep); @@ -1298,8 +1320,19 @@ tandy_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x00a0: - mem_mapping_set_addr(&dev->ram_mapping, - ((val >> 1) & 7) * 128 * 1024, 0x20000); + if (val & 0x10) { + dev->base = (mem_size - 256) * 1024; + dev->mask = 0x3ffff; + mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); + mem_mapping_set_addr(&dev->ram_mapping, + ((val >> 1) & 7) * 128 * 1024, 0x40000); + } else { + dev->base = (mem_size - 128) * 1024; + dev->mask = 0x1ffff; + mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); + mem_mapping_set_addr(&dev->ram_mapping, + ((val >> 1) & 7) * 128 * 1024, 0x20000); + } dev->ram_bank = val; break; @@ -1319,14 +1352,18 @@ tandy_write(uint16_t addr, uint8_t val, void *priv) dev->rom_offset = ((val ^ 4) & 7) * 0x10000; mem_mapping_set_exec(&dev->rom_mapping, &dev->rom[dev->rom_offset]); + break; + + default: + break; } } static uint8_t tandy_read(uint16_t addr, void *priv) { - tandy_t *dev = (tandy_t *) priv; - uint8_t ret = 0xff; + const tandy_t *dev = (tandy_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0x00a0: @@ -1340,6 +1377,9 @@ tandy_read(uint16_t addr, void *priv) case 0xffea: ret = (dev->rom_bank ^ 0x10); break; + + default: + break; } return ret; @@ -1348,24 +1388,24 @@ tandy_read(uint16_t addr, void *priv) static void write_ram(uint32_t addr, uint8_t val, void *priv) { - tandy_t *dev = (tandy_t *) priv; + const tandy_t *dev = (tandy_t *) priv; - ram[dev->base + (addr & 0x1ffff)] = val; + ram[dev->base + (addr & dev->mask)] = val; } static uint8_t read_ram(uint32_t addr, void *priv) { - tandy_t *dev = (tandy_t *) priv; + const tandy_t *dev = (tandy_t *) priv; - return (ram[dev->base + (addr & 0x1ffff)]); + return (ram[dev->base + (addr & dev->mask)]); } static uint8_t read_rom(uint32_t addr, void *priv) { - tandy_t *dev = (tandy_t *) priv; - uint32_t addr2 = (addr & 0xffff) + dev->rom_offset; + const tandy_t *dev = (tandy_t *) priv; + uint32_t addr2 = (addr & 0xffff) + dev->rom_offset; return (dev->rom[addr2]); } @@ -1434,8 +1474,10 @@ machine_tandy1k_init(const machine_t *model, int type) * 0xFFE8 (SL2), so we remove it from the main mapping. */ dev->base = (mem_size - 128) * 1024; - mem_mapping_add(&dev->ram_mapping, 0x80000, 0x20000, - read_ram, NULL, NULL, write_ram, NULL, NULL, NULL, 0, dev); + dev->mask = 0x1ffff; + mem_mapping_add(&dev->ram_mapping, 0x60000, 0x20000, + read_ram, NULL, NULL, write_ram, NULL, NULL, NULL, + MEM_MAPPING_INTERNAL, dev); mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); device_add(&keyboard_tandy_device); @@ -1475,6 +1517,9 @@ machine_tandy1k_init(const machine_t *model, int type) device_add(&pssj_device); device_add(&eep_1000sl2_device); break; + + default: + break; } standalone_gameport_type = &gameport_device; diff --git a/src/machine/m_v86p.c b/src/machine/m_v86p.c index 62b6e48344..54af9b0535 100644 --- a/src/machine/m_v86p.c +++ b/src/machine/m_v86p.c @@ -52,7 +52,7 @@ int machine_v86p_init(const machine_t *model) { int ret; - int rom = 0; + int rom_id = 0; 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", @@ -60,7 +60,7 @@ machine_v86p_init(const machine_t *model) if (!ret) { /* Try an older version of the BIOS. */ - rom = 1; + 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); @@ -68,7 +68,7 @@ machine_v86p_init(const machine_t *model) if (!ret) { /* Try JVERNET's BIOS. */ - rom = 2; + rom_id = 2; ret = bios_load_linear("roms/machines/v86p/V86P.ROM", 0x000f0000, 65536, 0); } @@ -76,7 +76,7 @@ machine_v86p_init(const machine_t *model) if (bios_only || !ret) return ret; - if (rom == 2) + if (rom_id == 2) loadfont("roms/machines/v86p/V86P.FON", 8); else loadfont("roms/machines/v86p/v86pfont.rom", 8); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 84eb517c8e..9a0b39a89d 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -310,7 +310,9 @@ machine_xt_pxxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + device_add(&keyboard_xt_device); + + machine_xt_common_init(model); return ret; } @@ -491,6 +493,14 @@ machine_xt_vendex_init(const machine_t *model) return ret; } +static void +machine_xt_hyundai_common_init(const machine_t *model) +{ + device_add(&keyboard_xt_hyundai_device); + + machine_xt_common_init(model); +} + int machine_xt_super16t_init(const machine_t *model) { @@ -502,7 +512,7 @@ machine_xt_super16t_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_hyundai_common_init(model); /* On-board FDC cannot be disabled */ device_add(&fdc_xt_device); @@ -521,7 +531,7 @@ machine_xt_super16te_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + machine_xt_hyundai_common_init(model); /* On-board FDC cannot be disabled */ device_add(&fdc_xt_device); @@ -630,3 +640,19 @@ machine_xt_pb8810_init(const machine_t *model) return ret; } + +int +machine_xt_glabios_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/glabios/GLABIOS_0.2.6_8X_012324.ROM", + 0x000fe000, 8192, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_init_ex(model); + + return ret; +} diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index 59db0cbe0c..87c2fe3623 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -19,6 +19,7 @@ #include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/keyboard.h> +#include <86box/plat_unused.h> static int laserxt_emspage[4]; static int laserxt_emscontrol[4]; @@ -37,7 +38,7 @@ get_laserxt_ems_addr(uint32_t addr) } static void -laserxt_write(uint16_t port, uint8_t val, void *priv) +laserxt_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { uint32_t paddr; uint32_t vaddr; @@ -73,11 +74,14 @@ laserxt_write(uint16_t port, uint8_t val, void *priv) mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); flushmmucache(); break; + + default: + break; } } static uint8_t -laserxt_read(uint16_t port, void *priv) +laserxt_read(uint16_t port, UNUSED(void *priv)) { switch (port) { case 0x0208: @@ -90,13 +94,15 @@ laserxt_read(uint16_t port, void *priv) case 0x8209: case 0xC209: return laserxt_emscontrol[port >> 14]; + + default: break; } return 0xff; } static void -mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) +mem_write_laserxtems(uint32_t addr, uint8_t val, UNUSED(void *priv)) { addr = get_laserxt_ems_addr(addr); if (addr < (mem_size << 10)) @@ -104,7 +110,7 @@ mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) } static uint8_t -mem_read_laserxtems(uint32_t addr, void *priv) +mem_read_laserxtems(uint32_t addr, UNUSED(void *priv)) { uint8_t val = 0xFF; addr = get_laserxt_ems_addr(addr); diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 4d6522295d..0b5a3eab09 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -57,6 +57,7 @@ #include <86box/vid_ogc.h> #include <86box/vid_colorplus.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 @@ -115,7 +116,7 @@ enum MM58274_ADDR { static struct tm intclk; -typedef struct { +typedef struct m24_kbd_t { /* Keyboard stuff. */ int wantirq; uint8_t command; @@ -123,18 +124,19 @@ typedef struct { uint8_t out; uint8_t output_port; uint8_t id; - int param, - param_total; + int param; + int param_total; uint8_t params[16]; uint8_t scan[7]; /* Mouse stuff. */ - int mouse_mode; - int x, y, b; + int mouse_input_mode; + int b; + pc_timer_t send_delay_timer; } m24_kbd_t; -typedef struct { +typedef struct m19_vid_t { ogc_t ogc; colorplus_t colorplus; int mode; @@ -439,7 +441,7 @@ mm58274_write(uint16_t addr, uint8_t val, void *priv) static uint8_t mm58274_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + const nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; @@ -548,7 +550,7 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) if (m24_kbd->param == m24_kbd->param_total) { switch (m24_kbd->command) { case 0x11: - m24_kbd->mouse_mode = 0; + m24_kbd->mouse_input_mode = 0; m24_kbd->scan[0] = m24_kbd->params[0]; m24_kbd->scan[1] = m24_kbd->params[1]; m24_kbd->scan[2] = m24_kbd->params[2]; @@ -559,7 +561,7 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0x12: - m24_kbd->mouse_mode = 1; + m24_kbd->mouse_input_mode = 1; m24_kbd->scan[0] = m24_kbd->params[0]; m24_kbd->scan[1] = m24_kbd->params[1]; m24_kbd->scan[2] = m24_kbd->params[2]; @@ -635,6 +637,10 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) if (val == 0x02) m24_kbd_adddata(0x00); + break; + + default: + break; } } @@ -714,7 +720,7 @@ m24_kbd_reset(void *priv) m24_kbd->wantirq = 0; keyboard_scan = 1; m24_kbd->param = m24_kbd->param_total = 0; - m24_kbd->mouse_mode = 0; + m24_kbd->mouse_input_mode = 0; m24_kbd->scan[0] = 0x1c; m24_kbd->scan[1] = 0x53; m24_kbd->scan[2] = 0x01; @@ -725,12 +731,14 @@ m24_kbd_reset(void *priv) } static int -ms_poll(int x, int y, int z, int b, void *priv) +ms_poll(void *priv) { m24_kbd_t *m24_kbd = (m24_kbd_t *) priv; - - m24_kbd->x += x; - m24_kbd->y += y; + int delta_x; + int delta_y; + int o_x; + int o_y; + int b = mouse_get_buttons_ex(); if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; @@ -759,57 +767,49 @@ ms_poll(int x, int y, int z, int b, void *priv) m24_kbd_adddata(m24_kbd->scan[1] | 0x80); m24_kbd->b = (m24_kbd->b & ~4) | (b & 4); - if (m24_kbd->mouse_mode) { + if (m24_kbd->mouse_input_mode) { if (((key_queue_end - key_queue_start) & 0xf) > 12) return 0xff; - if (!m24_kbd->x && !m24_kbd->y) + if (!mouse_moved()) return 0xff; - m24_kbd->y = -m24_kbd->y; + mouse_subtract_coords(&delta_x, &delta_y, &o_x, &o_y, -127, 127, 1, 0); - if (m24_kbd->x < -127) - m24_kbd->x = -127; - if (m24_kbd->x > 127) - m24_kbd->x = 127; - if (m24_kbd->x < -127) - m24_kbd->x = 0x80 | ((-m24_kbd->x) & 0x7f); + if ((delta_x == -127) && o_x) + delta_x = 0x80 | ((-delta_x) & 0x7f); - if (m24_kbd->y < -127) - m24_kbd->y = -127; - if (m24_kbd->y > 127) - m24_kbd->y = 127; - if (m24_kbd->y < -127) - m24_kbd->y = 0x80 | ((-m24_kbd->y) & 0x7f); + if ((delta_y == -127) && o_y) + delta_y = 0x80 | ((-delta_y) & 0x7f); m24_kbd_adddata(0xfe); - m24_kbd_adddata(m24_kbd->x); - m24_kbd_adddata(m24_kbd->y); - - m24_kbd->x = m24_kbd->y = 0; + m24_kbd_adddata(delta_x); + m24_kbd_adddata(delta_y); } else { - while (m24_kbd->x < -4) { + mouse_subtract_coords(&delta_x, &delta_y, &o_x, &o_y, -127, 127, 1, 0); + + while (delta_x < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->x += 4; + delta_x += 4; m24_kbd_adddata(m24_kbd->scan[3]); } - while (m24_kbd->x > 4) { + while (delta_x > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->x -= 4; + delta_x -= 4; m24_kbd_adddata(m24_kbd->scan[4]); } - while (m24_kbd->y < -4) { + while (delta_y < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->y += 4; + delta_y += 4; m24_kbd_adddata(m24_kbd->scan[5]); } - while (m24_kbd->y > 4) { + while (delta_y > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->y -= 4; + delta_y -= 4; m24_kbd_adddata(m24_kbd->scan[6]); } } @@ -1492,15 +1492,19 @@ m19_vid_init(m19_vid_t *vid) { device_context(&m19_vid_device); - /* int display_type; */ +#if 0 + int display_type; +#endif vid->mode = OLIVETTI_OGC_MODE; video_inform(VIDEO_FLAG_TYPE_CGA, &timing_m19_vid); - /* display_type = device_get_config_int("display_type"); */ +#if 0 + display_type = device_get_config_int("display_type"); +#endif /* OGC emulation part begin */ - loadfont_ex("roms/machines/m19/BIOS.BIN", 1, 90); + loadfont("roms/machines/m19/MBM2764-30 8514 107 AB PCF3.BIN", 7); /* composite is not working yet */ vid->ogc.cga.composite = 0; // (display_type != CGA_RGB); vid->ogc.cga.revision = device_get_config_int("composite_type"); @@ -1508,7 +1512,9 @@ m19_vid_init(m19_vid_t *vid) vid->ogc.cga.vram = malloc(0x8000); - /* cga_comp_init(vid->ogc.cga.revision); */ +#if 0 + cga_comp_init(vid->ogc.cga.revision); +#endif vid->ogc.cga.rgb_type = device_get_config_int("rgb_type"); cga_palette = (vid->ogc.cga.rgb_type << 1); @@ -1525,11 +1531,15 @@ m19_vid_init(m19_vid_t *vid) /* Plantronics emulation part begin*/ /* composite is not working yet */ vid->colorplus.cga.composite = 0; //(display_type != CGA_RGB); - /* vid->colorplus.cga.snow_enabled = device_get_config_int("snow_enabled"); */ +#if 0 + vid->colorplus.cga.snow_enabled = device_get_config_int("snow_enabled"); +#endif vid->colorplus.cga.vram = malloc(0x8000); - /* vid->colorplus.cga.cgamode = 0x1; */ +#if 0 + vid->colorplus.cga.cgamode = 0x1; +#endif /* Plantronics emulation part end*/ timer_add(&vid->ogc.cga.timer, ogc_poll, &vid->ogc, 1); @@ -1602,7 +1612,7 @@ const device_t m19_vid_device = { }; static uint8_t -m24_read(uint16_t port, void *priv) +m24_read(uint16_t port, UNUSED(void *priv)) { uint8_t ret = 0x00; int fdd_count = 0; @@ -1706,13 +1716,16 @@ m24_read(uint16_t port, void *priv) /* 1 = 720 kB (3.5"), 0 = 360 kB (5.25") */ ret |= (fdd_doublestep_40(0) || fdd_doublestep_40(1)) ? 0x1 : 0x0; break; + + default: + break; } return ret; } static uint8_t -m240_read(uint16_t port, void *priv) +m240_read(uint16_t port, UNUSED(void *priv)) { uint8_t ret = 0x00; int fdd_count = 0; @@ -1761,6 +1774,9 @@ m240_read(uint16_t port, void *priv) ret |= fdd_doublestep_40(1) ? 0x40 : 0x00; ret |= fdd_doublestep_40(0) ? 0x20 : 0x00; break; + + default: + break; } return ret; @@ -1900,6 +1916,7 @@ machine_xt_m19_init(const machine_t *model) ret = bios_load_linear("roms/machines/m19/BIOS.BIN", 0x000fc000, 16384, 0); + ret &= rom_present("roms/machines/m19/MBM2764-30 8514 107 AB PCF3.BIN"); if (bios_only || !ret) return ret; @@ -1926,7 +1943,7 @@ machine_xt_m19_init(const machine_t *model) device_add(&keyboard_xt_olivetti_device); - pit_set_clock(14318184.0); + pit_set_clock((uint32_t) 14318184.0); return ret; } diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c index bc1b6f7929..1fc284a468 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -39,9 +39,9 @@ #include <86box/chipset.h> #include <86box/io.h> #include <86box/video.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct philips_t { uint8_t reg; } philips_t; @@ -80,6 +80,9 @@ philips_write(uint16_t port, uint8_t val, void *priv) else cpu_dynamic_switch(0); break; + + default: + break; } philips_log("Philips XT Mainboard: Write %02x at %02x\n", val, port); @@ -88,8 +91,8 @@ philips_write(uint16_t port, uint8_t val, void *priv) static uint8_t philips_read(uint16_t port, void *priv) { - philips_t *dev = (philips_t *) priv; - uint8_t ret = 0xff; + const philips_t *dev = (philips_t *) priv; + uint8_t ret = 0xff; switch (port) { /* port 0xc0 @@ -100,6 +103,9 @@ philips_read(uint16_t port, void *priv) case 0xc0: ret = dev->reg; break; + + default: + break; } philips_log("Philips XT Mainboard: Read %02x at %02x\n", ret, port); @@ -116,7 +122,7 @@ philips_close(void *priv) } static void * -philips_init(const device_t *info) +philips_init(UNUSED(const device_t *info)) { philips_t *dev = (philips_t *) malloc(sizeof(philips_t)); memset(dev, 0, sizeof(philips_t)); diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 7558405999..a12fa4e96b 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -55,11 +55,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2018-2019 Fred N. van Kempen. * Copyright 2018-2019 Miran Grca. - * Copyright 2018-2019 Sarah Walker. + * Copyright 2018-2019 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -135,7 +135,7 @@ enum TC8521_ADDR { TC8521_LEAPYEAR = 0x1B }; -typedef struct { +typedef struct t1000_t { /* ROM drive */ uint8_t *romdrive; uint8_t rom_ctl; @@ -237,7 +237,7 @@ tc8521_time_get(uint8_t *regs, struct tm *tm) /* This is called every second through the NVR/RTC hook. */ static void -tc8521_tick(nvr_t *nvr) +tc8521_tick(UNUSED(nvr_t *nvr)) { t1000_log("TC8521: ping\n"); } @@ -288,8 +288,8 @@ tc8521_write(uint16_t addr, uint8_t val, void *priv) static uint8_t tc8521_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; - uint8_t page; + const nvr_t *nvr = (nvr_t *) priv; + uint8_t page; /* Get to the correct register page. */ addr &= 0x0f; @@ -336,7 +336,7 @@ tc8521_init(nvr_t *nvr, int size) /* Given an EMS page ID, return its physical address in RAM. */ static uint32_t -ems_execaddr(t1000_t *sys, int pg, uint16_t val) +ems_execaddr(t1000_t *sys, UNUSED(int pg), uint16_t val) { if (!(val & 0x80)) return 0; /* Bit 7 reset => not mapped */ @@ -360,7 +360,7 @@ ems_execaddr(t1000_t *sys, int pg, uint16_t val) static uint8_t ems_in(uint16_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; + const t1000_t *sys = (t1000_t *) priv; #if 0 t1000_log("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); @@ -467,7 +467,7 @@ addr_to_page(uint32_t addr) static uint8_t ems_read_ram(uint32_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; + const t1000_t *sys = (t1000_t *) priv; int pg = addr_to_page(addr); if (pg < 0) @@ -480,8 +480,8 @@ ems_read_ram(uint32_t addr, void *priv) static uint16_t ems_read_ramw(uint32_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; - int pg = addr_to_page(addr); + const t1000_t *sys = (t1000_t *) priv; + int pg = addr_to_page(addr); if (pg < 0) return 0xff; @@ -501,8 +501,8 @@ ems_read_ramw(uint32_t addr, void *priv) static uint32_t ems_read_raml(uint32_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; - int pg = addr_to_page(addr); + const t1000_t *sys = (t1000_t *) priv; + int pg = addr_to_page(addr); if (pg < 0) return 0xff; @@ -515,8 +515,8 @@ ems_read_raml(uint32_t addr, void *priv) static void ems_write_ram(uint32_t addr, uint8_t val, void *priv) { - t1000_t *sys = (t1000_t *) priv; - int pg = addr_to_page(addr); + const t1000_t *sys = (t1000_t *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; @@ -531,8 +531,8 @@ ems_write_ram(uint32_t addr, uint8_t val, void *priv) static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv) { - t1000_t *sys = (t1000_t *) priv; - int pg = addr_to_page(addr); + const t1000_t *sys = (t1000_t *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; @@ -555,8 +555,8 @@ ems_write_ramw(uint32_t addr, uint16_t val, void *priv) static void ems_write_raml(uint32_t addr, uint32_t val, void *priv) { - t1000_t *sys = (t1000_t *) priv; - int pg = addr_to_page(addr); + const t1000_t *sys = (t1000_t *) priv; + int pg = addr_to_page(addr); if (pg < 0) return; @@ -571,8 +571,8 @@ ems_write_raml(uint32_t addr, uint32_t val, void *priv) static uint8_t read_ctl(uint16_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; - uint8_t ret = 0xff; + const t1000_t *sys = (t1000_t *) priv; + uint8_t ret = 0xff; switch (addr & 0x0f) { case 1: @@ -595,6 +595,9 @@ read_ctl(uint16_t addr, void *priv) case 0x52: ret = (sys->is_640k ? 0x80 : 0); break; + + default: + break; } break; @@ -656,8 +659,14 @@ write_ctl(uint16_t addr, uint8_t val, void *priv) case 0x52: ems_set_640k(sys, val); break; + + default: + break; } break; + + default: + break; } } @@ -689,6 +698,9 @@ t1000_read_nvram(uint16_t addr, void *priv) tmp |= 0x2e; /* Bits 5, 3, 2, 1 always 1 */ tmp |= (sys->nvr_active & 0x40) >> 6; /* Ready state */ break; + + default: + break; } return tmp; @@ -733,13 +745,16 @@ t1000_write_nvram(uint16_t addr, uint8_t val, void *priv) if (val == 0x80) sys->nvr_addr = -1; break; + + default: + break; } } static uint8_t read_t1200_nvram(uint32_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; + const t1000_t *sys = (t1000_t *) priv; return sys->t1200_nvram[addr & 0x7FF]; } @@ -757,15 +772,15 @@ write_t1200_nvram(uint32_t addr, uint8_t value, void *priv) /* Port 0xC8 controls the ROM drive */ static uint8_t -t1000_read_rom_ctl(uint16_t addr, void *priv) +t1000_read_rom_ctl(UNUSED(uint16_t addr), void *priv) { - t1000_t *sys = (t1000_t *) priv; + const t1000_t *sys = (t1000_t *) priv; return (sys->rom_ctl); } static void -t1000_write_rom_ctl(uint16_t addr, uint8_t val, void *priv) +t1000_write_rom_ctl(UNUSED(uint16_t addr), uint8_t val, void *priv) { t1000_t *sys = (t1000_t *) priv; @@ -785,7 +800,7 @@ t1000_write_rom_ctl(uint16_t addr, uint8_t val, void *priv) static uint8_t t1000_read_rom(uint32_t addr, void *priv) { - t1000_t *sys = (t1000_t *) priv; + const t1000_t *sys = (t1000_t *) priv; if (!sys->romdrive) return 0xff; @@ -818,7 +833,7 @@ t1000_read_roml(uint32_t addr, void *priv) int machine_xt_t1000_init(const machine_t *model) { - FILE *f; + FILE *fp; int ret; ret = bios_load_linear("roms/machines/t1000/t1000.rom", @@ -841,15 +856,15 @@ machine_xt_t1000_init(const machine_t *model) * If the file is missing, continue to boot; the BIOS will * complain 'No ROM drive' but boot normally from floppy. */ - f = rom_fopen("roms/machines/t1000/t1000dos.rom", "rb"); - if (f != NULL) { + fp = rom_fopen("roms/machines/t1000/t1000dos.rom", "rb"); + if (fp != NULL) { t1000.romdrive = malloc(T1000_ROMSIZE); if (t1000.romdrive) { memset(t1000.romdrive, 0xff, T1000_ROMSIZE); - if (fread(t1000.romdrive, 1, T1000_ROMSIZE, f) != T1000_ROMSIZE) + if (fread(t1000.romdrive, 1, T1000_ROMSIZE, fp) != T1000_ROMSIZE) fatal("machine_xt_t1000_init(): Error reading DOS ROM data\n"); } - fclose(f); + fclose(fp); } mem_mapping_add(&t1000.rom_mapping, 0xa0000, 0x10000, t1000_read_rom, t1000_read_romw, t1000_read_roml, @@ -971,62 +986,62 @@ t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) static void t1000_configsys_load(void) { - FILE *f; + FILE *fp; int size; memset(t1000.t1000_nvram, 0x1a, sizeof(t1000.t1000_nvram)); - f = plat_fopen(nvr_path("t1000_config.nvr"), "rb"); - if (f != NULL) { + fp = plat_fopen(nvr_path("t1000_config.nvr"), "rb"); + if (fp != NULL) { size = sizeof(t1000.t1000_nvram); - if (fread(t1000.t1000_nvram, 1, size, f) != size) + if (fread(t1000.t1000_nvram, 1, size, fp) != size) fatal("t1000_configsys_load(): Error reading data\n"); - fclose(f); + fclose(fp); } } static void t1000_configsys_save(void) { - FILE *f; + FILE *fp; int size; - f = plat_fopen(nvr_path("t1000_config.nvr"), "wb"); - if (f != NULL) { + fp = plat_fopen(nvr_path("t1000_config.nvr"), "wb"); + if (fp != NULL) { size = sizeof(t1000.t1000_nvram); - if (fwrite(t1000.t1000_nvram, 1, size, f) != size) + if (fwrite(t1000.t1000_nvram, 1, size, fp) != size) fatal("t1000_configsys_save(): Error writing data\n"); - fclose(f); + fclose(fp); } } static void t1200_state_load(void) { - FILE *f; + FILE *fp; int size; memset(t1000.t1200_nvram, 0, sizeof(t1000.t1200_nvram)); - f = plat_fopen(nvr_path("t1200_state.nvr"), "rb"); - if (f != NULL) { + fp = plat_fopen(nvr_path("t1200_state.nvr"), "rb"); + if (fp != NULL) { size = sizeof(t1000.t1200_nvram); - if (fread(t1000.t1200_nvram, 1, size, f) != size) + if (fread(t1000.t1200_nvram, 1, size, fp) != size) fatal("t1200_state_load(): Error reading data\n"); - fclose(f); + fclose(fp); } } static void t1200_state_save(void) { - FILE *f; + FILE *fp; int size; - f = plat_fopen(nvr_path("t1200_state.nvr"), "wb"); - if (f != NULL) { + fp = plat_fopen(nvr_path("t1200_state.nvr"), "wb"); + if (fp != NULL) { size = sizeof(t1000.t1200_nvram); - if (fwrite(t1000.t1200_nvram, 1, size, f) != size) + if (fwrite(t1000.t1200_nvram, 1, size, fp) != size) fatal("t1200_state_save(): Error writing data\n"); - fclose(f); + fclose(fp); } } @@ -1034,13 +1049,13 @@ t1200_state_save(void) static void t1000_emsboard_load(void) { - FILE *f; + FILE *fp; if (mem_size > 512) { - f = plat_fopen(nvr_path("t1000_ems.nvr"), "rb"); - if (f != NULL) { - (void) !fread(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); + fp = plat_fopen(nvr_path("t1000_ems.nvr"), "rb"); + if (fp != NULL) { + (void) !fread(&ram[512 * 1024], 1024, (mem_size - 512), fp); + fclose(fp); } } } @@ -1048,13 +1063,13 @@ t1000_emsboard_load(void) static void t1000_emsboard_save(void) { - FILE *f; + FILE *fp; if (mem_size > 512) { - f = plat_fopen(nvr_path("t1000_ems.nvr"), "wb"); - if (f != NULL) { - fwrite(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); + fp = plat_fopen(nvr_path("t1000_ems.nvr"), "wb"); + if (fp != NULL) { + fwrite(&ram[512 * 1024], 1024, (mem_size - 512), fp); + fclose(fp); } } } diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 45a15649d9..4ec13b5c44 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -13,11 +13,11 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2018-2019 Fred N. van Kempen. * Copyright 2018-2019 Miran Grca. - * Copyright 2018-2019 Sarah Walker. + * Copyright 2018-2019 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,12 +51,14 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/m_xt_t1000.h> +#include <86box/plat_unused.h> #define T1000_XSIZE 640 #define T1000_YSIZE 200 /* Mapping of attributes to colours */ -static uint32_t blue, grey; +static uint32_t blue; +static uint32_t grey; static uint8_t boldcols[256]; /* Which attributes use the bold font */ static uint32_t blinkcols[256][2]; static uint32_t normcols[256][2]; @@ -124,14 +126,14 @@ typedef struct t1000_t { } t1000_t; static void t1000_recalctimings(t1000_t *t1000); -static void t1000_write(uint32_t addr, uint8_t val, void *p); -static uint8_t t1000_read(uint32_t addr, void *p); +static void t1000_write(uint32_t addr, uint8_t val, void *priv); +static uint8_t t1000_read(uint32_t addr, void *priv); static void t1000_recalcattrs(t1000_t *t1000); static void -t1000_out(uint16_t addr, uint8_t val, void *p) +t1000_out(uint16_t addr, uint8_t val, void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; switch (addr) { /* Emulated CRTC, register select */ case 0x3d0: @@ -158,21 +160,20 @@ t1000_out(uint16_t addr, uint8_t val, void *p) t1000_recalctimings(t1000); return; - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t1000->cga); - return; - /* CGA colour register */ - case 0x3D9: + case 0x3D8: /* CGA control register */ + case 0x3D9: /* CGA colour register */ cga_out(addr, val, &t1000->cga); return; + + default: + break; } } static uint8_t -t1000_in(uint16_t addr, void *p) +t1000_in(uint16_t addr, void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; uint8_t val; switch (addr) { @@ -186,24 +187,29 @@ t1000_in(uint16_t addr, void *p) val |= 0x20; /* LCD / CRT */ return val; } + break; + + default: + break; } return cga_in(addr, &t1000->cga); } static void -t1000_write(uint32_t addr, uint8_t val, void *p) +t1000_write(uint32_t addr, uint8_t val, void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; t1000->vram[addr & 0x3fff] = val; cycles -= 4; } static uint8_t -t1000_read(uint32_t addr, void *p) +t1000_read(uint32_t addr, void *priv) { - t1000_t *t1000 = (t1000_t *) p; + const t1000_t *t1000 = (t1000_t *) priv; + cycles -= 4; return t1000->vram[addr & 0x3fff]; @@ -213,7 +219,8 @@ static void t1000_recalctimings(t1000_t *t1000) { double disptime; - double _dispontime, _dispofftime; + double _dispontime; + double _dispofftime; if (!t1000->internal) { cga_recalctimings(&t1000->cga); @@ -231,7 +238,6 @@ static void t1000_text_row80(t1000_t *t1000) { uint32_t cols[2]; - int c; uint8_t chr; uint8_t attr; int drawcursor; @@ -277,12 +283,12 @@ t1000_text_row80(t1000_t *t1000) cols[0] = normcols[attr][0]; } if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + for (uint8_t c = 0; c < 8; c++) { + (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); } } else { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + for (uint8_t c = 0; c < 8; c++) + (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; } @@ -293,8 +299,8 @@ static void t1000_text_row40(t1000_t *t1000) { uint32_t cols[2]; - int x, c; - uint8_t chr, attr; + uint8_t chr; + uint8_t attr; int drawcursor; int cursorline; int bold; @@ -313,7 +319,7 @@ t1000_text_row40(t1000_t *t1000) } else { cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && ((t1000->cga.crtc[11] & 0x0F) >= sc); } - for (x = 0; x < 40; x++) { + for (uint8_t x = 0; x < 40; x++) { chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; drawcursor = ((ma == ca) && cursorline && (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); @@ -338,12 +344,12 @@ t1000_text_row40(t1000_t *t1000) cols[0] = normcols[attr][0]; } if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t1000->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + for (uint8_t c = 0; c < 8; c++) { + (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); } } else { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[t1000->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + for (uint8_t c = 0; c < 8; c++) { + (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; } } ++ma; @@ -354,7 +360,6 @@ t1000_text_row40(t1000_t *t1000) static void t1000_cgaline6(t1000_t *t1000) { - int x, c; uint8_t dat; uint32_t ink = 0; uint16_t addr; @@ -365,15 +370,15 @@ t1000_cgaline6(t1000_t *t1000) addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1); - for (x = 0; x < 80; x++) { + for (uint8_t x = 0; x < 80; x++) { dat = t1000->vram[addr & 0x3FFF]; addr++; - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { ink = (dat & 0x80) ? fg : bg; if (!(t1000->cga.cgamode & 8)) ink = grey; - ((uint32_t *) buffer32->line[t1000->displine])[x * 8 + c] = ink; + (buffer32->line[t1000->displine])[x * 8 + c] = ink; dat = dat << 1; } } @@ -384,19 +389,20 @@ t1000_cgaline6(t1000_t *t1000) static void t1000_cgaline4(t1000_t *t1000) { - int x, c; - uint8_t dat, pattern; - uint32_t ink0, ink1; + uint8_t dat; + uint8_t pattern; + uint32_t ink0; + uint32_t ink1; uint16_t addr; uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1); - for (x = 0; x < 80; x++) { + for (uint8_t x = 0; x < 80; x++) { dat = t1000->vram[addr & 0x3FFF]; addr++; - for (c = 0; c < 4; c++) { + for (uint8_t c = 0; c < 4; c++) { pattern = (dat & 0xC0) >> 6; if (!(t1000->cga.cgamode & 8)) pattern = 0; @@ -428,17 +434,17 @@ t1000_cgaline4(t1000_t *t1000) ink0 = ink1 = blue; break; } - ((uint32_t *) buffer32->line[t1000->displine])[x * 8 + 2 * c] = ink0; - ((uint32_t *) buffer32->line[t1000->displine])[x * 8 + 2 * c + 1] = ink1; - dat = dat << 2; + (buffer32->line[t1000->displine])[x * 8 + 2 * c] = ink0; + (buffer32->line[t1000->displine])[x * 8 + 2 * c + 1] = ink1; + dat = dat << 2; } } } static void -t1000_poll(void *p) +t1000_poll(void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; if (t1000->video_options != st_video_options || t1000->enabled != st_enabled) { t1000->video_options = st_video_options; @@ -643,7 +649,7 @@ t1000_recalcattrs(t1000_t *t1000) } static void * -t1000_init(const device_t *info) +t1000_init(UNUSED(const device_t *info)) { t1000_t *t1000 = malloc(sizeof(t1000_t)); memset(t1000, 0, sizeof(t1000_t)); @@ -681,18 +687,18 @@ t1000_init(const device_t *info) } static void -t1000_close(void *p) +t1000_close(void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; free(t1000->vram); free(t1000); } static void -t1000_speed_changed(void *p) +t1000_speed_changed(void *priv) { - t1000_t *t1000 = (t1000_t *) p; + t1000_t *t1000 = (t1000_t *) priv; t1000_recalctimings(t1000); } diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 5bf958d8ab..3f07e6a4e7 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -24,6 +24,7 @@ #include <86box/video.h> #include <86box/machine.h> #include "cpu.h" +#include <86box/plat_unused.h> #include <86box/m_xt_xi8088.h> @@ -67,7 +68,7 @@ xi8088_bios_128kb(void) } static void * -xi8088_init(const device_t *info) +xi8088_init(UNUSED(const device_t *info)) { xi8088.turbo = 1; xi8088.turbo_setting = device_get_config_int("turbo_setting"); diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index e5cebe5524..0da0919175 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -11,12 +11,12 @@ * * * - * Authors: Sarah Walker, + * Authors: Tux, * Miran Grca, * TheCollector1995, * EngiNerd * - * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Tux. * Copyright 2016-2019 Miran Grca. * Copyright 2020 EngiNerd. */ @@ -46,6 +46,7 @@ #include <86box/machine.h> #include <86box/io.h> #include <86box/vid_cga.h> +#include <86box/plat_unused.h> typedef struct { mem_mapping_t scratchpad_mapping; @@ -53,21 +54,22 @@ typedef struct { } zenith_t; static uint8_t -zenith_scratchpad_read(uint32_t addr, void *p) +zenith_scratchpad_read(uint32_t addr, void *priv) { - zenith_t *dev = (zenith_t *) p; + const zenith_t *dev = (zenith_t *) priv; + return dev->scratchpad_ram[addr & 0x3fff]; } static void -zenith_scratchpad_write(uint32_t addr, uint8_t val, void *p) +zenith_scratchpad_write(uint32_t addr, uint8_t val, void *priv) { - zenith_t *dev = (zenith_t *) p; + zenith_t *dev = (zenith_t *) priv; dev->scratchpad_ram[addr & 0x3fff] = val; } static void * -zenith_scratchpad_init(const device_t *info) +zenith_scratchpad_init(UNUSED(const device_t *info)) { zenith_t *dev; @@ -85,9 +87,9 @@ zenith_scratchpad_init(const device_t *info) } static void -zenith_scratchpad_close(void *p) +zenith_scratchpad_close(void *priv) { - zenith_t *dev = (zenith_t *) p; + zenith_t *dev = (zenith_t *) priv; free(dev->scratchpad_ram); free(dev); @@ -110,12 +112,8 @@ static const device_t zenith_scratchpad_device = { void machine_zenith_init(const machine_t *model) { - machine_common_init(model); - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_xt_device); - device_add(&zenith_scratchpad_device); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); @@ -142,6 +140,9 @@ machine_xt_z184_init(const machine_t *model) machine_zenith_init(model); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); + lpt1_remove(); /* only one parallel port */ lpt2_remove(); lpt1_init(0x278); @@ -169,6 +170,9 @@ machine_xt_z151_init(const machine_t *model) machine_zenith_init(model); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_tandy_device); + return ret; } @@ -189,6 +193,9 @@ machine_xt_z159_init(const machine_t *model) machine_zenith_init(model); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_tandy_device); + /* parallel port is on the memory board */ lpt1_remove(); /* only one parallel port */ lpt2_remove(); diff --git a/src/machine/machine.c b/src/machine/machine.c index 893700c7e8..9e530eb3b4 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -10,11 +10,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ @@ -41,6 +39,8 @@ #include <86box/video.h> #include <86box/machine.h> #include <86box/isamem.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> int bios_only = 0; int machine; @@ -72,13 +72,23 @@ machine_init_ex(int m) if (!bios_only) { machine_log("Initializing as \"%s\"\n", machine_getname()); + machine_init_p1(); + + machine_init_gpio(); + machine_init_gpio_acpi(); + + machine_snd = NULL; + is_vpc = 0; + standalone_gameport_type = NULL; gameport_instance_id = 0; /* Set up the architecture flags. */ - // AT = IS_AT(machine); - // PCI = IS_ARCH(machine, MACHINE_BUS_PCI); +#if 0 + AT = IS_AT(machine); + PCI = IS_ARCH(machine, MACHINE_BUS_PCI); +#endif cpu_set(); pc_speed_changed(); @@ -103,6 +113,8 @@ machine_init_ex(int m) /* Reset the fast off stuff. */ cpu_fast_off_reset(); + + pci_flags = 0x00000000; } /* All good, boot the machine! */ @@ -112,17 +124,7 @@ machine_init_ex(int m) if (bios_only || !ret) return ret; - if (gfxcard[0] != VID_NONE) { - if (ibm8514_enabled) { - ibm8514_device_add(); - } - if (xga_enabled) - xga_device_add(); - } - - /* Reset the graphics card (or do nothing if it was already done - by the machine's init function). */ - video_reset(gfxcard[0]); + video_post_reset(); return ret; } @@ -137,15 +139,15 @@ machine_init(void) int machine_available(int m) { - int ret; - device_t *d = (device_t *) machine_get_device(m); + int ret; + const device_t *dev = machine_get_device(m); bios_only = 1; - ret = device_available(d); + ret = device_available(dev); /* Do not check via machine_init_ex() if the device is not NULL and it has a CONFIG_BIOS field. */ - if ((d == NULL) || (ret != -1)) + if ((dev == NULL) || (ret != -1)) ret = machine_init_ex(m); bios_only = 0; @@ -164,15 +166,18 @@ pit_irq0_timer(int new_out, int old_out) } void -machine_common_init(const machine_t *model) +machine_common_init(UNUSED(const machine_t *model)) { + uint8_t cpu_requires_fast_pit = is486 || (!is286 && is8086 && (cpu_s->rspeed >= 8000000)); + cpu_requires_fast_pit = cpu_requires_fast_pit && !cpu_16bitbus; + /* System devices first. */ pic_init(); dma_init(); int pit_type = IS_AT(machine) ? PIT_8254 : PIT_8253; /* Select fast PIT if needed */ - if ((pit_mode == -1 && is486) || pit_mode == 1) + if (((pit_mode == -1) && cpu_requires_fast_pit) || (pit_mode == 1)) pit_type += 2; pit_common_init(pit_type, pit_irq0_timer, NULL); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3302444778..da3dc01e45 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13,11 +13,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ @@ -34,6 +32,10 @@ #include <86box/keyboard.h> #include <86box/sound.h> #include <86box/video.h> +#include <86box/plat_unused.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> // Temporarily here till we move everything out into the right files extern const device_t pcjr_device; @@ -52,6 +54,7 @@ extern const device_t vid_ppc512_device; extern const device_t vid_device_sl; extern const device_t t1200_video_device; extern const device_t compaq_plasma_device; +extern const device_t ps1_2011_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, @@ -136,8 +139,12 @@ const machine_filter_t machine_chipsets[] = { { "SiS 471", MACHINE_CHIPSET_SIS_471 }, { "SiS 496", MACHINE_CHIPSET_SIS_496 }, { "SiS 501", MACHINE_CHIPSET_SIS_501 }, + { "SiS 5501", MACHINE_CHIPSET_SIS_5501 }, { "SiS 5511", MACHINE_CHIPSET_SIS_5511 }, { "SiS 5571", MACHINE_CHIPSET_SIS_5571 }, + { "SiS 5581", MACHINE_CHIPSET_SIS_5581 }, + { "SiS 5591", MACHINE_CHIPSET_SIS_5591 }, + { "SiS (5)600", MACHINE_CHIPSET_SIS_5600 }, { "SMSC VictoryBX-66", MACHINE_CHIPSET_SMSC_VICTORYBX_66 }, { "STPC Client", MACHINE_CHIPSET_STPC_CLIENT }, { "STPC Consumer-II", MACHINE_CHIPSET_STPC_CONSUMER_II }, @@ -164,7 +171,6 @@ const machine_filter_t machine_chipsets[] = { }; /* Machines to add before machine freeze: - - PCChips M773 (440BX + SMSC with AMI BIOS); - TMC Mycomp PCI54ST; - Zeos Quadtel 486. @@ -208,10 +214,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_pc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -222,7 +228,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PC, + .bus_flags = MACHINE_PC5150, .flags = MACHINE_FLAGS_NONE, .ram = { .min = 16, @@ -231,8 +237,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -246,10 +253,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_pc82_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -260,7 +267,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PC, + .bus_flags = MACHINE_PC5150, .flags = MACHINE_FLAGS_NONE, .ram = { .min = 64, @@ -269,8 +276,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -284,10 +292,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_pcjr_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -301,18 +309,19 @@ const machine_t machines[] = { .bus_flags = MACHINE_PCJR, .flags = MACHINE_VIDEO_FIXED, .ram = { - .min = 128, + .min = 64, .max = 640, .step = 64 }, .nvrmask = 0, .kbc_device = NULL, /* TODO: No specific kbd_device yet */ - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &pcjr_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &pcjr_device, .snd_device = NULL, .net_device = NULL }, @@ -322,10 +331,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -345,8 +354,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -360,10 +370,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt86_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -383,8 +393,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt86_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -398,10 +409,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_americxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -421,8 +432,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -436,10 +448,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_amixt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -459,8 +471,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -474,10 +487,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_bw230_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -497,8 +510,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -512,10 +526,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_mpc1600_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -535,8 +549,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -550,10 +565,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_compaq_portable_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -573,8 +588,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_compaq_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -588,10 +604,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_dtk_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -611,8 +627,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -626,10 +643,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pcspirit_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -649,8 +666,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -664,10 +682,49 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_genxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &keyboard_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] GLaBIOS", + .internal_name = "glabios", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_glabios_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -687,8 +744,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -702,10 +760,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_top88_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -725,8 +783,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -740,10 +799,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_super16t_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -763,8 +822,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -778,10 +838,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_super16te_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -801,8 +861,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -816,10 +877,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_jukopc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -839,8 +900,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -854,10 +916,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_kaypropc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -877,8 +939,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -887,15 +950,15 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-500", - .internal_name = "pc500", + .name = "[8088] Micoms XL-7 Turbo", + .internal_name = "mxl7t", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc500_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_xt_micoms_xl7turbo_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -909,14 +972,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_PC, .flags = MACHINE_FLAGS_NONE, .ram = { - .min = 128, + .min = 64, .max = 640, .step = 64 }, .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff00, + .kbc_device = &keyboard_xt_device, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -925,15 +989,15 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-700", - .internal_name = "pc700", + .name = "[8088] Multitech PC-500", + .internal_name = "pc500", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc700_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_xt_pc500_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -953,8 +1017,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -963,15 +1028,15 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Micoms XL-7 Turbo", - .internal_name = "mxl7t", + .name = "[8088] Multitech PC-700", + .internal_name = "pc700", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_micoms_xl7turbo_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_xt_pc700_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -985,14 +1050,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_PC, .flags = MACHINE_FLAGS_NONE, .ram = { - .min = 64, + .min = 128, .max = 640, .step = 64 }, .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_device = &keyboard_pc_device, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1006,10 +1072,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pc4i_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1025,12 +1091,13 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1044,10 +1111,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_m19_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1063,16 +1130,17 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_xt_olivetti_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &m19_vid_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &m19_vid_device, .snd_device = NULL, .net_device = NULL }, @@ -1082,10 +1150,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_openxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1105,8 +1173,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1120,10 +1189,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pb8810_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1139,12 +1208,13 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1158,10 +1228,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_p3105_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1181,8 +1251,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1196,10 +1267,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pxxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1219,8 +1290,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1234,10 +1306,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pravetz16_imko4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1257,8 +1329,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pravetz_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1272,10 +1345,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_sansx16_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1291,12 +1364,13 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1310,10 +1384,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_europc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088_EUROPC, .block = CPU_BLOCK_NONE, @@ -1333,8 +1407,9 @@ const machine_t machines[] = { }, .nvrmask = 15, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1348,10 +1423,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pcxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1371,8 +1446,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1386,10 +1462,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_tandy_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088_EUROPC, .block = CPU_BLOCK_NONE, @@ -1409,12 +1485,13 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_tandy_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_device, .snd_device = NULL, .net_device = NULL }, @@ -1424,10 +1501,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_tandy1000hx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088_EUROPC, .block = CPU_BLOCK_NONE, @@ -1441,18 +1518,19 @@ const machine_t machines[] = { .bus_flags = MACHINE_PC, .flags = MACHINE_VIDEO_FIXED, .ram = { - .min = 256, + .min = 384, .max = 640, .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_tandy_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_device_hx, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_device_hx, .snd_device = NULL, .net_device = NULL }, @@ -1462,10 +1540,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_t1000_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1485,12 +1563,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = &keyboard_xt_t1x00_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &t1000_video_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &t1000_video_device, .snd_device = NULL, .net_device = NULL }, @@ -1500,10 +1579,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_vendex_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1523,8 +1602,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1539,10 +1619,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_laserxt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1562,8 +1642,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1579,10 +1660,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_xi8088_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1602,8 +1683,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = &keyboard_ps2_xi8088_device, - .kbc_p1 = 0xff04, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = &xi8088_device, .fdc_device = NULL, .sio_device = NULL, @@ -1617,10 +1699,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_znic_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1640,8 +1722,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1655,10 +1738,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_z151_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1678,8 +1761,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1693,10 +1777,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_z159_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1716,8 +1800,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1731,10 +1816,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_z184_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1754,12 +1839,13 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &cga_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &cga_device, .snd_device = NULL, .net_device = NULL }, @@ -1769,10 +1855,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_GC100A, .init = machine_xt_p3120_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK_NONE, @@ -1792,8 +1878,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1807,10 +1894,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_v20xt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8088, .block = CPU_BLOCK(CPU_8088), @@ -1830,8 +1917,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -1847,10 +1935,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_pc1512_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -1870,12 +1958,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_1512_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_1512_device, .snd_device = NULL, .net_device = NULL }, @@ -1885,15 +1974,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_pc1640_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -1908,12 +1997,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_1640_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_1640_device, .snd_device = NULL, .net_device = NULL }, @@ -1923,15 +2013,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_pc2086_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -1946,12 +2036,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_pc2086_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_pc2086_device, .snd_device = NULL, .net_device = NULL }, @@ -1961,15 +2052,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_pc3086_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -1984,12 +2075,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_pc3086_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_pc3086_device, .snd_device = NULL, .net_device = NULL }, @@ -1999,15 +2091,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_pc200_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2022,12 +2114,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_200_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_200_device, .snd_device = NULL, .net_device = NULL }, @@ -2037,15 +2130,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ppc512_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2060,12 +2153,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_ppc512_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_ppc512_device, .snd_device = NULL, .net_device = NULL }, @@ -2075,10 +2169,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_compaq_deskpro_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2098,8 +2192,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_compaq_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2113,10 +2208,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_elt_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2136,8 +2231,9 @@ const machine_t machines[] = { }, .nvrmask = 0x3f, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2151,10 +2247,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_m24_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2174,12 +2270,13 @@ const machine_t machines[] = { }, .nvrmask = 15, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &ogc_m24_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &ogc_m24_device, .snd_device = NULL, .net_device = NULL }, @@ -2190,10 +2287,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_m240_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2213,8 +2310,9 @@ const machine_t machines[] = { }, .nvrmask = 15, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff04, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2228,10 +2326,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_iskra3104_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2251,8 +2349,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2266,10 +2365,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_tandy1000sl2_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2289,12 +2388,13 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &vid_device_sl, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &vid_device_sl, .snd_device = NULL, .net_device = NULL }, @@ -2304,10 +2404,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_xt_t1200_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2327,12 +2427,13 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = &keyboard_xt_t1x00_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, - .device = &t1200_video_device, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &t1200_video_device, .snd_device = NULL, .net_device = NULL }, @@ -2342,10 +2443,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_v86p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2365,8 +2466,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2382,10 +2484,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_lxt3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, @@ -2405,8 +2507,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = &keyboard_xt_lxt3_device, - .kbc_p1 = 0xff00, + .kbc_p1 = 0xff, .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2424,10 +2527,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_ibm_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2447,8 +2550,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2463,10 +2567,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps1_m2011_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2481,14 +2585,15 @@ const machine_t machines[] = { .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, .ram = { .min = 512, - .max = 16384, + .max = 15360, .step = 512 }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ps1_2011_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -2502,10 +2607,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_m30_286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286 | CPU_PKG_486SLC_IBM, .block = CPU_BLOCK_NONE, @@ -2525,8 +2630,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2541,10 +2647,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_ibmxt286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2564,8 +2670,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2580,15 +2687,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_ibmatami_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2603,8 +2710,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2620,15 +2728,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_at_cmdpc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2638,13 +2746,14 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 640, - .max = 16384, - .step = 128 + .max = 14912, + .step = 64 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2659,15 +2768,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_at_portableii_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2682,8 +2791,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2698,22 +2808,22 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_at_portableiii_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 16000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 640, .max = 16384, @@ -2721,12 +2831,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &compaq_plasma_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &compaq_plasma_device, .snd_device = NULL, .net_device = NULL }, @@ -2737,10 +2848,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_mr286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2760,8 +2871,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2776,10 +2888,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_pc8_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2799,8 +2911,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2816,10 +2929,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_at_m290_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2839,8 +2952,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2857,10 +2971,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_openat_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -2880,8 +2994,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2897,15 +3012,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_ibmatpx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2920,8 +3035,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2936,15 +3052,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_ibmatquadtel_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2959,8 +3075,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -2975,15 +3092,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_siemens_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 6000000, + .max_bus = 12500000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2998,8 +3115,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3014,10 +3132,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_at_t3100e_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3037,8 +3155,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3053,10 +3172,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_GC103, .init = machine_at_quadt286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3068,7 +3187,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_SOFTFLOAT_ONLY, .ram = { .min = 512, .max = 16384, @@ -3076,8 +3195,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3092,10 +3212,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_GC103, .init = machine_at_tg286m_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3115,8 +3235,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3131,10 +3252,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_NEAT, .init = machine_at_neat_ami_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3154,8 +3275,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* has an Award-branded KBC controller */ + { + .name = "[NEAT] Hyundai Super-286C", + .internal_name = "super286c", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_super286c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 1024, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3170,10 +3332,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_NEAT, .init = machine_at_3302_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3185,7 +3347,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 512, .max = 16384, @@ -3193,8 +3355,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3204,15 +3367,15 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[NEAT] Phoenix 286 clone", + .name = "[NEAT] Arche AMA-2010", .internal_name = "px286", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_NEAT, .init = machine_at_px286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3232,8 +3395,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3248,10 +3412,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_gw286ct_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3271,8 +3435,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3287,10 +3452,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_gdc212m_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3310,8 +3475,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3326,10 +3492,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_award286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3341,16 +3507,17 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_IDE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3365,10 +3532,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_super286tr_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3383,13 +3550,14 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3404,10 +3572,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_spc4200p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3419,7 +3587,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_FLAGS_NONE, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, .max = 2048, @@ -3427,8 +3595,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3443,10 +3612,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_spc4216p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3466,8 +3635,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3482,10 +3652,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_spc4620p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3497,7 +3667,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_VIDEO, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, .max = 5120, @@ -3505,8 +3675,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3521,10 +3692,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_deskmaster286_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, @@ -3535,17 +3706,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3562,10 +3734,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_50_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286 | CPU_PKG_486SLC_IBM, .block = CPU_BLOCK_NONE, @@ -3585,8 +3757,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3601,10 +3774,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_60_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_286 | CPU_PKG_486SLC_IBM, .block = CPU_BLOCK_NONE, @@ -3624,8 +3797,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3643,10 +3817,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps1_m2121_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3666,8 +3840,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3682,10 +3857,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_pc916sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3705,8 +3880,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3721,10 +3897,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_quadt386sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3744,8 +3920,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3760,10 +3937,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, .init = machine_at_arb1374_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3783,8 +3960,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3792,17 +3970,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the AMIKey KBC firmware, which is an updated 'F' type. */ + /* Has the AMIKey-2 KBC. */ { .name = "[ALi M1217] AAEON SBC-350A", .internal_name = "sbc350a", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, .init = machine_at_sbc350a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3822,8 +4000,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3831,19 +4010,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has an AMI KBC firmware, the only photo of this is too low resolution - for me to read what's on the KBC chip, so I'm going to assume AMI 'F' - based on the other known HT18 AMI BIOS strings. */ + /* Has a VIA VT82C42N KBC. */ { - .name = "[ALi M1217] Flytech 386", + .name = "[ALi M1217] Flytech A36", .internal_name = "flytech386", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, .init = machine_at_flytech386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3854,7 +4031,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_AT, .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, @@ -3863,27 +4040,27 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &tvga8900d_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &tvga8900d_device, .snd_device = NULL, .net_device = NULL }, - /* I'm going to assume this has a standard/generic IBM-compatible AT KBC - firmware until the board is identified. */ + /* Has a JetKey KBC without version, shows up as a 'H'. */ { - .name = "[ALi M1217] MR BIOS 386SX clone", - .internal_name = "mr1217", + .name = "[ALi M1217] Chaintech 325AX", + .internal_name = "325ax", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_mr1217_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_325ax_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -3895,7 +4072,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, .max = 16384, @@ -3903,8 +4080,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3912,19 +4090,19 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM PS/2 Type 1 KBC firmware. */ + /* Has a JetKey KBC without version, shows up as a 'H'. */ { - .name = "[ALi M6117] Acrosser PJ-A511M", - .internal_name = "pja511m", + .name = "[ALi M1217] Chaintech 325AX (MR BIOS)", + .internal_name = "mr1217", .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M6117, - .init = machine_at_pja511m_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_mr1217_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_M6117, + .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -3933,17 +4111,58 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, - .max = 32768, + .max = 16384, .step = 1024 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ALi M6117] Acrosser PJ-A511M", + .internal_name = "pja511m", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M6117, + .init = machine_at_pja511m_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_M6117, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3958,10 +4177,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M6117, .init = machine_at_prox1332_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_M6117, .block = CPU_BLOCK_NONE, @@ -3981,8 +4200,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -3999,10 +4219,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_HT18, .init = machine_at_ama932j_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4022,12 +4242,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &oti067_ama932j_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &oti067_ama932j_device, .snd_device = NULL, .net_device = NULL }, @@ -4040,10 +4261,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_INTEL_82335, .init = machine_at_adi386sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4063,8 +4284,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4078,10 +4300,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_INTEL_82335, .init = machine_at_shuttle386sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4101,8 +4323,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4119,10 +4342,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_NEAT, .init = machine_at_cmdsl386sx16_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4142,8 +4365,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4158,10 +4382,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_NEAT, .init = machine_at_neat_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4181,8 +4405,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4197,10 +4422,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_OPTI_291, .init = machine_at_awardsx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4220,8 +4445,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4238,10 +4464,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_VLSI_SCAMP, .init = machine_at_cmdsl386sx25_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4261,12 +4487,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5402_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5402_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -4279,10 +4506,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_VLSI_SCAMP, .init = machine_at_dataexpert386sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4302,8 +4529,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4318,10 +4546,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_VLSI_SCAMP, .init = machine_at_spc6033p_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4341,27 +4569,28 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &ati28800k_spc6033p_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &ati28800k_spc6033p_device, .snd_device = NULL, .net_device = NULL }, /* Has an unknown AMI KBC firmware, I'm going to assume 'F' until a photo or real hardware BIOS string is found. */ { - .name = "[SCAT] KMX-C-02", + .name = "[SCAT] Kaimei KMX-C-02", .internal_name = "kmxc02", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_SCAT, .init = machine_at_kmxc02_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4381,8 +4610,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4397,15 +4627,15 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_WD76C10, .init = machine_at_wd76c10_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 16000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4420,8 +4650,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4438,10 +4669,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_55sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4461,8 +4692,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4477,10 +4709,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_65sx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386SX, .block = CPU_BLOCK_NONE, @@ -4500,8 +4732,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4519,10 +4752,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486SLC, .chipset = MACHINE_CHIPSET_OPTI_283, .init = machine_at_rycleopardlx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_486SLC_IBM, .block = CPU_BLOCK_NONE, @@ -4542,8 +4775,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4553,16 +4787,17 @@ const machine_t machines[] = { }, /* 386DX machines */ + /* Has a Jetkey V3, which identifies as a 'B'. */ { - .name = "[ACC 2168] AMI 386DX clone", + .name = "[ACC 2168] Juko AT046DX3", .internal_name = "acc386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_ACC_2168, .init = machine_at_acc386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -4582,8 +4817,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4598,10 +4834,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_CT_386, .init = machine_at_ecs386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -4621,8 +4857,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4637,10 +4874,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_CT_386, .init = machine_at_spc6000a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -4660,8 +4897,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4670,38 +4908,77 @@ const machine_t machines[] = { .net_device = NULL }, /* Uses Compaq KBC firmware. */ -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) { - .name = "[ISA] Compaq Deskpro 386", + .name = "[ISA] Compaq Deskpro 386 (September 1986)", .internal_name = "deskpro386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_deskpro386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX_DESKPRO386, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 25000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_FLAGS_NONE, .ram = { .min = 1024, - .max = 14336, + .max = 16384, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ISA] Compaq Deskpro 386 (May 1988)", + .internal_name = "deskpro386_05_1988", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_deskpro386_05_1988_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX_DESKPRO386, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 25000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4709,29 +4986,28 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_DESKPRO386) */ { .name = "[ISA] Compaq Portable III (386)", .internal_name = "portableiii386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_portableiii386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, + .min_bus = 20000000, + .max_bus = 20000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, .max = 14336, @@ -4739,12 +5015,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &compaq_plasma_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &compaq_plasma_device, .snd_device = NULL, .net_device = NULL }, @@ -4755,10 +5032,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_micronics386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -4778,8 +5055,89 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ + { + .name = "[ALi M1429] ECS Panda 386V", + .internal_name = "ecs386v", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_ALI_M1429, + .init = machine_at_ecs386v_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0, + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024, + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The board has a "ASII KB-100" which I was not able to find any information about, + but the BIOS sends commands C9 without a parameter and D5, both of which are + Phoenix MultiKey commands. */ + { + .name = "[OPTi 495] U-Board OPTi 495SLC", + .internal_name = "award495", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_OPTI_495, + .init = machine_at_opti495_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4794,10 +5152,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_SIS_310, .init = machine_at_asus386_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX, .block = CPU_BLOCK_NONE, @@ -4817,8 +5175,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4835,10 +5194,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_80_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX | CPU_PKG_486BL, .block = CPU_BLOCK_NONE, @@ -4858,8 +5217,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4869,18 +5229,17 @@ const machine_t machines[] = { }, /* 386DX/486 machines */ - /* The BIOS sends commands C9 without a parameter and D5, both of which are - Phoenix MultiKey commands. */ + /* Has AMIKey F KBC firmware. */ { - .name = "[OPTi 495] Award 486 clone", - .internal_name = "award495", + .name = "[OPTi 495] DataExpert SX495", + .internal_name = "ami495", .type = MACHINE_TYPE_386DX_486, .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_opti495_ami_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -4892,7 +5251,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -4900,8 +5259,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4909,17 +5269,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey F KBC firmware. */ + /* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */ { - .name = "[OPTi 495] DataExpert SX495", - .internal_name = "ami495", + .name = "[OPTi 495] DataExpert SX495 (MR BIOS)", + .internal_name = "mr495", .type = MACHINE_TYPE_386DX_486, .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_ami_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_opti495_mr_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -4931,7 +5291,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -4939,8 +5299,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4948,19 +5309,19 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */ + /* Winbond W83C42 with unknown firmware. */ { - .name = "[OPTi 495] DataExpert SX495 (MR BIOS)", - .internal_name = "mr495", + .name = "[ALi M1429G] DataExpert EXP4349", + .internal_name = "exp4349", .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_mr_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_exp4349_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, + .package = CPU_PKG_386DX | CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -4970,16 +5331,17 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, - .max = 32768, + .max = 49152, .step = 1024 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -4994,10 +5356,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX_486, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_70_type3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX | CPU_PKG_486BL | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5017,8 +5379,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5033,10 +5396,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX_486, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_80_axx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_386DX | CPU_PKG_486BL | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5056,8 +5419,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5078,10 +5442,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_ALI_M1429, .init = machine_at_ali1429_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5093,7 +5457,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5101,8 +5465,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5119,10 +5484,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_CT_CS4031, .init = machine_at_cs4031_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5142,8 +5507,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5159,10 +5525,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_mvi486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5174,7 +5540,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5182,8 +5548,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5198,10 +5565,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_401, .init = machine_at_isa486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5213,7 +5580,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5221,8 +5588,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5237,10 +5605,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_401, .init = machine_at_sis401_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5252,7 +5620,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5260,8 +5628,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5277,10 +5646,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_460, .init = machine_at_av4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5292,7 +5661,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -5300,8 +5669,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ + { + .name = "[SiS 461] Acer V10", + .internal_name = "acerv10", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_acerv10_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI: Adaptec AIC-6360 */ + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5309,17 +5719,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ + /* Has MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ { .name = "[SiS 471] SiS VL-BUS 471 REV. A1", .internal_name = "px471", .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_px471_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5339,8 +5749,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5358,10 +5769,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_VIA_VT82C495, .init = machine_at_486vchd_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5381,8 +5792,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5390,19 +5802,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* According to Deksor on the Win3x.org forum, the BIOS string ends in a -0, - indicating an unknown KBC firmware. But it does send the AMIKey get version - command, so it must expect an AMIKey. */ + /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ { .name = "[VLSI 82C480] HP Vectra 486VL", .internal_name = "vect486vl", .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_VLSI_VL82C480, .init = machine_at_vect486vl_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5422,12 +5832,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5428_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, + .sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/ + .vid_device = &gd5428_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -5438,10 +5849,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_VLSI_VL82C481, .init = machine_at_d824_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, @@ -5461,12 +5872,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5428_onboard_device, - .fdc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5428_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -5477,13 +5889,13 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_ps2_model_70_type4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_i486SX, CPU_i486SX_SLENH, CPU_Am486SX, CPU_Cx486S), .min_bus = 0, .max_bus = 0, .min_voltage = 0, @@ -5492,7 +5904,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO, + .flags = MACHINE_VIDEO | MACHINE_SOFTFLOAT_ONLY, .ram = { .min = 2048, .max = 65536, @@ -5500,8 +5912,9 @@ const machine_t machines[] = { }, .nvrmask = 63, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5519,10 +5932,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_ACC_2168, .init = machine_at_pb410a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5534,7 +5947,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 4096, .max = 36864, @@ -5542,8 +5955,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5558,10 +5972,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_acera1g_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5573,7 +5987,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 4096, .max = 36864, @@ -5581,12 +5995,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5428_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5428_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -5597,10 +6012,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_winbios1429_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5612,7 +6027,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5620,8 +6035,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5629,17 +6045,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ + /* This has a standalone AMI Megakey 1993, which is type 'P'. */ { - .name = "[SiS 461] DEC DECpc LPV", - .internal_name = "decpclpv", + .name = "[IMS 8848] Tekram G486IP", + .internal_name = "g486ip", .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_decpclpv_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_IMS_8848, + .init = machine_at_g486ip_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5650,35 +6066,36 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { - .min = 1024, - .max = 32768, - .step = 1024 + .min = 2048, + .max = 131072, + .step = 2048 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_86c805_onboard_vlb_device, - .vid_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, + .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, - /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ + /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ { - .name = "[SiS 461] Acer V10", - .internal_name = "acerv10", + .name = "[SiS 461] DEC DECpc LPV", + .internal_name = "decpclpv", .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_acerv10_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_decpclpv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5690,7 +6107,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 1024, .max = 32768, @@ -5698,12 +6115,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_86c805_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, @@ -5715,10 +6133,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, .init = machine_at_valuepoint433_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5738,8 +6156,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5747,19 +6166,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an - 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. - The photo of the board shows an AMIKey KBC which is indeed F. */ + /* Has AMI MegaKey KBC. */ { - .name = "[SiS 471] ABit AB-AH4", - .internal_name = "win471", + .name = "[i420TX] J-Bond PCI400C-A", + .internal_name = "pci400ca", .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_win471_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_pci400ca_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5770,17 +6187,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SCSI, .ram = { .min = 1024, .max = 65536, .step = 1024 }, .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_device = &keyboard_ps2_ami_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5789,19 +6207,60 @@ const machine_t machines[] = { .net_device = NULL }, + /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ + /* Has a Fujitsu MBL8042H KBC. */ + { + .name = "[Contaq 82C596A] A-Trend 4GPV5", + .internal_name = "4gpv5", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_CONTAQ_82C596, + .init = machine_at_4gpv5_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMI MegaKey KBC firmware. */ { - .name = "[Contaq 82C597] Green-B", + .name = "[Contaq 82C597] Visionex Green-B", .internal_name = "greenb", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_CONTAQ_82C597, .init = machine_at_greenb_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5821,8 +6280,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5830,17 +6290,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a VIA VT82C42N KBC. */ + /* Version 1.0 has an AMIKEY-2, version 2.0 has a VIA VT82C42N KBC. */ { .name = "[OPTi 895] Jetway J-403TG", .internal_name = "403tg", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_403tg_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5860,8 +6320,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5876,10 +6337,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_403tg_d_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5899,8 +6360,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5915,10 +6377,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_403tg_d_mr_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5938,8 +6400,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -5947,17 +6410,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H keyboard BIOS. */ + /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ { - .name = "[SiS 471] AOpen Vi15G", - .internal_name = "vi15g", + .name = "[OPTi 895] Packard Bell PB450", + .internal_name = "pb450", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_vi15g_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pb450_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -5968,8 +6431,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, .ram = { .min = 1024, .max = 65536, @@ -5977,26 +6440,29 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &gd5428_vlb_onboard_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ + /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an + 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. + The photo of the board shows an AMIKey KBC which is indeed F. */ { - .name = "[SiS 471] ASUS VL/I-486SV2G (GX4)", - .internal_name = "vli486sv2g", + .name = "[SiS 471] ABIT AB-AH4", + .internal_name = "win471", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_vli486sv2g_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_win471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6007,8 +6473,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6016,8 +6482,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6025,17 +6492,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + /* Has AMIKey-2 'H' keyboard BIOS. */ { - .name = "[SiS 471] DTK PKM-0038S E-2", - .internal_name = "dtk486", + .name = "[SiS 471] AOpen Vi15G", + .internal_name = "vi15g", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_dtk486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_vi15g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6047,7 +6514,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6055,8 +6522,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6064,17 +6532,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Unknown Epox VLB Socket 3 board, has AMIKey F keyboard BIOS. */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[SiS 471] Epox 486SX/DX Green", - .internal_name = "ami471", + .name = "[SiS 471] ASUS VL/I-486SV2G (GX4)", + .internal_name = "vli486sv2g", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_ami471_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_vli486sv2g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6085,8 +6553,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6094,8 +6562,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6103,17 +6572,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* TriGem AMIBIOS Pre-Color with TriGem AMI 'Z' keyboard controller */ + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ { - .name = "[SiS 471] TriGem 486G", - .internal_name = "tg486g", + .name = "[SiS 471] DTK PKM-0038S E-2", + .internal_name = "dtk486", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_tg486g_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_dtk486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6124,8 +6593,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6133,8 +6602,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6142,19 +6612,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - - /* 486 machines which utilize the PCI bus */ - /* Machine with ALi M1429G chipset and M1435 southbridge */ + /* Has a Lance LT38C41L with AMIKey F keyboard BIOS. */ { - .name = "[ALi M1429G] MSI MS-4134", - .internal_name = "ms4134", + .name = "[SiS 471] Epox GXA486SG", + .internal_name = "ami471", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_ms4134_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_ami471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6165,17 +6633,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, .ram = { .min = 1024, - .max = 131072, + .max = 65536, .step = 1024 }, - .nvrmask = 255, + .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6183,17 +6652,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* TriGem machine with M1429G and PhoenixBIOS */ + /* TriGem AMIBIOS Pre-Color with TriGem AMI 'Z' keyboard controller */ { - .name = "[ALi M1429G] TriGem 486GP", - .internal_name = "tg486gp", + .name = "[SiS 471] TriGem 486G", + .internal_name = "tg486g", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_tg486gp_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_tg486g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6204,17 +6673,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, /* Has internal video: Western Digital WD90C33-ZZ */ .ram = { .min = 1024, - .max = 131072, + .max = 65536, .step = 1024 }, - .nvrmask = 255, + .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6222,17 +6692,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ + /* Unknown revision phoenix 1993 multikey */ { - .name = "[ALi M1489] AAEON SBC-490", - .internal_name = "sbc490", + .name = "[SiS 471] DEC Venturis 4xx", + .internal_name = "dvent4xx", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_sbc490_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_dvent4xx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6243,36 +6713,36 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE_DUAL | MACHINE_SUPER_IO | MACHINE_APM | MACHINE_VIDEO, .ram = { .min = 1024, .max = 65536, .step = 1024 }, - .nvrmask = 255, + .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &tgui9440_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &s3_phoenix_trio32_onboard_vlb_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[ALi M1489] ABIT AB-PB4", - .internal_name = "abpb4", + .name = "[ALi M1429G] ECS AL486", + .internal_name = "ecsal486", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_abpb4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ecsal486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6283,17 +6753,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, .ram = { .min = 1024, - .max = 65536, + .max = 98304, .step = 1024 }, - .nvrmask = 255, + .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6301,21 +6772,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. - The BIOS string always ends in -U, but the BIOS will send AMIKey commands 0xCA - and 0xCB if command 0xA1 returns a letter in the 0x5x or 0x7x ranges, so I'm - going to give it an AMI 'U' KBC. */ + /* This uses a VIA VT82C42N KBC, which is a clone of type 'F' with additional commands */ { - .name = "[ALi M1489] AMI WinBIOS 486 PCI", - .internal_name = "win486pci", + .name = "[ALi M1429G] Lanner Electronics AP-4100AA", + .internal_name = "ap4100aa", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_win486pci_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ap4100aa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6326,17 +6793,18 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_AT, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, - .max = 65536, + .max = 32768, .step = 1024 }, - .nvrmask = 255, + .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6344,21 +6812,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. - The known BIOS string ends in -E, and the BIOS returns whatever command 0xA1 - returns (but only if command 0xA1 is instant response), so said ALi keyboard - controller likely returns 'E'. */ + /* JETKey V5.0 */ { - .name = "[ALi M1489] MSI MS-4145", - .internal_name = "ms4145", + .name = "[ALi M1429G] A-Trend ATC-1762", + .internal_name = "atc1762", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_ms4145_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_atc1762_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6369,8 +6833,260 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 40960, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486 machines which utilize the PCI bus */ + /* Machine with ALi M1429G chipset and M1435 southbridge */ + /* Has an AMIKEY-2 KBC. */ + { + .name = "[ALi M1429G] MSI MS-4134", + .internal_name = "ms4134", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ms4134_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* TriGem machine with M1429G and PhoenixBIOS */ + { + .name = "[ALi M1429G] TriGem 486GP", + .internal_name = "tg486gp", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_tg486gp_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1489] AAEON SBC-490", + .internal_name = "sbc490", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_sbc490_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &tgui9440_onboard_pci_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. */ + { + .name = "[ALi M1489] ABIT AB-PB4", + .internal_name = "abpb4", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_abpb4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, /* Machine has a PISA slot */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The BIOS string always ends in -U, but the BIOS will send AMIKey commands 0xCA + and 0xCB if command 0xA1 returns a letter in the 0x5x or 0x7x ranges, so I'm + going to give it an AMI 'U' KBC. */ + { + .name = "[ALi M1489] AMI WinBIOS 486 PCI", + .internal_name = "win486pci", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_win486pci_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The known BIOS string ends in -E, and the BIOS returns whatever command 0xA1 + returns (but only if command 0xA1 is instant response), so said ALi keyboard + controller likely returns 'E'. */ + { + .name = "[ALi M1489] MSI MS-4145", + .internal_name = "ms4145", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_ms4145_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 65536, @@ -6378,8 +7094,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6394,10 +7111,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_tf486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6417,8 +7134,49 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an ALi M5042 with phoenix firmware like the ESA TF-486. */ + { + .name = "[ALi M1489] Acrosser AR-B1476", + .internal_name = "arb1476", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_arb1476_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, /* Has onboard video: C&T F65545 */ + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6433,10 +7191,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_pc330_6573_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3_PC330, .block = CPU_BLOCK_NONE, @@ -6448,20 +7206,21 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 1024, .max = 65536, .step = 1024 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5430_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -6472,10 +7231,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_486ap4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6487,7 +7246,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6495,8 +7254,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6511,10 +7271,50 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_ninja_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Phoenix Multikey/42 PS/2 KBC, but unknown version */ + { + .name = "[i420EX] Anigma BAT4IP3e", + .internal_name = "bat4ip3e", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_bat4ip3e_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6526,7 +7326,47 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i420EX] Advanced Integration Research 486PI", + .internal_name = "486pi", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_486pi_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6534,8 +7374,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* absolutely no KBC info */ + { + .name = "[i420EX] ICS SB486P", + .internal_name = "sb486p", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_sb486p_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6550,10 +7431,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_486sp3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6565,7 +7446,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6573,8 +7454,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6589,10 +7471,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_alfredo_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6604,7 +7486,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -6612,8 +7494,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6621,18 +7504,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a - SST 29EE010 Flash chip. */ + /* According to another string seen on the UH19 website, this has AMI 'H' KBC. */ { - .name = "[i420ZX] ASUS PCI/I-486SP3G", - .internal_name = "486sp3g", + .name = "[i420TX] AMI Super Voyager PCI", + .internal_name = "amis76", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_INTEL_420ZX, - .init = machine_at_486sp3g_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_amis76_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6643,8 +7525,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -6652,8 +7534,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6661,17 +7544,18 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */ - { - .name = "[IMS 8848] J-Bond PCI400C-B", - .internal_name = "pci400cb", + /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a + SST 29EE010 Flash chip. */ + { + .name = "[i420ZX] ASUS PCI/I-486SP3G", + .internal_name = "486sp3g", .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_IMS_8848, - .init = machine_at_pci400cb_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .chipset = MACHINE_CHIPSET_INTEL_420ZX, + .init = machine_at_486sp3g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6683,16 +7567,17 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, .ram = { - .min = 2048, + .min = 1024, .max = 131072, - .step = 2048 + .step = 1024 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6700,17 +7585,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has a standalone AMI Megakey 1993, which is type 'P'. */ + /* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */ { - .name = "[IMS 8848] Tekram G486IP", - .internal_name = "g486ip", + .name = "[IMS 8848] J-Bond PCI400C-B", + .internal_name = "pci400cb", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_IMS_8848, - .init = machine_at_g486ip_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_pci400cb_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6721,8 +7606,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -6730,8 +7615,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6746,10 +7632,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_486sp3c_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6769,8 +7655,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6785,10 +7672,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_ls486e_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6799,7 +7686,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -6808,8 +7695,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6817,17 +7705,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS does not send a single non-standard KBC command, so it has a standard PS/2 KBC. */ + /* Has a VIA VT82C42N KBC. */ { .name = "[SiS 496] Micronics M4Li", .internal_name = "m4li", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_m4li_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6847,8 +7735,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6856,17 +7745,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a BestKey KBC which clones AMI type 'H'. */ + /* Revision 1 has a Lance LT38C41L, revision 2 has a Holtek HT6542B. Another variant with a Bestkey KBC might exist as well. */ { .name = "[SiS 496] Rise Computer R418", .internal_name = "r418", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_r418_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6877,7 +7766,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -6886,8 +7775,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6895,7 +7785,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + /* This has a Holtek HT6542B KBC and the BIOS does not send a single non-standard KBC command, so it must be an ASIC that clones the standard IBM PS/2 KBC. */ { .name = "[SiS 496] Soyo 4SAW2", @@ -6903,10 +7793,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_4saw2_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), @@ -6920,14 +7810,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCIV, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 1024, + .min = 2048, .max = 261120, .step = 1024 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6936,17 +7827,17 @@ const machine_t machines[] = { .net_device = NULL }, /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version - of type 'H'. */ + of type 'H'. There are other variants of the board with Holtek HT6542B KBCs. */ { .name = "[SiS 496] Zida Tomato 4DP", .internal_name = "4dps", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_4dps_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6958,16 +7849,57 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { - .min = 1024, + .min = 2048, .max = 261120, .step = 1024 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* AMIKEY-2 */ + { + .name = "[SiS 496] MSI MS-4144", + .internal_name = "ms4144", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_ms4144_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 5120, /* Hack: machine seems to break with less than 5 MBs of RAM */ + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6982,10 +7914,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_atc1415_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7005,8 +7937,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7016,15 +7949,15 @@ const machine_t machines[] = { }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[UMC 8881] ECS Elite UM8810PAIO", + .name = "[UMC 8881] ECS Elite UM8810P-AIO", .internal_name = "ecs486", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_ecs486_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7035,7 +7968,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI, + .bus_flags = MACHINE_PCI | MACHINE_BUS_PS2_LATCH, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -7044,8 +7977,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7055,15 +7989,15 @@ const machine_t machines[] = { }, /* Has AMIKey Z(!) KBC firmware. */ { - .name = "[UMC 8881] Epson Action PC 2600", + .name = "[UMC 8881] Epson ActionPC 2600", .internal_name = "actionpc2600", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_actionpc2600_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7075,7 +8009,48 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 262144, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { + .name = "[UMC 8881] Epson ActionTower 8400", + .internal_name = "actiontower8400", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_actiontower8400_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, .ram = { .min = 1024, .max = 262144, @@ -7083,8 +8058,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7100,10 +8076,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_m919_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7123,8 +8099,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7139,10 +8116,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_spc7700plw_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7162,8 +8139,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7174,14 +8152,14 @@ const machine_t machines[] = { /* This has a Holtek KBC. */ { .name = "[UMC 8881] Shuttle HOT-433A", - .internal_name = "hot433", + .internal_name = "hot433a", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_hot433_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_hot433a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7201,8 +8179,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7217,10 +8196,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_VIA_VT82C496G, .init = machine_at_g486vpa_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7231,7 +8210,7 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCIV, + .bus_flags = MACHINE_PS2_PCIV, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, @@ -7240,8 +8219,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7256,10 +8236,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_VIA_VT82C496G, .init = machine_at_486vipio2_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7271,7 +8251,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 1024, .max = 131072, @@ -7279,8 +8259,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7299,10 +8280,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_CLIENT, .init = machine_at_itoxstar_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -7322,8 +8303,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7339,10 +8321,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, .init = machine_at_arb1423c_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -7354,7 +8336,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -7362,8 +8344,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7379,10 +8362,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, .init = machine_at_arb1479_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -7394,7 +8377,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -7402,8 +8385,50 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Consumer-II] Lanner Electronics IAC-H488", + .internal_name = "iach488", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, + .init = machine_at_iach488_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ + .ram = { + .min = 32768, + .max = 131072, + .step = 32768 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7419,10 +8444,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_ELITE, .init = machine_at_pcm9340_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -7442,8 +8467,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7459,10 +8485,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_MISC, .chipset = MACHINE_CHIPSET_STPC_ATLAS, .init = machine_at_pcm5330_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_STPC, .block = CPU_BLOCK_NONE, @@ -7482,8 +8508,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7505,10 +8532,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_excaliburpci_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7520,7 +8547,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ .ram = { .min = 2048, .max = 131072, @@ -7528,8 +8555,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7544,10 +8572,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_p5mp3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7558,8 +8586,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 196608, @@ -7567,8 +8595,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7583,10 +8612,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_dellxp60_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7597,8 +8626,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7606,8 +8635,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7622,10 +8652,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_opti560l_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7637,7 +8667,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7645,8 +8675,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7663,10 +8694,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_ambradp60_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7678,7 +8709,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7686,8 +8717,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7702,10 +8734,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_valuepointp60_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7717,7 +8749,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_VIDEO_8514A | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7725,12 +8757,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &mach32_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -7741,10 +8774,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_revenge_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7756,7 +8789,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7764,8 +8797,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7773,17 +8807,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMI MegaKey KBC firmware. */ + /* Has AMI MegaKey 'H' KBC firmware. */ { - .name = "[i430LX] Micro Star 586MC1", - .internal_name = "586mc1", + .name = "[i430LX] Gigabyte GA-586IS", + .internal_name = "586is", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_586mc1_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_586is_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7794,8 +8828,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -7803,8 +8837,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7819,10 +8854,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_pb520r_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7834,7 +8869,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 8192, .max = 139264, @@ -7842,12 +8877,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5434_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5434_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -7862,10 +8898,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_OPTI_547_597, .init = machine_at_excalibur_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7877,7 +8913,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 65536, @@ -7885,8 +8921,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7903,10 +8940,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_OPTI_547_597, .init = machine_at_p5vl_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7918,7 +8955,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -7926,8 +8963,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7944,10 +8982,50 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_SIS_501, .init = machine_at_excaliburpci2_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 501] ASUS PCI/I-P5SP4", + .internal_name = "p5sp4", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_p5sp4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET4, .block = CPU_BLOCK_NONE, @@ -7959,16 +9037,59 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Socket 5 machines */ + /* 430NX */ + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430NX] Intel Premiere/PCI II", + .internal_name = "plato", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_plato_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, + .min = 2048, .max = 131072, - .step = 8192 + .step = 2048 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -7976,38 +9097,39 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ + /* Same as Intel Premiere PCI/II, but with a Dell OEM BIOS */ { - .name = "[SiS 501] ASUS PCI/I-P5SP4", - .internal_name = "p5sp4", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_p5sp4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .name = "[i430NX] Dell Dimension XPS Pxxx", + .internal_name = "dellplato", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_dellplato_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { - .package = CPU_PKG_SOCKET4, + .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 60000000, + .min_bus = 50000000, .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, + .min = 2048, .max = 131072, - .step = 8192 + .step = 2048 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8015,32 +9137,30 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - - /* Socket 5 machines */ - /* 430NX */ - /* This has the Phoenix MultiKey KBC firmware. */ + /* This has the Phoenix MultiKey KBC firmware. + This is basically an Intel Premiere/PCI II with a fancier POST screen. */ { - .name = "[i430NX] Intel Premiere/PCI II", - .internal_name = "plato", + .name = "[i430NX] AMBRA DP90 PCI", + .internal_name = "ambradp90", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_plato_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_ambradp90_init, + .p1_handler = NULL, + .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 = 66666667, - .min_voltage = 3520, + .min_voltage = 3380, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 2048, .max = 131072, @@ -8048,8 +9168,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8057,39 +9178,39 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has the Phoenix MultiKey KBC firmware. - This is basically an Intel Premiere/PCI II with a fancier POST screen. */ + /* Has AMI 'H' KBC firmware. */ { - .name = "[i430NX] AMBRA DP90 PCI", - .internal_name = "ambradp90", + .name = "[i430NX] Gigabyte GA-586IP", + .internal_name = "586ip", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_ambradp90_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_586ip_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 66666667, - .min_voltage = 3380, + .min_voltage = 3520, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 1.5 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, .ram = { .min = 2048, - .max = 131072, + .max = 262144, .step = 2048 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8099,15 +9220,15 @@ const machine_t machines[] = { }, /* Has AMI MegaKey KBC firmware. */ { - .name = "[i430NX] Gigabyte GA-586IP", - .internal_name = "430nx", + .name = "[i430NX] Teknor TEK-932", + .internal_name = "tek932", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_430nx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_tek932_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8119,7 +9240,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE | MACHINE_APM, .ram = { .min = 2048, .max = 262144, @@ -8127,8 +9248,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8145,10 +9267,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_acerv30_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8160,7 +9282,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8168,8 +9290,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8184,10 +9307,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_apollo_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8199,7 +9322,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8207,8 +9330,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8225,10 +9349,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_zappa_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8240,16 +9364,17 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8264,10 +9389,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_powermatev_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8279,7 +9404,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8287,8 +9412,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8303,10 +9429,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_hawk_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8318,7 +9444,47 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* KBC On-Chip the VT82C406MV. */ + { + .name = "[i430FX] FIC PT-2000", + .internal_name = "pt2000", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_pt2000_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8326,8 +9492,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8346,10 +9513,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_OPTI_547_597, .init = machine_at_pat54pv_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_K5, CPU_5K86), @@ -8361,7 +9528,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 2048, .max = 65536, @@ -8369,8 +9536,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8386,10 +9554,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_OPTI_547_597, .init = machine_at_hot543_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8401,7 +9569,46 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[OPTi 597] Northgate Computer Systems Elegance Pentium 90", + .internal_name = "ncselp90", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_ncselp90_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_APM | MACHINE_IDE_DUAL | MACHINE_SUPER_IO, .ram = { .min = 8192, .max = 131072, @@ -8409,8 +9616,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8427,10 +9635,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_SIS_501, .init = machine_at_p54sp4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_K5, CPU_5K86), @@ -8442,7 +9650,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8450,8 +9658,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8466,10 +9675,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_SIS_501, .init = machine_at_sq588_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_PENTIUMMMX), @@ -8481,7 +9690,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8489,8 +9698,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8505,10 +9715,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_SIS_501, .init = machine_at_p54sps_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_PENTIUMMMX), @@ -8520,7 +9730,7 @@ const machine_t machines[] = { .max_multi = 1.5 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8528,8 +9738,131 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = &keyboard_at_ami_device, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 5501] MSI MS-5109", + .internal_name = "ms5109", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_ms5109_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[SiS 5501] TriGem Torino", + .internal_name = "torino", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_torino_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9660_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + + /* UMC 889x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[UMC 889x] Shuttle HOT-539", + .internal_name = "hot539", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_UMC_UM8890BF, + .init = machine_at_hot539_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 40000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3600, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8540,17 +9873,18 @@ const machine_t machines[] = { /* Socket 7 (Single Voltage) machines */ /* 430FX */ - /* This has an AMIKey-2, which is an updated version of type 'H'. */ + /* This has an AMIKey-2, which is an updated version of type 'H'. + This also seems to be revision 2.1 with the FDC37C665 SIO. */ { - .name = "[i430FX] ASUS P/I-P54TP4XE", + .name = "[i430FX] ASUS P/I-P55TP4XE", .internal_name = "p54tp4xe", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_p54tp4xe_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8562,7 +9896,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8570,8 +9904,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8581,15 +9916,15 @@ const machine_t machines[] = { }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", + .name = "[i430FX] ASUS P/I-P55TP4XE (MR BIOS)", .internal_name = "p54tp4xe_mr", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_p54tp4xe_mr_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8601,7 +9936,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8609,8 +9944,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8618,17 +9954,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H KBC firmware. */ + /* Has AMIKey H KBC firmware. The KBC itself seems to differ between an AMIKEY-2 and a Winbond W83C42. */ { .name = "[i430FX] DataExpert EXP8551", .internal_name = "exp8551", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_exp8551_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8640,7 +9976,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8648,8 +9984,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8666,10 +10003,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_gw2katx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8681,16 +10018,17 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8706,10 +10044,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_vectra54_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8721,7 +10059,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -8729,12 +10067,13 @@ const machine_t machines[] = { }, .nvrmask = 511, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_phoenix_trio64_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -8747,10 +10086,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_thor_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8762,20 +10101,21 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_phoenix_trio64vplus_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -8788,10 +10128,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_mrthor_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8803,17 +10143,18 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_phoenix_trio64vplus_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -8829,10 +10170,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_endeavor_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = machine_at_endeavor_gpio_handler, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8844,21 +10185,22 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_phoenix_trio64_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_pci_device, + .snd_device = &sb_vibra16s_onboard_device, .net_device = NULL }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ @@ -8868,10 +10210,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_ms5119_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8883,7 +10225,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8891,8 +10233,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8908,10 +10251,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_pb640_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8923,20 +10266,21 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &gd5440_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5440_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -8947,10 +10291,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_mb500n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -8962,7 +10306,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -8970,8 +10314,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8979,17 +10324,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has an AMI 'H' KBC firmware (1992). */ + /* Has an AMI MegaKey 'H' KBC firmware (1992). */ { .name = "[i430FX] QDI FMB", .internal_name = "fmb", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, .init = machine_at_fmb_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX), @@ -9001,7 +10346,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -9009,8 +10354,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9020,19 +10366,17 @@ const machine_t machines[] = { }, /* 430HX */ - /* I can't determine what KBC firmware this has, but given that the Acer V35N and - V60 have Phoenix MultiKey KBC firmware on the chip, I'm going to assume so - does the M3A. */ + /* Has a Phoenix Multikey KBC in the SM(S)C SIO. */ { .name = "[i430HX] Acer M3A", .internal_name = "acerm3a", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_acerm3a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9044,7 +10388,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 8192, .max = 196608, @@ -9052,8 +10396,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9061,17 +10406,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey F KBC firmware. */ + /* Has AMIKey-2 or VIA VT82C42N KBC (depending on the revision) with AMIKEY 'F' KBC firmware. */ { .name = "[i430HX] AOpen AP53", .internal_name = "ap53", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_ap53_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9083,7 +10428,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -9091,8 +10436,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9107,10 +10453,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_8500tuc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9122,7 +10468,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -9130,8 +10476,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9139,18 +10486,18 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] Unable to determine what KBC this has. A list on a Danish site shows - the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ + /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. + A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ { .name = "[i430HX] Supermicro P55T2S", .internal_name = "p55t2s", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_p55t2s_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9162,16 +10509,17 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9181,6 +10529,48 @@ const machine_t machines[] = { }, /* 430VX */ + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430VX] Dell Hannibal+", + .internal_name = "dellhannibalp", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_dellhannibalp_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[i430VX] ECS P5VX-B", @@ -9188,10 +10578,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_p5vxb_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9203,7 +10593,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9211,8 +10601,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9229,10 +10620,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_gw2kte_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9244,7 +10635,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9252,8 +10643,51 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5501 */ + /* Has the Lance LT38C41 KBC. */ + { + .name = "[SiS 5501] Chaintech 5SBM2 (M103)", + .internal_name = "5sbm2", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_5sbm2_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9270,10 +10704,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_SIS_5511, .init = machine_at_ap5s_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9285,7 +10719,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -9293,8 +10727,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9309,10 +10744,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_SIS_5511, .init = machine_at_ms5124_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9324,7 +10759,47 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Megakey 'R' KBC */ + { + .name = "[SiS 5511] AMI Atlas PCI-II", + .internal_name = "amis727", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_amis727_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -9332,8 +10807,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9351,10 +10827,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_acerv35n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_Cx6x86MX), @@ -9366,7 +10842,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 196608, @@ -9374,8 +10850,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9390,10 +10867,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_p55t2p4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9405,7 +10882,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 262144, @@ -9413,8 +10890,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9429,10 +10907,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_m7shi_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9444,7 +10922,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9452,8 +10930,9 @@ const machine_t machines[] = { }, .nvrmask = 511, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9470,10 +10949,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_tc430hx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9485,7 +10964,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -9493,27 +10972,27 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_virge_375_pci_device, .snd_device = NULL, .net_device = NULL }, - /* OEM version of Intel TC430HX, has AMI MegaKey KBC firmware on the PC87306 - Super I/O chip */ + /* OEM version of Intel TC430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { .name = "[i430HX] Toshiba Infinia 7200", .internal_name = "infinia7200", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_infinia7200_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9525,7 +11004,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 131072, @@ -9533,28 +11012,67 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_virge_375_pci_device, .snd_device = NULL, .net_device = NULL }, - /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the - PC87306 Super I/O chip, command 0xA1 returns '5'. - Command 0xA0 copyright string: (C)1994 AMI . */ + /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ + { + .name = "[i430HX] Intel CU430HX", + .internal_name = "cu430hx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_cu430hx_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 196608, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { .name = "[i430HX] Toshiba Equium 5200D", .internal_name = "equium5200", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_equium5200_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9566,21 +11084,22 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the @@ -9593,10 +11112,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_pcv90_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9608,16 +11127,17 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 196608, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9625,17 +11145,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B with the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", .internal_name = "p65up5_cp55t2d", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_p65up5_cp55t2d_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9646,8 +11166,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -9655,8 +11175,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Unknown PS/2 KBC. */ + { + .name = "[i430HX] Radisys EPC-2102", + .internal_name = "epc2102", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_epc2102_init, + .p1_handler = NULL, + .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 = 83333333, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9666,17 +11227,17 @@ const machine_t machines[] = { }, /* 430VX */ - /* This has the VIA VT82C42N KBC. */ + /* This has the VIA VT82C42N or Holtek HT6542B KBC. */ { .name = "[i430VX] AOpen AP5VM", .internal_name = "ap5vm", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_ap5vm_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9688,7 +11249,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9696,8 +11257,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9705,17 +11267,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has AMIKey H KBC firmware (AMIKey-2). */ + /* Has AMIKey H KBC firmware (AMIKey-2) on a BestKey KBC. */ { .name = "[i430VX] ASUS P/I-P55TVP4", .internal_name = "p55tvp4", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_p55tvp4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9726,8 +11288,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 3.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9735,8 +11297,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9752,10 +11315,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_5ivg_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9767,7 +11330,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9775,8 +11338,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9784,17 +11348,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] Has AMIKey 'F' KBC firmware. */ + /* [TEST] Has AMIKey 'F' KBC firmware on a VIA VT82C42N KBC. */ { .name = "[i430VX] Biostar MB-8500TVX-A", .internal_name = "8500tvxa", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_8500tvxa_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9806,7 +11370,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9814,8 +11378,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9831,10 +11396,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_presario2240_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9854,12 +11419,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_trio64v2_dx_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -9870,10 +11436,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_presario4500_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9893,12 +11459,13 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &s3_trio64v2_dx_onboard_pci_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -9909,10 +11476,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_p55va_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9924,7 +11491,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -9932,8 +11499,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9948,10 +11516,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_brio80xx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -9963,16 +11531,17 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, + .min = 16384, .max = 131072, .step = 8192 }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -9989,10 +11558,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_pb680_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10004,20 +11573,21 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -10028,10 +11598,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_pb810_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10043,7 +11613,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, .ram = { .min = 8192, .max = 131072, @@ -10051,8 +11621,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10068,10 +11639,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_mb520n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10083,7 +11654,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10091,8 +11662,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10108,10 +11680,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, .init = machine_at_i430vx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10123,7 +11695,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -10131,8 +11703,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10149,10 +11722,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_nupro592_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10164,7 +11737,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Has internal video: C&T B69000 */ .ram = { .min = 8192, .max = 262144, @@ -10172,8 +11745,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10188,10 +11762,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_tx97_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10203,7 +11777,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -10211,8 +11785,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10220,6 +11795,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ + { + .name = "[i430TX] Gateway Tomahawk", + .internal_name = "tomahawk", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tomahawk_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = &cs4236b_device, + .net_device = &pcnet_am79c973_onboard_device + }, #if defined(DEV_BRANCH) && defined(USE_AN430TX) /* This has the Phoenix MultiKey KBC firmware. */ { @@ -10228,10 +11843,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_an430tx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10251,8 +11866,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10268,10 +11884,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_ym430tx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10283,7 +11899,47 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* PhoenixBIOS 4.0 Rel 6.0 for 430TX, most likely has AMI KBC of some sort. Also has onboard Yamaha YMF701 which can't be emulated yet. */ + { + .name = "[i430TX] Micronics Thunderbolt", + .internal_name = "thunderbolt", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_thunderbolt_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 262144, @@ -10291,8 +11947,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10300,17 +11957,18 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. */ + /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. + A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { .name = "[i430TX] PC Partner MB540N", .internal_name = "mb540n", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_mb540n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10322,7 +11980,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -10330,8 +11988,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10346,10 +12005,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_56a5_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10361,7 +12020,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -10369,8 +12028,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10385,10 +12045,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_p5mms98_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10400,7 +12060,47 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ + { + .name = "[i430TX] TriGem Richmond", + .internal_name = "richmond", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_richmond_init, + .p1_handler = NULL, + .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 = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -10408,8 +12108,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10427,10 +12128,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_VPX, .init = machine_at_ficva502_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10442,7 +12143,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -10450,8 +12151,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10469,10 +12171,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, .init = machine_at_ficpa2012_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10484,7 +12186,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -10492,8 +12194,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10505,36 +12208,37 @@ const machine_t machines[] = { /* SiS 5571 */ /* Has the SiS 5571 chipset with on-chip KBC. */ { - .name = "[SiS 5571] Rise R534F", - .internal_name = "r534f", + .name = "[SiS 5571] Daewoo CB52X-SI", + .internal_name = "cb52xsi", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_r534f_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_cb52xsi_init, + .p1_handler = NULL, + .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 = 83333333, - .min_voltage = 2500, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 393216, + .max = 262144, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10549,10 +12253,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, .init = machine_at_ms5146_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10564,16 +12268,181 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 262144, .step = 8192 }, - .nvrmask = 127, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5571 chipset with on-chip KBC. */ + { + .name = "[SiS 5571] Rise R534F", + .internal_name = "r534f", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5571, + .init = machine_at_r534f_init, + .p1_handler = NULL, + .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 = 83333333, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 393216, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5581 */ + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] ASUS SP97-XV", + .internal_name = "sp97xv", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sp97xv_init, + .p1_handler = NULL, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] BCM SQ-578", + .internal_name = "sq578", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sq578_init, + .p1_handler = NULL, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] MSI MS-5172", + .internal_name = "ms5172", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_ms5172_init, + .p1_handler = NULL, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10581,40 +12450,41 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN IV+] PC Chips M560", - .internal_name = "m560", + .name = "[ALi ALADDiN IV+] MSI MS-5164", + .internal_name = "ms5164", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_m560_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_ms5164_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 83333333, - .min_voltage = 2500, + .min_voltage = 2100, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, + .max = 1048576, .step = 8192 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10624,36 +12494,37 @@ const machine_t machines[] = { }, /* Has the ALi M1543 southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN IV+] MSI MS-5164", - .internal_name = "ms5164", + .name = "[ALi ALADDiN IV+] PC Chips M560", + .internal_name = "m560", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_ms5164_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_m560_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 60000000, + .min_bus = 50000000, .max_bus = 83333333, - .min_voltage = 2100, + .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10671,10 +12542,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, .init = machine_at_p5a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10686,16 +12557,17 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { - .min = 1024, + .min = 8192, .max = 1572864, .step = 8192 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10711,10 +12583,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, .init = machine_at_m579_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10726,7 +12598,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -10734,8 +12606,49 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* M1534c kbc */ + { + .name = "[ALi ALADDiN V] Gateway Lucas", + .internal_name = "gwlucas", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_gwlucas_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCIONLY, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373*/ + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10750,10 +12663,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, .init = machine_at_5aa_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10765,7 +12678,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -10773,8 +12686,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10789,10 +12703,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, .init = machine_at_5ax_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10804,7 +12718,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 1024, .max = 1572864, @@ -10812,8 +12726,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10831,10 +12746,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, .init = machine_at_ax59pro_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10846,7 +12761,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -10854,8 +12769,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10871,10 +12787,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, .init = machine_at_mvp3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10886,7 +12802,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -10894,8 +12810,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10911,10 +12828,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, .init = machine_at_ficva503a_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10926,7 +12843,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -10934,8 +12851,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10951,10 +12869,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, .init = machine_at_5emapro_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -10966,7 +12884,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -10974,8 +12892,51 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -10987,16 +12948,56 @@ const machine_t machines[] = { /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] AOpen AP61", + .internal_name = "ap61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_ap61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i450KX] ASUS P/I-P6RP4", .internal_name = "p6rp4", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_450KX, .init = machine_at_p6rp4_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11007,8 +13008,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, .max = 524288, @@ -11016,8 +13017,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11034,10 +13036,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_acerv60n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11049,7 +13051,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11057,8 +13059,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11066,17 +13069,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", .internal_name = "p65up5_cp6nd", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_p65up5_cp6nd_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11087,8 +13090,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11096,8 +13099,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11105,18 +13109,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The MB-8600TTX has an AMIKey 'F' KBC firmware, so I'm going to assume so does - the MB-8600TTC until someone can actually identify it. */ + /* Has a VIA VT82C42N with likely AMIKey 'F' KBC firmware. */ { .name = "[i440FX] Biostar MB-8600TTC", .internal_name = "8600ttc", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_8600ttc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11128,7 +13131,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11136,8 +13139,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ + { + .name = "[i440FX] Gateway 2000 Venus", + .internal_name = "gw2kvenus", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_gw2kvenus_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 2.0, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11145,16 +13189,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] Gigabyte GA-686NX", .internal_name = "686nx", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_686nx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11166,7 +13211,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11174,8 +13219,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11192,10 +13238,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_ap440fx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11207,7 +13253,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 131072, @@ -11215,8 +13261,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11233,10 +13280,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_vs440fx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11248,7 +13295,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11256,8 +13303,49 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", + .internal_name = "lgibmx61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_lgibmx61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-78xx */ + .ram = { + .min = 40960, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11272,10 +13360,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_m6mi_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11287,7 +13375,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -11295,8 +13383,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11304,19 +13393,17 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* I found a BIOS string of it that ends in -S, but it could be a typo for -5 - (there's quite a few AMI BIOS strings around with typo'd KBC codes), so I'm - going to give it an AMI MegaKey. */ + /* Has a VIA VT82C42N KBC with likely AMI MegaKey firmware. */ { .name = "[i440FX] PC Partner MB600N", .internal_name = "mb600n", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_mb600n_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET8, .block = CPU_BLOCK_NONE, @@ -11328,7 +13415,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11336,8 +13423,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11355,10 +13443,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_PRO_II, .init = machine_at_m729_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11370,7 +13458,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ .ram = { .min = 1024, .max = 1572864, @@ -11378,8 +13466,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11389,17 +13478,17 @@ const machine_t machines[] = { }, /* 440FX */ - /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ + /* The base board has a Holtek HT6542B KBC with AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] ASUS P/I-P65UP5 (C-PKND)", .internal_name = "p65up5_cpknd", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_p65up5_cpknd_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11411,7 +13500,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11419,8 +13508,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11436,10 +13526,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_kn97_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11451,7 +13541,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -11459,8 +13549,9 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11478,10 +13569,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, .init = machine_at_lx6_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11489,11 +13580,52 @@ const machine_t machines[] = { .max_bus = 100000000, .min_voltage = 1500, .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 5.5 + .min_multi = 2.0, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey KBC firmware. */ + { + .name = "[i440LX] Micronics Spitfire", + .internal_name = "spitfire", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_spitfire_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11501,8 +13633,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11510,18 +13643,18 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey KBC firmware. */ + /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ { - .name = "[i440LX] Micronics Spitfire", - .internal_name = "spitfire", + .name = "[i440LX] NEC Mate NX MA30D/23D", + .internal_name = "ma30d", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_spitfire_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_ma30d_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11533,16 +13666,17 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11560,10 +13694,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440EX, .init = machine_at_p6i440e2_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11575,7 +13709,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11583,8 +13717,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11602,10 +13737,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_p2bls_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11617,7 +13752,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7890AB */ .ram = { .min = 8192, .max = 1048576, @@ -11625,8 +13760,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11642,10 +13778,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_p3bf_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11657,7 +13793,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11665,8 +13801,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11682,10 +13819,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_bf6_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11697,7 +13834,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -11705,8 +13842,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11722,10 +13860,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_ax6bc_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11737,7 +13875,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -11745,8 +13883,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11762,10 +13901,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_686bx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11777,7 +13916,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -11785,8 +13924,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11802,10 +13942,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_vei8_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11817,7 +13957,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: Matrox MGA-G200 and sound: Crystal CS4820 */ .ram = { .min = 8192, .max = 1048576, @@ -11825,8 +13965,49 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", + .internal_name = "lgibmx7g", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lgibmx7g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11842,10 +14023,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_s1846_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11857,7 +14038,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 1048576, @@ -11865,13 +14046,14 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &es1371_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &es1371_onboard_device, .net_device = NULL }, /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC @@ -11882,10 +14064,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_p6sba_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11897,7 +14079,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -11905,8 +14087,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11924,10 +14107,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440ZX, .init = machine_at_ms6168_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11938,8 +14121,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11947,12 +14130,13 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &voodoo_3_2000_agp_onboard_8m_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &voodoo_3_2000_agp_onboard_8m_device, .snd_device = NULL, .net_device = NULL }, @@ -11964,10 +14148,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440ZX, .init = machine_at_borapro_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -11978,8 +14162,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_AGP, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -11987,12 +14171,13 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &voodoo_3_2000_agp_onboard_8m_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &voodoo_3_2000_agp_onboard_8m_device, .snd_device = NULL, .net_device = NULL }, @@ -12001,15 +14186,15 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC-6310BXII", .internal_name = "atc6310bxii", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, .init = machine_at_atc6310bxii_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -12021,7 +14206,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12029,8 +14214,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12048,10 +14234,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, .init = machine_at_ficka6130_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -12063,7 +14249,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS ES1938S */ .ram = { .min = 8192, .max = 524288, @@ -12071,8 +14257,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12088,10 +14275,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, .init = machine_at_p3v133_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -12103,7 +14290,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -12111,8 +14298,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12128,10 +14316,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, .init = machine_at_p3v4x_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -12143,7 +14331,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 2097152, @@ -12151,8 +14339,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12168,10 +14357,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, .init = machine_at_gt694va_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, @@ -12183,7 +14372,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ .ram = { .min = 8192, .max = 3145728, @@ -12191,13 +14380,56 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &es1371_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &es1371_onboard_device, + .net_device = NULL + }, + + /* SiS (5)600 */ + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] Freetech/Flexus P6F99", + .internal_name = "p6f99", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_p6f99_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1371_onboard_device, /* ES1373 but we currently don't emulate that. */ .net_device = NULL }, @@ -12211,10 +14443,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1_2, .chipset = MACHINE_CHIPSET_INTEL_440GX, .init = machine_at_fw6400gx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1 | CPU_PKG_SLOT2, .block = CPU_BLOCK_NONE, @@ -12226,7 +14458,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_NOISA, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, .max = 2097152, @@ -12234,8 +14466,9 @@ const machine_t machines[] = { }, .nvrmask = 511, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12254,10 +14487,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1_370, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_s1857_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1 | CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12269,7 +14502,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12277,13 +14510,14 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &es1371_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &es1371_onboard_device, .net_device = NULL }, /* VIA Apollo Pro */ @@ -12295,10 +14529,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1_370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, .init = machine_at_p6bat_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1 | CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12310,7 +14544,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12318,13 +14552,14 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &cmi8738_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cmi8738_onboard_device, .net_device = NULL }, @@ -12338,10 +14573,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT2, .chipset = MACHINE_CHIPSET_INTEL_440GX, .init = machine_at_6gxu_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT2, .block = CPU_BLOCK_NONE, @@ -12353,7 +14588,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI */ .ram = { .min = 16384, .max = 2097152, @@ -12361,8 +14596,9 @@ const machine_t machines[] = { }, .nvrmask = 511, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12378,10 +14614,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT2, .chipset = MACHINE_CHIPSET_INTEL_440GX, .init = machine_at_s2dge_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT2, .block = CPU_BLOCK_NONE, @@ -12393,7 +14629,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 16384, .max = 2097152, @@ -12401,8 +14637,9 @@ const machine_t machines[] = { }, .nvrmask = 511, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12421,10 +14658,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_INTEL_440LX, .init = machine_at_s370slm_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12436,7 +14673,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED, }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12444,8 +14681,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12463,10 +14701,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_awo671r_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12477,8 +14715,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 /* limits assumed */ }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_PCI, /* Machine has EISA, possibly for a riser? */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB | MACHINE_VIDEO, /* Machine has internal video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ .ram = { .min = 8192, .max = 524288, @@ -12486,8 +14724,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12503,10 +14742,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_cubx_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12518,7 +14757,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has quad channel IDE with internal controller: CMD PCI-0648 */ .ram = { .min = 8192, .max = 1048576, @@ -12526,8 +14765,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12543,10 +14783,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_ambx133_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12558,7 +14798,7 @@ const machine_t machines[] = { .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12566,8 +14806,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12585,10 +14826,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_INTEL_440ZX, .init = machine_at_63a1_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12600,7 +14841,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -12608,8 +14849,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12622,15 +14864,15 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC-7020BXII", .internal_name = "atc7020bxii", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, .init = machine_at_atc7020bxii_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12642,7 +14884,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12650,8 +14892,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12659,6 +14902,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has an ITE IT8671F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[SMSC VictoryBX-66] PC Chips M773", + .internal_name = "m773", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, + .init = machine_at_m773_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, /* VIA Apollo Pro */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA @@ -12669,10 +14953,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, .init = machine_at_apas3_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12684,7 +14968,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -12692,8 +14976,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12709,10 +14994,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, .init = machine_at_p6bap_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12724,7 +15009,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB | MACHINE_SOUND, .ram = { .min = 8192, .max = 1572864, @@ -12732,13 +15017,14 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cmi8738_onboard_device, .net_device = NULL }, /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA @@ -12749,10 +15035,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, .init = machine_at_6via90ap_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12764,7 +15050,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_A97, - .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, .max = 3145728, @@ -12772,8 +15058,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12789,10 +15076,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, .init = machine_at_cuv4xls_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET370, .block = CPU_BLOCK_NONE, @@ -12803,8 +15090,8 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_NOI97, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .bus_flags = MACHINE_PS2_NOI97, /* Has Asus-proprietary LAN/SCSI slot */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 16384, .max = 4194304, @@ -12812,13 +15099,14 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = &cmi8738_onboard_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cmi8738_onboard_device, .net_device = NULL }, @@ -12831,10 +15119,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_MISC, .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_vpc2007_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), @@ -12846,7 +15134,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -12854,8 +15142,9 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12870,10 +15159,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_NONE, .chipset = MACHINE_CHIPSET_NONE, .init = NULL, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = 0, .block = CPU_BLOCK_NONE, @@ -12893,8 +15182,9 @@ const machine_t machines[] = { }, .nvrmask = 0, .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12907,9 +15197,23 @@ const machine_t machines[] = { /* Saved copies - jumpers get applied to these. We use also machine_gpio to store IBM PC/XT jumpers as they need more than one byte. */ -static uint16_t machine_p1; +static uint8_t machine_p1_default; +static uint8_t machine_p1; + +static uint32_t machine_gpio_default; static uint32_t machine_gpio; +static uint32_t machine_gpio_acpi_default; +static uint32_t machine_gpio_acpi; + +void *machine_snd = NULL; + +uint8_t +machine_get_p1_default(void) +{ + return machine_p1_default; +} + uint8_t machine_get_p1(void) { @@ -12917,9 +15221,50 @@ machine_get_p1(void) } void -machine_load_p1(int m) +machine_set_p1_default(uint8_t val) +{ + machine_p1 = machine_p1_default = val; +} + +void +machine_set_p1(uint8_t val) +{ + machine_p1 = val; +} + +void +machine_and_p1(uint8_t val) +{ + machine_p1 = machine_p1_default & val; +} + +uint8_t +machine_handle_p1(uint8_t write, uint8_t val) +{ + uint8_t ret = 0xff; + + if (machines[machine].p1_handler) + ret = machines[machine].p1_handler(write, val); + else { + if (write) + machine_p1 = machine_p1_default & val; + else + ret = machine_p1; + } + + return ret; +} + +void +machine_init_p1(void) +{ + machine_p1 = machine_p1_default = machines[machine].kbc_p1; +} + +uint32_t +machine_get_gpio_default(void) { - machine_p1 = machines[machine].kbc_p1; + return machine_gpio_default; } uint32_t @@ -12929,15 +15274,97 @@ machine_get_gpio(void) } void -machine_load_gpio(int m) +machine_set_gpio_default(uint32_t val) +{ + machine_gpio = machine_gpio_default = val; +} + +void +machine_set_gpio(uint32_t val) +{ + machine_gpio = val; +} + +void +machine_and_gpio(uint32_t val) +{ + machine_gpio = machine_gpio_default & val; +} + +uint32_t +machine_handle_gpio(uint8_t write, uint32_t val) +{ + uint32_t ret = 0xffffffff; + + if (machines[machine].gpio_handler) + ret = machines[machine].gpio_handler(write, val); + else { + if (write) + machine_gpio = machine_gpio_default & val; + else + ret = machine_gpio; + } + + return ret; +} + +void +machine_init_gpio(void) +{ + machine_gpio = machine_gpio_default = machines[machine].gpio; +} + +uint32_t +machine_get_gpio_acpi_default(void) +{ + return machine_gpio_acpi_default; +} + +uint32_t +machine_get_gpio_acpi(void) +{ + return machine_gpio_acpi; +} + +void +machine_set_gpio_acpi_default(uint32_t val) +{ + machine_gpio_acpi = machine_gpio_acpi_default = val; +} + +void +machine_set_gpio_acpi(uint32_t val) +{ + machine_gpio_acpi = val; +} + +void +machine_and_gpio_acpi(uint32_t val) +{ + machine_gpio_acpi = machine_gpio_acpi_default & val; +} + +uint32_t +machine_handle_gpio_acpi(uint8_t write, uint32_t val) { - machine_gpio = machines[machine].gpio; + uint32_t ret = 0xffffffff; + + if (machines[machine].gpio_acpi_handler) + ret = machines[machine].gpio_acpi_handler(write, val); + else { + if (write) + machine_gpio_acpi = machine_gpio_acpi_default & val; + else + ret = machine_gpio_acpi; + } + + return ret; } void -machine_set_gpio(uint32_t gpio) +machine_init_gpio_acpi(void) { - machine_gpio = gpio; + machine_gpio_acpi = machine_gpio_acpi_default = machines[machine].gpio_acpi; } int @@ -12946,16 +15373,16 @@ machine_count(void) return ((sizeof(machines) / sizeof(machine_t)) - 1); } -char * +const char * machine_getname(void) { - return ((char *) machines[machine].name); + return (machines[machine].name); } -char * +const char * machine_getname_ex(int m) { - return ((char *) machines[m].name); + return (machines[m].name); } const device_t * @@ -13021,16 +15448,16 @@ machine_get_net_device(int m) return (NULL); } -char * +const char * machine_get_internal_name(void) { - return ((char *) machines[machine].internal_name); + return (machines[machine].internal_name); } -char * +const char * machine_get_internal_name_ex(int m) { - return ((char *) machines[m].internal_name); + return (machines[m].internal_name); } int @@ -13086,12 +15513,12 @@ machine_get_type(int m) } int -machine_get_machine_from_internal_name(char *s) +machine_get_machine_from_internal_name(const char *s) { int c = 0; while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, (const char *) s)) + if (!strcmp(machines[c].internal_name, s)) return c; c++; } diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 6aad805444..d3d5d1ce77 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -13,5 +13,5 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c - smram.c spd.c sst_flash.c) +add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c mmu_2386.c + rom.c row.c smram.c spd.c sst_flash.c) diff --git a/src/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index 5e473f540b..7cd40e9d78 100644 --- a/src/mem/catalyst_flash.c +++ b/src/mem/catalyst_flash.c @@ -55,20 +55,23 @@ enum { }; typedef struct flash_t { - uint8_t command, pad, - pad0, pad1, - *array; - - mem_mapping_t mapping, mapping_h[2]; + uint8_t command; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t *array; + + mem_mapping_t mapping; + mem_mapping_t mapping_h[2]; } flash_t; static char flash_path[1024]; static uint8_t -flash_read(uint32_t addr, void *p) +flash_read(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint8_t ret = 0xff; + const flash_t *dev = (flash_t *) priv; + uint8_t ret = 0xff; addr &= biosmask; @@ -86,16 +89,19 @@ flash_read(uint32_t addr, void *p) else if (addr == 0x00001) ret = 0xB4; /* 28F010 */ break; + + default: + break; } return ret; } static uint16_t -flash_readw(uint32_t addr, void *p) +flash_readw(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint16_t *q; + flash_t *dev = (flash_t *) priv; + const uint16_t *q; addr &= biosmask; @@ -105,10 +111,10 @@ flash_readw(uint32_t addr, void *p) } static uint32_t -flash_readl(uint32_t addr, void *p) +flash_readl(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint32_t *q; + flash_t *dev = (flash_t *) priv; + const uint32_t *q; addr &= biosmask; @@ -118,9 +124,9 @@ flash_readl(uint32_t addr, void *p) } static void -flash_write(uint32_t addr, uint8_t val, void *p) +flash_write(uint32_t addr, uint8_t val, void *priv) { - flash_t *dev = (flash_t *) p; + flash_t *dev = (flash_t *) priv; addr &= biosmask; @@ -141,13 +147,15 @@ flash_write(uint32_t addr, uint8_t val, void *p) } static void -flash_writew(uint32_t addr, uint16_t val, void *p) +flash_writew(UNUSED(uint32_t addr), UNUSED(uint16_t val), UNUSED(void *priv)) { + // } static void -flash_writel(uint32_t addr, uint32_t val, void *p) +flash_writel(UNUSED(uint32_t addr), UNUSED(uint32_t val), UNUSED(void *priv)) { + // } static void @@ -179,9 +187,9 @@ catalyst_flash_reset(void *priv) } static void * -catalyst_flash_init(const device_t *info) +catalyst_flash_init(UNUSED(const device_t *info)) { - FILE *f; + FILE *fp; flash_t *dev; dev = malloc(sizeof(flash_t)); @@ -199,24 +207,24 @@ catalyst_flash_init(const device_t *info) dev->command = CMD_RESET; - f = nvr_fopen(flash_path, "rb"); - if (f) { - (void) !fread(dev->array, 0x20000, 1, f); - fclose(f); + fp = nvr_fopen(flash_path, "rb"); + if (fp) { + (void) !fread(dev->array, 0x20000, 1, fp); + fclose(fp); } return dev; } static void -catalyst_flash_close(void *p) +catalyst_flash_close(void *priv) { - FILE *f; - flash_t *dev = (flash_t *) p; + FILE *fp; + flash_t *dev = (flash_t *) priv; - f = nvr_fopen(flash_path, "wb"); - fwrite(dev->array, 0x20000, 1, f); - fclose(f); + fp = nvr_fopen(flash_path, "wb"); + fwrite(dev->array, 0x20000, 1, fp); + fclose(fp); free(dev->array); dev->array = NULL; diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index e29d161397..8e4a6cc141 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -23,13 +23,18 @@ #include #include <86box/86box.h> #include <86box/i2c.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct i2c_eeprom_t { void *i2c; - uint8_t addr, *data, writable; - - uint32_t addr_mask, addr_register; - uint8_t addr_len, addr_pos; + uint8_t addr; + uint8_t *data; + uint8_t writable; + + uint32_t addr_mask; + uint32_t addr_register; + uint8_t addr_len; + uint8_t addr_pos; } i2c_eeprom_t; #ifdef ENABLE_I2C_EEPROM_LOG @@ -51,11 +56,11 @@ i2c_eeprom_log(const char *fmt, ...) #endif static uint8_t -i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv) +i2c_eeprom_start(UNUSED(void *bus), uint8_t addr, uint8_t read, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; - i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr); + i2c_eeprom_log("I2C EEPROM %s %02X: start(%c)\n", i2c_getbusname(dev->i2c), dev->addr, read ? 'R' : 'W'); if (!read) { dev->addr_pos = 0; @@ -66,20 +71,19 @@ i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv) } static uint8_t -i2c_eeprom_read(void *bus, uint8_t addr, void *priv) +i2c_eeprom_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; uint8_t ret = dev->data[dev->addr_register]; i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret); - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return ret; } static uint8_t -i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) +i2c_eeprom_write(UNUSED(void *bus), uint8_t addr, uint8_t data, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; @@ -95,8 +99,7 @@ i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable); if (dev->writable) dev->data[dev->addr_register] = data; - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return dev->writable; } @@ -104,7 +107,7 @@ i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) } static void -i2c_eeprom_stop(void *bus, uint8_t addr, void *priv) +i2c_eeprom_stop(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; @@ -132,7 +135,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w uint32_t pow_size = 1 << log2i(size); if (pow_size < size) size = pow_size << 1; - size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */ + if (size >= 8388608) + size = 8388608; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits from command address */ i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable); @@ -144,7 +148,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */ dev->addr_mask = size - 1; - i2c_sethandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_sethandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); return dev; } @@ -156,7 +161,8 @@ i2c_eeprom_close(void *dev_handle) i2c_eeprom_log("I2C EEPROM %s %02X: close()\n", i2c_getbusname(dev->i2c), dev->addr); - i2c_removehandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_removehandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); free(dev); } diff --git a/src/mem/intel_flash.c b/src/mem/intel_flash.c index af7a71eea3..7949f302a3 100644 --- a/src/mem/intel_flash.c +++ b/src/mem/intel_flash.c @@ -58,34 +58,39 @@ enum { }; typedef struct flash_t { - uint8_t command, status, - pad, flags, - *array; - - uint16_t flash_id, pad16; - - uint32_t program_addr, - block_start[BLOCKS_NUM], block_end[BLOCKS_NUM], - block_len[BLOCKS_NUM]; - - mem_mapping_t mapping[4], mapping_h[16]; + uint8_t command; + uint8_t status; + uint8_t pad; + uint8_t flags; + uint8_t *array; + + uint16_t flash_id; + uint16_t pad16; + + uint32_t program_addr; + uint32_t block_start[BLOCKS_NUM]; + uint32_t block_end[BLOCKS_NUM]; + uint32_t block_len[BLOCKS_NUM]; + + mem_mapping_t mapping[4]; + mem_mapping_t mapping_h[16]; } flash_t; static char flash_path[1024]; static uint8_t -flash_read(uint32_t addr, void *p) +flash_read(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint8_t ret = 0xff; + const flash_t *dev = (flash_t *) priv; + uint8_t ret = 0xff; if (dev->flags & FLAG_INV_A16) addr ^= 0x10000; addr &= biosmask; switch (dev->command) { - case CMD_READ_ARRAY: default: + case CMD_READ_ARRAY: ret = dev->array[addr]; break; @@ -105,11 +110,11 @@ flash_read(uint32_t addr, void *p) } static uint16_t -flash_readw(uint32_t addr, void *p) +flash_readw(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint16_t *q; - uint16_t ret = 0xffff; + flash_t *dev = (flash_t *) priv; + const uint16_t *q; + uint16_t ret = 0xffff; if (dev->flags & FLAG_INV_A16) addr ^= 0x10000; @@ -123,8 +128,8 @@ flash_readw(uint32_t addr, void *p) if (dev->flags & FLAG_WORD) switch (dev->command) { - case CMD_READ_ARRAY: default: + case CMD_READ_ARRAY: break; case CMD_IID: @@ -143,10 +148,10 @@ flash_readw(uint32_t addr, void *p) } static uint32_t -flash_readl(uint32_t addr, void *p) +flash_readl(uint32_t addr, void *priv) { - flash_t *dev = (flash_t *) p; - uint32_t *q; + flash_t *dev = (flash_t *) priv; + const uint32_t *q; if (dev->flags & FLAG_INV_A16) addr ^= 0x10000; @@ -158,10 +163,9 @@ flash_readl(uint32_t addr, void *p) } static void -flash_write(uint32_t addr, uint8_t val, void *p) +flash_write(uint32_t addr, uint8_t val, void *priv) { - flash_t *dev = (flash_t *) p; - int i; + flash_t *dev = (flash_t *) priv; uint32_t bb_mask = biosmask & 0xffffe000; if (biosmask == 0x7ffff) bb_mask &= 0xffff8000; @@ -175,7 +179,7 @@ flash_write(uint32_t addr, uint8_t val, void *p) switch (dev->command) { case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { - for (i = 0; i < 6; i++) { + for (uint8_t i = 0; i < 6; i++) { if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]); } @@ -200,7 +204,7 @@ flash_write(uint32_t addr, uint8_t val, void *p) dev->status = 0; break; case CMD_ERASE_SETUP: - for (i = 0; i < 7; i++) { + for (uint8_t i = 0; i < 7; i++) { if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) dev->program_addr = i; } @@ -209,15 +213,17 @@ flash_write(uint32_t addr, uint8_t val, void *p) case CMD_PROGRAM_SETUP_ALT: dev->program_addr = addr; break; + + default: + break; } } } static void -flash_writew(uint32_t addr, uint16_t val, void *p) +flash_writew(uint32_t addr, uint16_t val, void *priv) { - flash_t *dev = (flash_t *) p; - int i; + flash_t *dev = (flash_t *) priv; uint32_t bb_mask = biosmask & 0xffffe000; if (biosmask == 0x7ffff) bb_mask &= 0xffff8000; @@ -232,7 +238,7 @@ flash_writew(uint32_t addr, uint16_t val, void *p) switch (dev->command) { case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { - for (i = 0; i < 6; i++) { + for (uint8_t i = 0; i < 6; i++) { if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]); } @@ -257,7 +263,7 @@ flash_writew(uint32_t addr, uint16_t val, void *p) dev->status = 0; break; case CMD_ERASE_SETUP: - for (i = 0; i < 7; i++) { + for (uint8_t i = 0; i < 7; i++) { if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) dev->program_addr = i; } @@ -266,23 +272,26 @@ flash_writew(uint32_t addr, uint16_t val, void *p) case CMD_PROGRAM_SETUP_ALT: dev->program_addr = addr; break; + + default: + break; } } } static void -flash_writel(uint32_t addr, uint32_t val, void *p) +flash_writel(UNUSED(uint32_t addr), UNUSED(uint32_t val), UNUSED(void *priv)) { #if 0 - flash_writew(addr, val & 0xffff, p); - flash_writew(addr + 2, (val >> 16) & 0xffff, p); + flash_writew(addr, val & 0xffff, priv); + flash_writew(addr + 2, (val >> 16) & 0xffff, priv); #endif } static void intel_flash_add_mappings(flash_t *dev) { - int max = 2; + uint8_t max = 2; uint32_t base; uint32_t fbase; uint32_t sub = 0x20000; @@ -295,7 +304,7 @@ intel_flash_add_mappings(flash_t *dev) max = 4; } - for (int i = 0; i < max; i++) { + for (uint8_t i = 0; i < max; i++) { if (biosmask == 0x7ffff) base = 0x80000 + (i << 16); else if (biosmask == 0x3ffff) @@ -338,7 +347,7 @@ intel_flash_reset(void *priv) static void * intel_flash_init(const device_t *info) { - FILE *f; + FILE *fp; flash_t *dev; uint8_t type = info->local & 0xff; @@ -503,42 +512,42 @@ intel_flash_init(const device_t *info) dev->command = CMD_READ_ARRAY; dev->status = 0; - f = nvr_fopen(flash_path, "rb"); - if (f) { - (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); + fp = nvr_fopen(flash_path, "rb"); + if (fp) { + (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, fp); if (dev->block_len[BLOCK_MAIN2]) - (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f); + (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, fp); if (dev->block_len[BLOCK_MAIN3]) - (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f); + (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, fp); if (dev->block_len[BLOCK_MAIN4]) - (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f); + (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, fp); - (void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f); - (void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f); - fclose(f); + (void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, fp); + (void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, fp); + fclose(fp); } return dev; } static void -intel_flash_close(void *p) +intel_flash_close(void *priv) { - FILE *f; - flash_t *dev = (flash_t *) p; + FILE *fp; + flash_t *dev = (flash_t *) priv; - f = nvr_fopen(flash_path, "wb"); - fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); + fp = nvr_fopen(flash_path, "wb"); + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, fp); if (dev->block_len[BLOCK_MAIN2]) - fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f); + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, fp); if (dev->block_len[BLOCK_MAIN3]) - fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f); + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, fp); if (dev->block_len[BLOCK_MAIN4]) - fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f); + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, fp); - fwrite(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f); - fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f); - fclose(f); + fwrite(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, fp); + fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, fp); + fclose(fp); free(dev->array); dev->array = NULL; diff --git a/src/mem/mem.c b/src/mem/mem.c index 3008e658c3..188aa49d0c 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -29,6 +29,7 @@ #include "cpu.h" #include "x86_ops.h" #include "x86.h" +#include "x86seg_common.h" #include <86box/machine.h> #include <86box/m_xt_xi8088.h> #include <86box/config.h> @@ -69,7 +70,7 @@ page_t *pages; /* RAM page table */ page_t **page_lookup; /* pagetable lookup */ uint32_t pages_sz; /* #pages in table */ -uint8_t *ram; +uint8_t *ram; /* the virtual RAM */ uint8_t *ram2; /* the virtual RAM */ uint8_t page_ff[4096]; uint32_t rammask; @@ -119,17 +120,20 @@ int purgeable_page_count = 0; uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ +mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; +mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; + /* FIXME: re-do this with a 'mem_ops' struct. */ static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ static uint8_t *readlookupp; static uint8_t *writelookupp; static mem_mapping_t *base_mapping; static mem_mapping_t *last_mapping; -static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; -static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; +static uint8_t _mem_wp[MEM_MAPPINGS_NO]; +static uint8_t _mem_wp_bus[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_state_t _mem_state[MEM_MAPPINGS_NO]; static uint32_t remap_start_addr; @@ -162,7 +166,7 @@ mem_log(const char *fmt, ...) int mem_addr_is_ram(uint32_t addr) { - mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS]; + const mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS]; return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_mid_mapping2) || (mapping == &ram_remapped_mapping); @@ -242,7 +246,7 @@ flushmmucache_nopc(void) void mem_flush_write_page(uint32_t addr, uint32_t virt) { - page_t *page_target = &pages[addr >> 12]; + const page_t *page_target = &pages[addr >> 12]; #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) uint32_t a; #endif @@ -522,7 +526,7 @@ mmutranslate_noabrt_pae(uint32_t addr, int rw) addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8); temp = rammap64(addr4) & 0x000000ffffffffffULL; - ; + temp3 = temp & temp4; if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) @@ -705,7 +709,7 @@ read_mem_b(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - ret = map->read_b(addr, map->p); + ret = map->read_b(addr, map->priv); resub_cycles(old_cycles); @@ -728,9 +732,9 @@ read_mem_w(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - ret = map->read_w(addr, map->p); + ret = map->read_w(addr, map->priv); else if (map && map->read_b) - ret = map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + ret = map->read_b(addr, map->priv) | (map->read_b(addr + 1, map->priv) << 8); } resub_cycles(old_cycles); @@ -749,7 +753,7 @@ write_mem_b(uint32_t addr, uint8_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_b) - map->write_b(addr, val, map->p); + map->write_b(addr, val, map->priv); resub_cycles(old_cycles); } @@ -770,10 +774,10 @@ write_mem_w(uint32_t addr, uint16_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map) { if (map->write_w) - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->priv); else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); } } } @@ -805,7 +809,7 @@ readmembl(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - return map->read_b(addr, map->p); + return map->read_b(addr, map->priv); return 0xff; } @@ -839,7 +843,7 @@ writemembl(uint32_t addr, uint8_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_b) - map->write_b(addr, val, map->p); + map->write_b(addr, val, map->priv); } /* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ @@ -862,7 +866,7 @@ readmembl_no_mmut(uint32_t addr, uint32_t a64) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - return map->read_b(addr, map->p); + return map->read_b(addr, map->priv); return 0xff; } @@ -892,7 +896,7 @@ writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_b) - map->write_b(addr, val, map->p); + map->write_b(addr, val, map->priv); } uint16_t @@ -944,10 +948,10 @@ readmemwl(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - return map->read_w(addr, map->p); + return map->read_w(addr, map->priv); if (map && map->read_b) { - return map->read_b(addr, map->p) | ((uint16_t) (map->read_b(addr + 1, map->p)) << 8); + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } return 0xffff; @@ -1016,13 +1020,13 @@ writememwl(uint32_t addr, uint16_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_w) { - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->priv); return; } if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); return; } } @@ -1064,10 +1068,10 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - return map->read_w(addr, map->p); + return map->read_w(addr, map->priv); if (map && map->read_b) { - return map->read_b(addr, map->p) | ((uint16_t) (map->read_b(addr + 1, map->p)) << 8); + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } return 0xffff; @@ -1119,13 +1123,13 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_w) { - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->priv); return; } if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); return; } } @@ -1193,13 +1197,13 @@ readmemll(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->p); + return map->read_l(addr, map->priv); if (map && map->read_w) - return map->read_w(addr, map->p) | ((uint32_t) (map->read_w(addr + 2, map->p)) << 16); + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); if (map && map->read_b) - return map->read_b(addr, map->p) | ((uint32_t) (map->read_b(addr + 1, map->p)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->p)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); return 0xffffffff; } @@ -1280,19 +1284,19 @@ writememll(uint32_t addr, uint32_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->p); + map->write_l(addr, val, map->priv); return; } if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); return; } if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); return; } } @@ -1334,13 +1338,13 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->p); + return map->read_l(addr, map->priv); if (map && map->read_w) - return map->read_w(addr, map->p) | ((uint32_t) (map->read_w(addr + 2, map->p)) << 16); + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); if (map && map->read_b) - return map->read_b(addr, map->p) | ((uint32_t) (map->read_b(addr + 1, map->p)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->p)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); return 0xffffffff; } @@ -1391,19 +1395,19 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->p); + map->write_l(addr, val, map->priv); return; } if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); return; } if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); return; } } @@ -1469,7 +1473,7 @@ readmemql(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->p) | ((uint64_t) map->read_l(addr + 4, map->p) << 32); + return map->read_l(addr, map->priv) | ((uint64_t) map->read_l(addr + 4, map->priv) << 32); return readmemll(addr) | ((uint64_t) readmemll(addr + 4) << 32); } @@ -1548,26 +1552,26 @@ writememql(uint32_t addr, uint64_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->p); - map->write_l(addr + 4, val >> 32, map->p); + map->write_l(addr, val, map->priv); + map->write_l(addr + 4, val >> 32, map->priv); return; } if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - map->write_w(addr + 4, val >> 32, map->p); - map->write_w(addr + 6, val >> 48, map->p); + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + map->write_w(addr + 4, val >> 32, map->priv); + map->write_w(addr + 6, val >> 48, map->priv); return; } if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - map->write_b(addr + 4, val >> 32, map->p); - map->write_b(addr + 5, val >> 40, map->p); - map->write_b(addr + 6, val >> 48, map->p); - map->write_b(addr + 7, val >> 56, map->p); + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + map->write_b(addr + 4, val >> 32, map->priv); + map->write_b(addr + 5, val >> 40, map->priv); + map->write_b(addr + 6, val >> 48, map->priv); + map->write_b(addr + 7, val >> 56, map->priv); return; } } @@ -1583,40 +1587,38 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - for (i = 0; i < num; i++) { - if (cr0 >> 31) { - if (write && ((i == 0) || !(addr & 0xfff))) - cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); - - if (cond) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal(addr, write); - a64[i] = (uint32_t) a; - - high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); - } else if (!(addr & 0xfff)) { - a = mmutranslatereal(last_addr, write); - a64[i] = (uint32_t) a; - - high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); - - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { + if (cr0 >> 31) for (i = 0; i < num; i++) { + if (write && ((i == 0) || !(addr & 0xfff))) + cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); + + if (cond) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal(addr, write); + a64[i] = (uint32_t) a; + + high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); + } else if (!(addr & 0xfff)) { + a = mmutranslatereal(last_addr, write); + a64[i] = (uint32_t) a; + + high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); + + if (!cpu_state.abrt) { a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - } else - mmu_perm = page_lookupp[addr >> 12]; - } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else + mmu_perm = page_lookupp[addr >> 12]; addr++; } @@ -1631,10 +1633,10 @@ mem_readb_phys(uint32_t addr) mem_logical_addr = 0xffffffff; if (map) { - if (map->exec) + if (cpu_use_exec && map->exec) ret = map->exec[(addr - map->base) & map->mask]; else if (map->read_b) - ret = map->read_b(addr, map->p); + ret = map->read_b(addr, map->priv); } return ret; @@ -1643,17 +1645,17 @@ mem_readb_phys(uint32_t addr) uint16_t mem_readw_phys(uint32_t addr) { - mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint16_t ret; - uint16_t *p; + mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; + uint16_t ret; + const uint16_t *p; mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) - ret = map->read_w(addr, map->p); + ret = map->read_w(addr, map->priv); else { ret = mem_readb_phys(addr + 1) << 8; ret |= mem_readb_phys(addr); @@ -1665,17 +1667,17 @@ mem_readw_phys(uint32_t addr) uint32_t mem_readl_phys(uint32_t addr) { - mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint32_t ret; - uint32_t *p; + mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; + uint32_t ret; + const uint32_t *p; mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) - ret = map->read_l(addr, map->p); + ret = map->read_l(addr, map->priv); else { ret = mem_readw_phys(addr + 2) << 16; ret |= mem_readw_phys(addr); @@ -1711,10 +1713,10 @@ mem_writeb_phys(uint32_t addr, uint8_t val) mem_logical_addr = 0xffffffff; if (map) { - if (map->exec) + if (cpu_use_exec && map->exec) map->exec[(addr - map->base) & map->mask] = val; else if (map->write_b) - map->write_b(addr, val, map->p); + map->write_b(addr, val, map->priv); } } @@ -1726,11 +1728,11 @@ mem_writew_phys(uint32_t addr, uint16_t val) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->priv); else { mem_writeb_phys(addr, val & 0xff); mem_writeb_phys(addr + 1, (val >> 8) & 0xff); @@ -1745,11 +1747,11 @@ mem_writel_phys(uint32_t addr, uint32_t val) mem_logical_addr = 0xffffffff; - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { + if (cpu_use_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) - map->write_l(addr, val, map->p); + map->write_l(addr, val, map->priv); else { mem_writew_phys(addr, val & 0xffff); mem_writew_phys(addr + 2, (val >> 16) & 0xffff); @@ -1759,9 +1761,9 @@ mem_writel_phys(uint32_t addr, uint32_t val) void mem_write_phys(void *src, uint32_t addr, int transfer_size) { - uint8_t *pb; - uint16_t *pw; - uint32_t *pl; + const uint8_t *pb; + const uint16_t *pw; + const uint32_t *pl; if (transfer_size == 4) { pl = (uint32_t *) src; @@ -1776,49 +1778,49 @@ mem_write_phys(void *src, uint32_t addr, int transfer_size) } uint8_t -mem_read_ram(uint32_t addr, void *priv) +mem_read_ram(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; } uint16_t -mem_read_ramw(uint32_t addr, void *priv) +mem_read_ramw(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Read W %04X from %08X\n", *(uint16_t *) &ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; } uint32_t -mem_read_raml(uint32_t addr, void *priv) +mem_read_raml(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Read L %08X from %08X\n", *(uint32_t *) &ram[addr], addr); #endif - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; } uint8_t -mem_read_ram_2gb(uint32_t addr, void *priv) +mem_read_ram_2gb(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) @@ -1831,7 +1833,7 @@ mem_read_ram_2gb(uint32_t addr, void *priv) } uint16_t -mem_read_ram_2gbw(uint32_t addr, void *priv) +mem_read_ram_2gbw(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) @@ -1844,7 +1846,7 @@ mem_read_ram_2gbw(uint32_t addr, void *priv) } uint32_t -mem_read_ram_2gbl(uint32_t addr, void *priv) +mem_read_ram_2gbl(uint32_t addr, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) @@ -1858,71 +1860,71 @@ mem_read_ram_2gbl(uint32_t addr, void *priv) #ifdef USE_NEW_DYNAREC static inline int -page_index(page_t *p) +page_index(page_t *page) { - return ((uintptr_t) p - (uintptr_t) pages) / sizeof(page_t); + return ((uintptr_t) page - (uintptr_t) pages) / sizeof(page_t); } void -page_add_to_evict_list(page_t *p) +page_add_to_evict_list(page_t *page) { - pages[purgable_page_list_head].evict_prev = page_index(p); - p->evict_next = purgable_page_list_head; - p->evict_prev = 0; + pages[purgable_page_list_head].evict_prev = page_index(page); + page->evict_next = purgable_page_list_head; + page->evict_prev = 0; purgable_page_list_head = pages[purgable_page_list_head].evict_prev; purgeable_page_count++; } void -page_remove_from_evict_list(page_t *p) +page_remove_from_evict_list(page_t *page) { - if (!page_in_evict_list(p)) + if (!page_in_evict_list(page)) fatal("page_remove_from_evict_list: not in evict list!\n"); - if (p->evict_prev) - pages[p->evict_prev].evict_next = p->evict_next; + if (page->evict_prev) + pages[page->evict_prev].evict_next = page->evict_next; else - purgable_page_list_head = p->evict_next; - if (p->evict_next) - pages[p->evict_next].evict_prev = p->evict_prev; - p->evict_prev = EVICT_NOT_IN_LIST; + purgable_page_list_head = page->evict_next; + if (page->evict_next) + pages[page->evict_next].evict_prev = page->evict_prev; + page->evict_prev = EVICT_NOT_IN_LIST; purgeable_page_count--; } void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; uint64_t byte_mask = (uint64_t) 1 << (addr & PAGE_BYTE_MASK_MASK); - p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + page->mem[addr & 0xfff] = val; + page->dirty_mask |= mask; + if ((page->code_present_mask & mask) && !page_in_evict_list(page)) + page_add_to_evict_list(page); + page->byte_dirty_mask[byte_offset] |= byte_mask; + if ((page->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(page)) + page_add_to_evict_list(page); } } void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint16_t *) &page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint16_t *) &page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; @@ -1930,34 +1932,34 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) if ((addr & 0xf) == 0xf) mask |= (mask << 1); - *(uint16_t *) &p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + *(uint16_t *) &page->mem[addr & 0xfff] = val; + page->dirty_mask |= mask; + if ((page->code_present_mask & mask) && !page_in_evict_list(page)) + page_add_to_evict_list(page); if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { - p->byte_dirty_mask[byte_offset + 1] |= 1; - if ((p->byte_code_present_mask[byte_offset + 1] & 1) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + page->byte_dirty_mask[byte_offset + 1] |= 1; + if ((page->byte_code_present_mask[byte_offset + 1] & 1) && !page_in_evict_list(page)) + page_add_to_evict_list(page); } else byte_mask |= (byte_mask << 1); - p->byte_dirty_mask[byte_offset] |= byte_mask; + page->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + if ((page->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(page)) + page_add_to_evict_list(page); } } void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint32_t *) &page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint32_t *) &page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; @@ -1965,85 +1967,85 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) if ((addr & 0xf) >= 0xd) mask |= (mask << 1); - *(uint32_t *) &p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) - page_add_to_evict_list(p); + *(uint32_t *) &page->mem[addr & 0xfff] = val; + page->dirty_mask |= mask; + page->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(page) && ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))) + page_add_to_evict_list(page); if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK - 3)) { uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); - p->byte_dirty_mask[byte_offset + 1] |= byte_mask_2; - if ((p->byte_code_present_mask[byte_offset + 1] & byte_mask_2) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + page->byte_dirty_mask[byte_offset + 1] |= byte_mask_2; + if ((page->byte_code_present_mask[byte_offset + 1] & byte_mask_2) && !page_in_evict_list(page)) + page_add_to_evict_list(page); } } } #else void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - p->mem[addr & 0xfff] = val; + page->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + page->mem[addr & 0xfff] = val; } } void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint16_t *) &page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint16_t *) &page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0xf) == 0xf) mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint16_t *) &p->mem[addr & 0xfff] = val; + page->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint16_t *) &page->mem[addr & 0xfff] = val; } } void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *page) { - if (p == NULL) + if (page == NULL) return; # ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint32_t *) &page->mem[addr & 0xfff]) || codegen_in_recompile) { # else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff])) { + if ((page->mem == NULL) || (page->mem == page_ff) || (val != *(uint32_t *) &page->mem[addr & 0xfff])) { # endif uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0xf) >= 0xd) mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint32_t *) &p->mem[addr & 0xfff] = val; + page->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint32_t *) &page->mem[addr & 0xfff] = val; } } #endif void -mem_write_ram(uint32_t addr, uint8_t val, void *priv) +mem_write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); } else @@ -2051,13 +2053,13 @@ mem_write_ram(uint32_t addr, uint8_t val, void *priv) } void -mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +mem_write_ramw(uint32_t addr, uint16_t val, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write W %04X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[addr >> 12]); } else @@ -2065,13 +2067,13 @@ mem_write_ramw(uint32_t addr, uint16_t val, void *priv) } void -mem_write_raml(uint32_t addr, uint32_t val, void *priv) +mem_write_raml(uint32_t addr, uint32_t val, UNUSED(void *priv)) { #ifdef ENABLE_MEM_LOG if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write L %08X to %08X\n", val, addr); #endif - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[addr >> 12]); } else @@ -2079,65 +2081,65 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) } static uint8_t -mem_read_remapped(uint32_t addr, void *priv) +mem_read_remapped(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; } static uint16_t -mem_read_remappedw(uint32_t addr, void *priv) +mem_read_remappedw(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; } static uint32_t -mem_read_remappedl(uint32_t addr, void *priv) +mem_read_remappedl(uint32_t addr, UNUSED(void *priv)) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; } static uint8_t -mem_read_remapped2(uint32_t addr, void *priv) +mem_read_remapped2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return ram[addr]; } static uint16_t -mem_read_remappedw2(uint32_t addr, void *priv) +mem_read_remappedw2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint16_t *) &ram[addr]; } static uint32_t -mem_read_remappedl2(uint32_t addr, void *priv) +mem_read_remappedl2(uint32_t addr, UNUSED(void *priv)) { addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); return *(uint32_t *) &ram[addr]; } static void -mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +mem_write_remapped(uint32_t addr, uint8_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2145,11 +2147,11 @@ mem_write_remapped(uint32_t addr, uint8_t val, void *priv) } static void -mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +mem_write_remappedw(uint32_t addr, uint16_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2157,11 +2159,11 @@ mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) } static void -mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +mem_write_remappedl(uint32_t addr, uint32_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2169,11 +2171,11 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) } static void -mem_write_remapped2(uint32_t addr, uint8_t val, void *priv) +mem_write_remapped2(uint32_t addr, uint8_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2181,11 +2183,11 @@ mem_write_remapped2(uint32_t addr, uint8_t val, void *priv) } static void -mem_write_remappedw2(uint32_t addr, uint16_t val, void *priv) +mem_write_remappedw2(uint32_t addr, uint16_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2193,11 +2195,11 @@ mem_write_remappedw2(uint32_t addr, uint16_t val, void *priv) } static void -mem_write_remappedl2(uint32_t addr, uint32_t val, void *priv) +mem_write_remappedl2(uint32_t addr, uint32_t val, UNUSED(void *priv)) { uint32_t oldaddr = addr; addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2208,7 +2210,7 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { #ifdef USE_NEW_DYNAREC - page_t *p; + page_t *page; start_addr &= ~PAGE_MASK_MASK; end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; @@ -2217,15 +2219,15 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) if ((start_addr >> 12) >= pages_sz) continue; - p = &pages[start_addr >> 12]; - if (p) { - p->dirty_mask = 0xffffffffffffffffULL; + page = &pages[start_addr >> 12]; + if (page) { + page->dirty_mask = 0xffffffffffffffffULL; - if ((p->mem != page_ff) && p->byte_dirty_mask) - memset(p->byte_dirty_mask, 0xff, 64 * sizeof(uint64_t)); + if ((page->mem != page_ff) && page->byte_dirty_mask) + memset(page->byte_dirty_mask, 0xff, 64 * sizeof(uint64_t)); - if (!page_in_evict_list(p)) - page_add_to_evict_list(p); + if (!page_in_evict_list(page)) + page_add_to_evict_list(page); } } #else @@ -2282,6 +2284,7 @@ mem_mapping_recalc(uint64_t base, uint64_t size) mem_mapping_t *map; int n; uint64_t c; + uint8_t wp; if (!size || (base_mapping == NULL)) return; @@ -2300,27 +2303,42 @@ mem_mapping_recalc(uint64_t base, uint64_t size) /* Walk mapping list. */ while (map != NULL) { /* In range? */ - if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { + if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && + ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { uint64_t start = (map->base < base) ? map->base : base; - uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? ((uint64_t) map->base + (uint64_t) map->size) : (base + size); + uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? + ((uint64_t) map->base + (uint64_t) map->size) : (base + size); if (start < map->base) start = map->base; for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { /* CPU */ n = !!in_smm; - if (map->exec && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) + wp = _mem_wp[c >> MEM_GRANULARITY_BITS]; + + if (map->exec && mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) write_mapping[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) read_mapping[c >> MEM_GRANULARITY_BITS] = map; /* Bus */ n |= STATE_BUS; - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS]; + + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; } } @@ -2380,19 +2398,35 @@ mem_mapping_recalc(uint64_t base, uint64_t size) #endif } +void +mem_set_wp(uint64_t base, uint64_t size, uint8_t flags, uint8_t wp) +{ + uint64_t c; + uint64_t end = base + size; + + for (c = base; c < end; c += MEM_GRANULARITY_SIZE) { + if (flags & ACCESS_BUS) + _mem_wp_bus[c >> MEM_GRANULARITY_BITS] = wp; + if (flags & ACCESS_CPU) + _mem_wp[c >> MEM_GRANULARITY_BITS] = wp; + } + + mem_mapping_recalc(base, size); +} + void mem_mapping_set(mem_mapping_t *map, uint32_t base, uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv), uint8_t *exec, uint32_t fl, - void *p) + void *priv) { if (size != 0x00000000) map->enable = 1; @@ -2409,7 +2443,7 @@ mem_mapping_set(mem_mapping_t *map, map->write_l = write_l; map->exec = exec; map->flags = fl; - map->p = p; + map->priv = priv; map->next = NULL; mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next); @@ -2422,15 +2456,15 @@ void mem_mapping_add(mem_mapping_t *map, uint32_t base, uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv), uint8_t *exec, uint32_t fl, - void *p) + void *priv) { /* Do a sanity check */ if ((base_mapping == NULL) && (last_mapping != NULL)) { @@ -2461,7 +2495,7 @@ mem_mapping_add(mem_mapping_t *map, last_mapping = map; mem_mapping_set(map, base, size, read_b, read_w, read_l, - write_b, write_w, write_l, exec, fl, p); + write_b, write_w, write_l, exec, fl, priv); } void @@ -2472,12 +2506,12 @@ mem_mapping_do_recalc(mem_mapping_t *map) void mem_mapping_set_handler(mem_mapping_t *map, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)) + uint8_t (*read_b)(uint32_t addr, void *priv), + uint16_t (*read_w)(uint32_t addr, void *priv), + uint32_t (*read_l)(uint32_t addr, void *priv), + void (*write_b)(uint32_t addr, uint8_t val, void *priv), + void (*write_w)(uint32_t addr, uint16_t val, void *priv), + void (*write_l)(uint32_t addr, uint32_t val, void *priv)) { map->read_b = read_b; map->read_w = read_w; @@ -2521,9 +2555,9 @@ mem_mapping_set_mask(mem_mapping_t *map, uint32_t mask) } void -mem_mapping_set_p(mem_mapping_t *map, void *p) +mem_mapping_set_p(mem_mapping_t *map, void *priv) { - map->p = p; + map->priv = priv; } void @@ -2598,7 +2632,9 @@ mem_a20_init(void) if (is6117) rammask |= 0x03000000; flushmmucache(); - // mem_a20_state = mem_a20_key | mem_a20_alt; +#if 0 + mem_a20_state = mem_a20_key | mem_a20_alt; +#endif } else { rammask = 0xfffff; flushmmucache(); @@ -2692,7 +2728,8 @@ mem_reset(void) } memset(ram, 0x00, ram_size); ram2_size = m - (1 << 30); - ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */ + /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ + ram2 = (uint8_t *) plat_mmap(ram2_size + 16, 0); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { if (config_changed == 2) fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); @@ -2700,17 +2737,18 @@ mem_reset(void) fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram2, 0x00, ram2_size); + memset(ram2, 0x00, ram2_size + 16); } else #endif { ram_size = m; - ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */ + /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ + ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */ if (ram == NULL) { fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, ram_size); + memset(ram, 0x00, ram_size + 16); if (mem_size > 1048576) ram2 = &(ram[1 << 30]); } @@ -2786,6 +2824,8 @@ mem_reset(void) } memset(_mem_exec, 0x00, sizeof(_mem_exec)); + memset(_mem_wp, 0x00, sizeof(_mem_wp)); + memset(_mem_wp_bus, 0x00, sizeof(_mem_wp_bus)); memset(write_mapping, 0x00, sizeof(write_mapping)); memset(read_mapping, 0x00, sizeof(read_mapping)); memset(write_mapping_bus, 0x00, sizeof(write_mapping_bus)); @@ -2865,6 +2905,35 @@ mem_init(void) writelookupp = malloc((1 << 20) * sizeof(uint8_t)); } +static void +umc_page_recalc(uint32_t c, int set) +{ + if (set) { + pages[c].mem = &ram[(c & 0xff) << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } else { + pages[c].mem = page_ff; + pages[c].write_b = NULL; + pages[c].write_w = NULL; + pages[c].write_l = NULL; + } + +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64]; +#endif +} + +void +umc_smram_recalc(uint32_t start, int set) +{ + for (uint32_t c = start; c < (start + 0x0020); c++) + umc_page_recalc(c, set); +} + void mem_remap_top(int kb) { diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c new file mode 100644 index 0000000000..abc34ff968 --- /dev/null +++ b/src/mem/mmu_2386.c @@ -0,0 +1,1050 @@ +/* + * 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. + * + * Memory handling and MMU. + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/version.h> +#include "cpu.h" +#include "x86_ops.h" +#include "x86.h" +#include "x86seg_common.h" +#include <86box/machine.h> +#include <86box/m_xt_xi8088.h> +#include <86box/config.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/plat.h> +#include <86box/rom.h> +#include <86box/gdbstub.h> + +/* As below, 1 = exec, 4 = read. */ +int read_type = 4; + +/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */ +void +mem_debug_check_addr(uint32_t addr, int flags) +{ + uint32_t bp_addr; + uint32_t bp_mask; + uint32_t len_type_pair; + int bp_enabled; + uint8_t match_flags[4] = { 0, 2, 0, 6 }; + + if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG))) + return; + + if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) { + bp_addr = dr[i]; + bp_enabled = (dr[7] >> (i << 1)) & 0x03; + len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f; + bp_mask = ~((len_type_pair >> 2) & 0x03); + + if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) { + /* + From the Intel i386 documemntation: + + (Note that the processor sets Bn regardless of whether Gn or + Ln is set. If more than one breakpoint condition occurs at one time and if + the breakpoint trap occurs due to an enabled condition other than n, Bn may + be set, even though neither Gn nor Ln is set.) + */ + dr[6] |= (1 << i); + if (bp_enabled) + trap |= (read_type == 1) ? 8 : 4; + } + } +} + +uint8_t +mem_readb_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint8_t ret = 0xff; + + mem_logical_addr = 0xffffffff; + + if (map && map->read_b) + ret = map->read_b(addr, map->priv); + + return ret; +} + +uint16_t +mem_readw_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint16_t ret; + + mem_logical_addr = 0xffffffff; + + if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) + ret = map->read_w(addr, map->priv); + else { + ret = mem_readb_phys(addr + 1) << 8; + ret |= mem_readb_phys(addr); + } + + return ret; +} + +uint32_t +mem_readl_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint32_t ret; + + mem_logical_addr = 0xffffffff; + + if (!cpu_16bitbus && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) + ret = map->read_l(addr, map->priv); + else { + ret = mem_readw_phys(addr + 2) << 16; + ret |= mem_readw_phys(addr); + } + + return ret; +} + +void +mem_writeb_map(uint32_t addr, uint8_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + mem_logical_addr = 0xffffffff; + + if (map && map->write_b) + map->write_b(addr, val, map->priv); +} + +void +mem_writew_map(uint32_t addr, uint16_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + mem_logical_addr = 0xffffffff; + + if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) + map->write_w(addr, val, map->priv); + else { + mem_writeb_phys(addr, val & 0xff); + mem_writeb_phys(addr + 1, val >> 8); + } +} + +void +mem_writel_map(uint32_t addr, uint32_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + mem_logical_addr = 0xffffffff; + + if (!cpu_16bitbus && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) + map->write_l(addr, val, map->priv); + else { + mem_writew_phys(addr, val & 0xffff); + mem_writew_phys(addr + 2, val >> 16); + } +} + +#define mmutranslate_read_2386(addr) mmutranslatereal_2386(addr,0) +#define mmutranslate_write_2386(addr) mmutranslatereal_2386(addr,1) + +uint64_t +mmutranslatereal_2386(uint32_t addr, int rw) +{ + uint32_t temp; + uint32_t temp2; + uint32_t temp3; + uint32_t addr2; + + if (cpu_state.abrt) + return 0xffffffffffffffffULL; + + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = mem_readl_map(addr2); + if (!(temp & 1)) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return 0xffffffffffffffffULL; + } + + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + + return 0xffffffffffffffffULL; + } + + mmu_perm = temp & 4; + mem_writel_map(addr2, mem_readl_map(addr2) | (rw ? 0x60 : 0x20)); + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + temp3 = temp & temp2; + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return 0xffffffffffffffffULL; + } + + mmu_perm = temp & 4; + mem_writel_map(addr2, mem_readl_map(addr2) | 0x20); + mem_writel_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), + mem_readl_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) | (rw ? 0x60 : 0x20)); + + return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); +} + +uint64_t +mmutranslate_noabrt_2386(uint32_t addr, int rw) +{ + uint32_t temp; + uint32_t temp2; + uint32_t temp3; + uint32_t addr2; + + if (cpu_state.abrt) + return 0xffffffffffffffffULL; + + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = mem_readl_map(addr2); + + if (!(temp & 1)) + return 0xffffffffffffffffULL; + + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + return 0xffffffffffffffffULL; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + temp3 = temp & temp2; + + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + return 0xffffffffffffffffULL; + + return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); +} + +uint8_t +readmembl_2386(uint32_t addr) +{ + mem_mapping_t *map; + uint64_t a; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + + mem_debug_check_addr(addr, read_type); + addr64 = (uint64_t) addr; + mem_logical_addr = addr; + + high_page = 0; + + if (cr0 >> 31) { + a = mmutranslate_read_2386(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) + return 0xff; + } + addr = (uint32_t) (addr64 & rammask); + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_b) + return map->read_b(addr, map->priv); + + return 0xff; +} + +void +writemembl_2386(uint32_t addr, uint8_t val) +{ + mem_mapping_t *map; + uint64_t a; + + mem_debug_check_addr(addr, 2); + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); + + addr64 = (uint64_t) addr; + mem_logical_addr = addr; + + high_page = 0; + + if (cr0 >> 31) { + a = mmutranslate_write_2386(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) + return; + } + addr = (uint32_t) (addr64 & rammask); + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->write_b) + map->write_b(addr, val, map->priv); +} + +/* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ +uint8_t +readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); + + mem_logical_addr = addr; + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xff; + + addr = a64 & rammask; + } else + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_b) + return map->read_b(addr, map->priv); + + return 0xff; +} + +/* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */ +void +writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); + + mem_logical_addr = addr; + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + + addr = a64 & rammask; + } else + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->write_b) + map->write_b(addr, val, map->priv); +} + +uint16_t +readmemwl_2386(uint32_t addr) +{ + mem_mapping_t *map; + uint64_t a; + + addr64a[0] = addr; + addr64a[1] = addr + 1; + mem_debug_check_addr(addr, read_type); + mem_debug_check_addr(addr + 1, read_type); + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + for (uint8_t i = 0; i < 2; i++) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; + + if (a > 0xffffffffULL) + return 0xffff; + } + } + + return readmembl_no_mmut_2386(addr, addr64a[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, addr64a[1])) << 8); + } + } + + if (cr0 >> 31) { + a = mmutranslate_read_2386(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) + return 0xffff; + } else + addr64a[0] = (uint64_t) addr; + + addr = addr64a[0] & rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr, map->priv); + + if (map && map->read_b) { + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + } + + return 0xffff; +} + +void +writememwl_2386(uint32_t addr, uint16_t val) +{ + mem_mapping_t *map; + uint64_t a; + + addr64a[0] = addr; + addr64a[1] = addr + 1; + mem_debug_check_addr(addr, 2); + mem_debug_check_addr(addr + 1, 2); + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + for (uint8_t i = 0; i < 2; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; + + if (a > 0xffffffffULL) + return; + } + } + } + + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writemembl_no_mmut_2386(addr, addr64a[0], val); + writemembl_no_mmut_2386(addr + 1, addr64a[1], val >> 8); + return; + } + } + + if (cr0 >> 31) { + a = mmutranslate_write_2386(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->write_w) { + map->write_w(addr, val, map->priv); + return; + } + + if (map && map->write_b) { + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + return; + } +} + +/* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */ +uint16_t +readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffff; + } + + return readmembl_no_mmut_2386(addr, a64[0]) | + (((uint16_t) readmembl_no_mmut_2386(addr + 1, a64[1])) << 8); + } + } + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffff; + + addr = (uint32_t) (a64[0] & rammask); + } else + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr, map->priv); + + if (map && map->read_b) { + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + } + + return 0xffff; +} + +/* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */ +void +writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + } + + writemembl_no_mmut_2386(addr, a64[0], val); + writemembl_no_mmut_2386(addr + 1, a64[1], val >> 8); + return; + } + } + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + + addr = (uint32_t) (a64[0] & rammask); + } else + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->write_w) { + map->write_w(addr, val, map->priv); + return; + } + + if (map && map->write_b) { + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + return; + } +} + +uint32_t +readmemll_2386(uint32_t addr) +{ + mem_mapping_t *map; + int i; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < 4; i++) { + addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, read_type); + } + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); + + mem_logical_addr = addr; + + high_page = 0; + + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + for (i = 0; i < 4; i++) { + if (i == 0) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read_2386(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + + if (a > 0xffffffffULL) + return 0xffff; + } + } + + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + return readmemwl_no_mmut_2386(addr, addr64a) | + (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); + } + } + + if (cr0 >> 31) { + a = mmutranslate_read_2386(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) + return 0xffffffff; + } + + addr = addr64a[0] & rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_l) + return map->read_l(addr, map->priv); + + if (map && map->read_w) + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); + + if (map && map->read_b) + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); + + return 0xffffffff; +} + +void +writememll_2386(uint32_t addr, uint32_t val) +{ + mem_mapping_t *map; + int i; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < 4; i++) { + addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 2); + } + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); + + mem_logical_addr = addr; + + high_page = 0; + + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + for (i = 0; i < 4; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + if (i == 0) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write_2386(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + + if (a > 0xffffffffULL) + return; + } + } + } + + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writememwl_no_mmut_2386(addr, &(addr64a[0]), val); + writememwl_no_mmut_2386(addr + 2, &(addr64a[2]), val >> 16); + return; + } + } + + if (cr0 >> 31) { + a = mmutranslate_write_2386(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr, val, map->priv); + return; + } + if (map && map->write_w) { + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + return; + } + if (map && map->write_b) { + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + return; + } +} + +/* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */ +uint32_t +readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); + + mem_logical_addr = addr; + + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffffffff; + } + + return readmemwl_no_mmut_2386(addr, a64) | + ((uint32_t) (readmemwl_no_mmut_2386(addr + 2, &(a64[2]))) << 16); + } + } + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffffffff; + + addr = (uint32_t) (a64[0] & rammask); + } else + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_l) + return map->read_l(addr, map->priv); + + if (map && map->read_w) + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); + + if (map && map->read_b) + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); + + return 0xffffffff; +} + +/* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ +void +writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) +{ + mem_mapping_t *map; + + GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); + + mem_logical_addr = addr; + + if (cpu_16bitbus || (addr & 3)) { + if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + } + + writememwl_no_mmut_2386(addr, &(a64[0]), val); + writememwl_no_mmut_2386(addr + 2, &(a64[2]), val >> 16); + return; + } + } + + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + + addr = (uint32_t) (a64[0] & rammask); + } else + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr, val, map->priv); + return; + } + if (map && map->write_w) { + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + return; + } + if (map && map->write_b) { + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + return; + } +} + +uint64_t +readmemql_2386(uint32_t addr) +{ + mem_mapping_t *map; + int i; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < 8; i++) { + addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, read_type); + } + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 7) { + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xff8) { + if (cr0 >> 31) { + for (i = 0; i < 8; i++) { + if (i == 0) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read_2386(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + + if (a > 0xffffffffULL) + return 0xffff; + } + } + + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + return readmemll_no_mmut_2386(addr, addr64a) | + (((uint64_t) readmemll_no_mmut_2386(addr + 4, &(addr64a[4]))) << 32); + } + } + + if (cr0 >> 31) { + a = mmutranslate_read_2386(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) + return 0xffffffffffffffffULL; + } + + addr = addr64a[0] & rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr, map->priv) | ((uint64_t) map->read_l(addr + 4, map->priv) << 32); + + return readmemll(addr) | ((uint64_t) readmemll(addr + 4) << 32); +} + +void +writememql_2386(uint32_t addr, uint64_t val) +{ + mem_mapping_t *map; + int i; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < 8; i++) { + addr64a[i] = (uint64_t) (addr + i); + mem_debug_check_addr(addr + i, 2); + } + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 7) { + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xff8) { + if (cr0 >> 31) { + for (i = 0; i < 8; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + if (i == 0) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write_2386(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + + if (addr64a[i] > 0xffffffffULL) + return; + } + } + } + + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writememll_no_mmut_2386(addr, addr64a, val); + writememll_no_mmut_2386(addr + 4, &(addr64a[4]), val >> 32); + return; + } + } + + if (cr0 >> 31) { + addr64a[0] = mmutranslate_write_2386(addr); + if (addr64a[0] > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr, val, map->priv); + map->write_l(addr + 4, val >> 32, map->priv); + return; + } + if (map && map->write_w) { + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + map->write_w(addr + 4, val >> 32, map->priv); + map->write_w(addr + 6, val >> 48, map->priv); + return; + } + if (map && map->write_b) { + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + map->write_b(addr + 4, val >> 32, map->priv); + map->write_b(addr + 5, val >> 40, map->priv); + map->write_b(addr + 6, val >> 48, map->priv); + map->write_b(addr + 7, val >> 56, map->priv); + return; + } +} + +void +do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) +{ + int i; + uint32_t last_addr = addr + (num - 1); + uint64_t a = 0x0000000000000000ULL; + + mem_debug_check_addr(addr, write ? 2 : read_type); + + for (i = 0; i < num; i++) + a64[i] = (uint64_t) addr; + + if (!(cr0 >> 31)) + return; + + for (i = 0; i < num; i++) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal_2386(addr, write); + a64[i] = (uint32_t) a; + } else if (!(addr & 0xfff)) { + a = mmutranslatereal_2386(last_addr, write); + a64[i] = (uint32_t) a; + + if (!cpu_state.abrt) { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + + addr++; + } +} diff --git a/src/mem/rom.c b/src/mem/rom.c index 80881c723a..f9718b7cee 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -138,13 +138,13 @@ rom_getfile(char *fn, char *s, int size) } int -rom_present(char *fn) +rom_present(const char *fn) { - FILE *f; + FILE *fp; - f = rom_fopen(fn, "rb"); - if (f != NULL) { - (void) fclose(f); + fp = rom_fopen(fn, "rb"); + if (fp != NULL) { + (void) fclose(fp); return 1; } @@ -154,7 +154,7 @@ rom_present(char *fn) uint8_t rom_read(uint32_t addr, void *priv) { - rom_t *rom = (rom_t *) priv; + const rom_t *rom = (rom_t *) priv; #ifdef ROM_TRACE if (rom->mapping.base == ROM_TRACE) @@ -205,10 +205,9 @@ rom_readl(uint32_t addr, void *priv) int rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { - FILE *f = rom_fopen(fn, "rb"); - int i; + FILE *fp = rom_fopen(fn, "rb"); - if (f == NULL) { + if (fp == NULL) { rom_log("ROM: image '%s' not found\n", fn); return 0; } @@ -220,19 +219,19 @@ rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t addr &= 0x03ffff; if (ptr != NULL) { - if (fseek(f, off, SEEK_SET) == -1) + if (fseek(fp, off, SEEK_SET) == -1) fatal("rom_load_linear(): Error seeking to the beginning of the file\n"); - for (i = 0; i < (sz >> 1); i++) { - if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1) + for (int i = 0; i < (sz >> 1); i++) { + if (fread(ptr + (addr + (i << 1)), 1, 1, fp) != 1) fatal("rom_load_linear(): Error reading even data\n"); } - for (i = 0; i < (sz >> 1); i++) { - if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1) + for (int i = 0; i < (sz >> 1); i++) { + if (fread(ptr + (addr + (i << 1) + 1), 1, 1, fp) != 1) fatal("rom_load_linear(): Error reading od data\n"); } } - (void) fclose(f); + (void) fclose(fp); return 1; } @@ -241,9 +240,9 @@ rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t int rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { - FILE *f = rom_fopen(fn, "rb"); + FILE *fp = rom_fopen(fn, "rb"); - if (f == NULL) { + if (fp == NULL) { rom_log("ROM: image '%s' not found\n", fn); return 0; } @@ -255,13 +254,13 @@ rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) addr &= 0x03ffff; if (ptr != NULL) { - if (fseek(f, off, SEEK_SET) == -1) + if (fseek(fp, off, SEEK_SET) == -1) fatal("rom_load_linear(): Error seeking to the beginning of the file\n"); - if (fread(ptr + addr, 1, sz, f) > sz) + if (fread(ptr + addr, 1, sz, fp) > sz) fatal("rom_load_linear(): Error reading data\n"); } - (void) fclose(f); + (void) fclose(fp); return 1; } @@ -270,9 +269,9 @@ rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) int rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) { - FILE *f = rom_fopen(fn, "rb"); + FILE *fp = rom_fopen(fn, "rb"); - if (f == NULL) { + if (fp == NULL) { rom_log("ROM: image '%s' not found\n", fn); return 0; } @@ -284,22 +283,28 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t addr &= 0x03ffff; } - (void) fseek(f, 0, SEEK_END); - if (ftell(f) < sz) { - (void) fclose(f); + (void) fseek(fp, 0, SEEK_END); + if (ftell(fp) < sz) { + (void) fclose(fp); return 0; } if (ptr != NULL) { - if (fseek(f, off, SEEK_SET) == -1) + if (fseek(fp, off, SEEK_SET) == -1) fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n"); - if (fread(ptr + addr + 0x10000, 1, sz >> 1, f) > (sz >> 1)) + if (fread(ptr + addr + 0x10000, 1, sz >> 1, fp) > (sz >> 1)) fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); - if (fread(ptr + addr, sz >> 1, 1, f) > (sz >> 1)) + if (fread(ptr + addr, sz >> 1, 1, fp) > (sz >> 1)) fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + if (sz == 0x40000) { + if (fread(ptr + addr + 0x30000, 1, sz >> 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n"); + if (fread(ptr + addr + 0x20000, sz >> 1, 1, fp) > (sz >> 1)) + fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); + } } - (void) fclose(f); + (void) fclose(fp); return 1; } @@ -308,18 +313,18 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t int rom_load_interleaved(const char *fnl, const char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) { - FILE *fl = rom_fopen(fnl, "rb"); - FILE *fh = rom_fopen(fnh, "rb"); + FILE *fpl = rom_fopen(fnl, "rb"); + FILE *fph = rom_fopen(fnh, "rb"); - if (fl == NULL || fh == NULL) { - if (fl == NULL) + if (fpl == NULL || fph == NULL) { + if (fpl == NULL) rom_log("ROM: image '%s' not found\n", fnl); else - (void) fclose(fl); - if (fh == NULL) + (void) fclose(fpl); + if (fph == NULL) rom_log("ROM: image '%s' not found\n", fnh); else - (void) fclose(fh); + (void) fclose(fph); return 0; } @@ -332,16 +337,16 @@ rom_load_interleaved(const char *fnl, const char *fnh, uint32_t addr, int sz, in } if (ptr != NULL) { - (void) fseek(fl, off, SEEK_SET); - (void) fseek(fh, off, SEEK_SET); + (void) fseek(fpl, off, SEEK_SET); + (void) fseek(fph, off, SEEK_SET); for (int c = 0; c < sz; c += 2) { - ptr[addr + c] = fgetc(fl) & 0xff; - ptr[addr + c + 1] = fgetc(fh) & 0xff; + ptr[addr + c] = fgetc(fpl) & 0xff; + ptr[addr + c + 1] = fgetc(fph) & 0xff; } } - (void) fclose(fh); - (void) fclose(fl); + (void) fclose(fph); + (void) fclose(fpl); return 1; } @@ -384,7 +389,7 @@ rom_reset(uint32_t addr, int sz) } uint8_t -bios_read(uint32_t addr, void *priv) +bios_read(uint32_t addr, UNUSED(void *priv)) { uint8_t ret = 0xff; @@ -397,7 +402,7 @@ bios_read(uint32_t addr, void *priv) } uint16_t -bios_readw(uint32_t addr, void *priv) +bios_readw(uint32_t addr, UNUSED(void *priv)) { uint16_t ret = 0xffff; @@ -410,7 +415,7 @@ bios_readw(uint32_t addr, void *priv) } uint32_t -bios_readl(uint32_t addr, void *priv) +bios_readl(uint32_t addr, UNUSED(void *priv)) { uint32_t ret = 0xffffffff; @@ -442,7 +447,7 @@ bios_add(void) mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, bios_read, bios_readw, bios_readl, NULL, NULL, NULL, - &rom[0x20000], MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0); + &rom[biosmask + 1 - 0x20000], MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0); mem_set_mem_state_both(0x0e0000, 0x20000, MEM_READ_ROMCS | MEM_WRITE_ROMCS); @@ -524,7 +529,7 @@ bios_load(const char *fn1, const char *fn2, uint32_t addr, int sz, int off, int } int -bios_load_linear_combined(const char *fn1, const char *fn2, int sz, int off) +bios_load_linear_combined(const char *fn1, const char *fn2, int sz, UNUSED(int off)) { uint8_t ret = 0; diff --git a/src/mem/row.c b/src/mem/row.c new file mode 100644 index 0000000000..ccd0325a4c --- /dev/null +++ b/src/mem/row.c @@ -0,0 +1,348 @@ +/* + * 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. + * + * DRAM row handling. + * + * Authors: Miran Grca, + * + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86_ops.h" +#include "x86.h" +#include <86box/config.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/spd.h> +#include <86box/row.h> +#include <86box/plat_unused.h> + +/* 0 1 2 3 4 5 6 7 */ +static uint8_t rows_num; +static uint8_t rows_default; +static uint8_t rows_bits; +static uint32_t row_unit; +static uint8_t drb_defaults[16]; +static row_t *rows; + + +static uint8_t +row_read(uint32_t addr, void *priv) +{ + const row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addreadlookup(mem_logical_addr, new_addr); + + return dev->buf[new_addr]; +} + + +static uint16_t +row_readw(uint32_t addr, void *priv) +{ + row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addreadlookup(mem_logical_addr, new_addr); + + return *(uint16_t *) &(dev->buf[new_addr]); +} + + +static uint32_t +row_readl(uint32_t addr, void *priv) +{ + row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addreadlookup(mem_logical_addr, new_addr); + + return *(uint32_t *) &(dev->buf[new_addr]); +} + + +static void +row_write(uint32_t addr, uint8_t val, void *priv) +{ + const row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addwritelookup(mem_logical_addr, new_addr); + mem_write_ramb_page(new_addr, val, &pages[addr >> 12]); +} + + +static void +row_writew(uint32_t addr, uint16_t val, void *priv) +{ + const row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addwritelookup(mem_logical_addr, new_addr); + mem_write_ramw_page(new_addr, val, &pages[addr >> 12]); +} + + +static void +row_writel(uint32_t addr, uint32_t val, void *priv) +{ + const row_t *dev = (row_t *) priv; + uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base; + + addwritelookup(mem_logical_addr, new_addr); + mem_write_raml_page(new_addr, val, &pages[addr >> 12]); +} + + +void +row_allocate(uint8_t row_id, uint8_t set) +{ + uint32_t offset; + + /* Do nothing if size is either zero or invalid. */ + if ((rows[row_id].host_size == 0x00000000) || (rows[row_id].host_size == 0xffffffff)) + return; + + if (rows[row_id].ram_size == 0x00000000) + return; + + for (uint32_t c = (rows[row_id].host_base >> 12); c < ((rows[row_id].host_base + rows[row_id].host_size) >> 12); c++) { + offset = c - (rows[row_id].host_base >> 12); + + pages[c].mem = set ? (rows[row_id].buf + rows[row_id].ram_base + ((offset << 12) & rows[row_id].ram_mask)) : page_ff; + pages[c].write_b = set ? mem_write_ramb_page : NULL; + pages[c].write_w = set ? mem_write_ramw_page : NULL; + pages[c].write_l = set ? mem_write_raml_page : NULL; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; +#endif + } + + if (rows[row_id].host_base >= 0x00100000) { + mem_set_mem_state_both(rows[row_id].host_base, rows[row_id].host_base + rows[row_id].host_size, + set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + } else { + if (0x000a0000 > rows[row_id].host_base) { + mem_set_mem_state_both(rows[row_id].host_base, 0x000a0000 - rows[row_id].host_base, + set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + } + if ((rows[row_id].host_base + rows[row_id].host_size) > 0x00100000) { + mem_set_mem_state_both(0x00100000, (rows[row_id].host_base + rows[row_id].host_size) - 0x00100000, + set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + } + } + + if (set) { + mem_mapping_set_addr(&rows[row_id].mapping, rows[row_id].host_base, rows[row_id].host_size); + mem_mapping_set_exec(&rows[row_id].mapping, rows[row_id].buf + rows[row_id].ram_base); + mem_mapping_set_mask(&rows[row_id].mapping, rows[row_id].ram_mask); + if ((rows[row_id].host_base == rows[row_id].ram_base) && (rows[row_id].host_size == rows[row_id].ram_size)) { +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml); +#else + if (rows[row_id].buf == ram2) { + mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl, + mem_write_ram,mem_write_ramw,mem_write_raml); + } else { + mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml); + } +#endif + } else { + mem_mapping_set_handler(&rows[row_id].mapping, row_read, row_readw, row_readl, + row_write, row_writew, row_writel); + } + } else + mem_mapping_disable(&rows[row_id].mapping); +} + + +void +row_disable(uint8_t row_id) +{ + row_allocate(row_id, 0); +} + + +void +row_set_boundary(uint8_t row_id, uint32_t boundary) +{ + if (row_id >= rows_num) + return; + + boundary &= ((1 << rows_bits) - 1); + + rows[row_id].host_size = boundary * row_unit; + if (row_id == 0) + rows[row_id].host_base = 0x00000000; + else { + rows[row_id].host_base = rows[row_id - 1].boundary * row_unit; + if (rows[row_id - 1].boundary > boundary) + rows[row_id].host_size = 0x00000000; + else + rows[row_id].host_size -= rows[row_id].host_base; + } + + rows[row_id].boundary = boundary; + + row_allocate(row_id, 1); +} + + +void +row_reset(UNUSED(void *priv)) +{ + uint32_t boundary; + uint32_t shift; + + for (int8_t i = (rows_num - 1); i >= 0; i--) + row_disable(i); + + for (uint8_t i = 0; i < rows_num; i++) { + shift = (i & 1) << 2; + boundary = ((uint32_t) drb_defaults[i]) + (((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) & 0xf) << 8); + row_set_boundary(i, boundary); + } +} + + +void +row_close(UNUSED(void *priv)) +{ + free(rows); + rows = NULL; +} + + +void * +row_init(const device_t *info) +{ + uint32_t cur_drb = 0; + uint32_t cur_drbe = 0; + uint32_t last_drb = 0; + uint32_t last_drbe = 0; + uint8_t phys_drbs[16]; + int i; + int max = info->local & 0xff; + uint32_t shift; + uint32_t drb; + uint32_t boundary; + uint32_t mask; + row_t *new_rows = NULL; + + rows_bits = ((info->local >> 24) & 0xff); + mask = (1 << rows_bits) - 1; + row_unit = ((info->local >> 8) & 0xff); + memset(phys_drbs, 0x00, 16); + spd_write_drbs(phys_drbs, 0x00, max, row_unit); + row_unit <<= 20; + rows_default = (info->local >> 16) & 0xff; + memset(drb_defaults, 0x00, 16); + for (i = 0; i < 8; i++) + drb_defaults[i] = rows_default; + + new_rows = calloc(max + 1, sizeof(row_t)); + rows_num = max + 1; + + rows = new_rows; + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + if (mem_size > 1048576) + mem_mapping_disable(&ram_2gb_mapping); +#endif + + for (uint32_t c = 0; c < pages_sz; c++) { + pages[c].mem = page_ff; + pages[c].write_b = NULL; + pages[c].write_w = NULL; + pages[c].write_l = NULL; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; +#endif + } + + /* Set all memory space above the default allocated area to external. */ + boundary = ((uint32_t) rows_default) * row_unit; + mem_set_mem_state_both(boundary, (mem_size << 10) - boundary, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + for (i = 0; i <= max; i++) { + cur_drb = phys_drbs[i]; + cur_drbe = phys_drbs[(i >> 1) + 8]; + + shift = (i & 1) << 2; + drb = (cur_drb & mask) + (((cur_drbe >> shift) & 0x03) << 8); + rows[i].ram_size = drb * row_unit; + + shift = ((i - 1) & 1) << 2; + drb = (last_drb & mask) + (((last_drbe >> shift) & 0x03) << 8); + rows[i].ram_base = drb * row_unit; + rows[i].ram_size -= rows[i].ram_base; + + rows[i].buf = ram; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + if (rows[i].ram_base >= (1 << 30)) { + rows[i].ram_base -= (1 << 30); + rows[i].buf = ram2; + } +#endif + + rows[i].ram_mask = rows[i].ram_size - 1; + + mem_mapping_add(&rows[i].mapping, rows[i].ram_base, rows[i].ram_size, + row_read, row_readw, row_readl, + row_write, row_writew, row_writel, + rows[i].buf + rows[i].ram_base, MEM_MAPPING_INTERNAL, &(rows[i])); + mem_mapping_disable(&rows[i].mapping); + + shift = (i & 1) << 2; + boundary = ((uint32_t) drb_defaults[i]) + ((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) << 8); + row_set_boundary(i, boundary); + + last_drb = cur_drb; + last_drbe = cur_drbe; + } + + flushmmucache(); + + return new_rows; +} + + +/* NOTE: NOT const, so that we can patch it at init. */ +device_t row_device = { + .name = "DRAM Rows", + .internal_name = "dram_rows", + .flags = DEVICE_AT, + .local = 0x0000, + .init = row_init, + .close = row_close, + .reset = row_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/mem/smram.c b/src/mem/smram.c index 7a1fbb664a..0532e2dd57 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -56,8 +56,8 @@ smram_log(const char *fmt, ...) static uint8_t smram_read(uint32_t addr, void *priv) { - smram_t *dev = (smram_t *) priv; - uint32_t new_addr = addr - dev->host_base + dev->ram_base; + const smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; if (new_addr >= (1 << 30)) return mem_read_ram_2gb(new_addr, priv); diff --git a/src/mem/spd.c b/src/mem/spd.c index c39a3bffd3..a3bcba46d8 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -27,11 +27,12 @@ #include <86box/spd.h> #include <86box/version.h> #include <86box/machine.h> +#include <86box/plat_unused.h> #define SPD_ROLLUP(x) ((x) >= 16 ? ((x) -15) : (x)) -int spd_present = 0; -spd_t *spd_modules[SPD_MAX_SLOTS]; +uint8_t spd_present = 0; +spd_t *spd_modules[SPD_MAX_SLOTS]; static const device_t spd_device; @@ -54,7 +55,7 @@ spd_log(const char *fmt, ...) #endif static void -spd_close(void *priv) +spd_close(UNUSED(void *priv)) { spd_log("SPD: close()\n"); @@ -67,7 +68,7 @@ spd_close(void *priv) } static void * -spd_init(const device_t *info) +spd_init(UNUSED(const device_t *info)) { spd_log("SPD: init()\n"); @@ -84,8 +85,8 @@ spd_init(const device_t *info) int comp_ui16_rev(const void *elem1, const void *elem2) { - uint16_t a = *((uint16_t *) elem1); - uint16_t b = *((uint16_t *) elem2); + const uint16_t a = *((const uint16_t *) elem1); + const uint16_t b = *((const uint16_t *) elem2); return ((a > b) ? -1 : ((a < b) ? 1 : 0)); } @@ -181,7 +182,6 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) uint8_t slot; uint8_t slot_count; uint8_t row; - uint8_t i; uint16_t min_module_size; uint16_t rows[SPD_MAX_SLOTS]; uint16_t asym; @@ -262,7 +262,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->dram_width = 8; edo_data->spd_rev = 0x12; - for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); + for (int i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); i < sizeof(edo_data->part_no); i++) edo_data->part_no[i] = ' '; /* part number should be space-padded */ edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); @@ -270,9 +270,9 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->mfg_year = 20; edo_data->mfg_week = 17; - for (i = 0; i < 63; i++) + for (uint8_t i = 0; i < 63; i++) edo_data->checksum += spd_modules[slot]->data[i]; - for (i = 0; i < 129; i++) + for (uint8_t i = 0; i < 129; i++) edo_data->checksum2 += spd_modules[slot]->data[i]; break; @@ -316,7 +316,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->ca_hold = sdram_data->data_hold = 0x08; sdram_data->spd_rev = 0x12; - for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]); + for (int i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]); i < sizeof(sdram_data->part_no); i++) sdram_data->part_no[i] = ' '; /* part number should be space-padded */ sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); @@ -327,11 +327,14 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->freq = 100; sdram_data->features = 0xFF; - for (i = 0; i < 63; i++) + for (uint8_t i = 0; i < 63; i++) sdram_data->checksum += spd_modules[slot]->data[i]; - for (i = 0; i < 129; i++) + for (uint8_t i = 0; i < 129; i++) sdram_data->checksum2 += spd_modules[slot]->data[i]; break; + + default: + break; } row++; @@ -346,9 +349,12 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit uint8_t dimm; uint8_t drb; uint8_t apollo = 0; + uint8_t two_step = !!(drb_unit & 0x80); uint16_t size; uint16_t rows[SPD_MAX_SLOTS]; + drb_unit &= 0x7f; + /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ if (reg_max < reg_min) { apollo = reg_max; @@ -381,14 +387,17 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } /* Determine the DRB register to write. */ - drb = reg_min + row; + if (two_step) + drb = reg_min + (row << 1); + else + drb = reg_min + row; if (apollo && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); /* Write DRB register, adding the previous DRB's value. */ if (row == 0) regs[drb] = 0; - else if ((apollo) && (drb == apollo)) + else if (apollo && (drb == apollo)) regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */ else regs[drb] = regs[drb - 1]; @@ -398,7 +407,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } } -/* Needed for 430LX. */ +/* Needed for 430NX. */ void spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) { @@ -444,8 +453,9 @@ spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */ regs[drb] = row_val & 0xff; drb = reg_min + 8 + (row >> 1); - shift = (row & 0x01) << 3; - regs[drb] = (((row_val & 0xfff) >> 8) << shift); + shift = (row & 0x01) << 2; + /* Limit to 1 GB space, per the 430NX datasheet. */ + regs[drb] = (regs[drb] & ~(0xf << shift)) | (((row_val >> 8) & 3) << shift); spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } @@ -544,8 +554,8 @@ spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max) regs[drb + 3] |= 0x06; switch (size) { - case 4: default: + case 4: regs[drb + 2] = 0x00; break; case 8: diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 169a1dc6db..cd6ec7cd9d 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -10,14 +10,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, + * Authors: Miran Grca, * Jasmine Iwanek, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. * Copyright 2022-2023 Jasmine Iwanek. */ #include @@ -35,21 +31,31 @@ #include <86box/m_xt_xi8088.h> typedef struct sst_t { - uint8_t manufacturer, id, has_bbp, is_39, - page_bytes, sdp, bbp_first_8k, bbp_last_8k; - - int command_state, id_mode, - dirty; - - uint32_t size, mask, - page_mask, page_base, - last_addr; - - uint8_t page_buffer[128], - page_dirty[128]; + uint8_t manufacturer; + uint8_t id; + uint8_t has_bbp; + uint8_t is_39; + uint8_t page_bytes; + uint8_t sdp; + uint8_t bbp_first_8k; + uint8_t bbp_last_8k; + + int command_state; + int id_mode; + int dirty; + + uint32_t size; + uint32_t mask; + uint32_t page_mask; + uint32_t page_base; + uint32_t last_addr; + + uint8_t page_buffer[128]; + uint8_t page_dirty[128]; uint8_t *array; - mem_mapping_t mapping[8], mapping_h[8]; + mem_mapping_t mapping[8]; + mem_mapping_t mapping_h[8]; pc_timer_t page_write_timer; } sst_t; @@ -125,6 +131,9 @@ static char flash_path[1024]; #define W29C020 0x4500 #define W29C040 0x4600 +#define AMD 0x01 /* AMD Manufacturer's ID */ +#define AMD29F020A 0xb000 + #define SIZE_512K 0x010000 #define SIZE_1M 0x020000 #define SIZE_2M 0x040000 @@ -138,12 +147,32 @@ sst_sector_erase(sst_t *dev, uint32_t addr) { uint32_t base = addr & (dev->mask & ~0xfff); - if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) - return; - else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) - return; + if (dev->manufacturer == AMD) { + base = addr & biosmask; + + if ((base >= 0x00000) && (base <= 0x0ffff)) + memset(&dev->array[0x00000], 0xff, 65536); + else if ((base >= 0x10000) && (base <= 0x1ffff)) + memset(&dev->array[0x10000], 0xff, 65536); + else if ((base >= 0x20000) && (base <= 0x2ffff)) + memset(&dev->array[0x20000], 0xff, 65536); + else if ((base >= 0x30000) && (base <= 0x37fff)) + memset(&dev->array[0x30000], 0xff, 32768); + else if ((base >= 0x38000) && (base <= 0x39fff)) + memset(&dev->array[0x38000], 0xff, 8192); + else if ((base >= 0x3a000) && (base <= 0x3bfff)) + memset(&dev->array[0x3a000], 0xff, 8192); + else if ((base >= 0x3c000) && (base <= 0x3ffff)) + memset(&dev->array[0x3c000], 0xff, 16384); + } else { + if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) + return; + else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) + return; + + memset(&dev->array[base], 0xff, 4096); + } - memset(&dev->array[base], 0xff, 4096); dev->dirty = 1; } @@ -252,14 +281,18 @@ sst_page_write(void *priv) } static uint8_t -sst_read_id(uint32_t addr, void *p) +sst_read_id(uint32_t addr, void *priv) { - sst_t *dev = (sst_t *) p; - uint8_t ret = 0x00; + const sst_t *dev = (sst_t *) priv; + uint8_t ret = 0x00; + uint32_t mask = 0xffff; + + if (dev->manufacturer == AMD) + mask >>= 8; - if ((addr & 0xffff) == 0) + if ((addr & mask) == 0) ret = dev->manufacturer; - else if ((addr & 0xffff) == 1) + else if ((addr & mask) == 1) ret = dev->id; #ifdef UNKNOWN_FLASH else if ((addr & 0xffff) == 0x100) @@ -272,6 +305,9 @@ sst_read_id(uint32_t addr, void *p) ret = dev->bbp_first_8k; else if (addr == 0x3fff2) ret = dev->bbp_last_8k; + } else if (dev->manufacturer == AMD) { + if ((addr & mask) == 2) + ret = 0x00; } return ret; @@ -291,9 +327,18 @@ sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val) } static void -sst_write(uint32_t addr, uint8_t val, void *p) +sst_write(uint32_t addr, uint8_t val, void *priv) { - sst_t *dev = (sst_t *) p; + sst_t *dev = (sst_t *) priv; + uint32_t mask = 0x7fff; + uint32_t addr0 = 0x5555; + uint32_t addr1 = 0x2aaa; + + if (dev->manufacturer == AMD) { + mask >>= 4; + addr0 >>= 4; + addr1 >>= 4; + } switch (dev->command_state) { case 0: @@ -303,7 +348,7 @@ sst_write(uint32_t addr, uint8_t val, void *p) if (dev->id_mode) dev->id_mode = 0; dev->command_state = 0; - } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) + } else if (((addr & mask) == addr0) && (val == 0xaa)) dev->command_state++; else { if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { @@ -320,7 +365,7 @@ sst_write(uint32_t addr, uint8_t val, void *p) case 1: case 4: /* 2nd and 5th Bus Write Cycle */ - if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) + if (((addr & mask) == addr1) && (val == 0x55)) dev->command_state++; else dev->command_state = 0; @@ -331,7 +376,7 @@ sst_write(uint32_t addr, uint8_t val, void *p) if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) { /* Sector erase - can be on any address. */ sst_new_command(dev, addr, val); - } else if ((addr & 0x7fff) == 0x5555) + } else if ((addr & mask) == addr0) sst_new_command(dev, addr, val); else dev->command_state = 0; @@ -359,19 +404,22 @@ sst_write(uint32_t addr, uint8_t val, void *p) dev->bbp_last_8k = 0xff; dev->command_state = 0; break; + + default: + break; } } static uint8_t -sst_read(uint32_t addr, void *p) +sst_read(uint32_t addr, void *priv) { - sst_t *dev = (sst_t *) p; - uint8_t ret = 0xff; + const sst_t *dev = (sst_t *) priv; + uint8_t ret = 0xff; addr &= 0x000fffff; if (dev->id_mode) - ret = sst_read_id(addr, p); + ret = sst_read_id(addr, priv); else { if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) ret = dev->array[addr - biosaddr]; @@ -381,15 +429,15 @@ sst_read(uint32_t addr, void *p) } static uint16_t -sst_readw(uint32_t addr, void *p) +sst_readw(uint32_t addr, void *priv) { - sst_t *dev = (sst_t *) p; + sst_t *dev = (sst_t *) priv; uint16_t ret = 0xffff; addr &= 0x000fffff; if (dev->id_mode) - ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8); + ret = sst_read(addr, priv) | (sst_read(addr + 1, priv) << 8); else { if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) ret = *(uint16_t *) &dev->array[addr - biosaddr]; @@ -399,15 +447,15 @@ sst_readw(uint32_t addr, void *p) } static uint32_t -sst_readl(uint32_t addr, void *p) +sst_readl(uint32_t addr, void *priv) { - sst_t *dev = (sst_t *) p; + sst_t *dev = (sst_t *) priv; uint32_t ret = 0xffffffff; addr &= 0x000fffff; if (dev->id_mode) - ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16); + ret = sst_readw(addr, priv) | (sst_readw(addr + 2, priv) << 16); else { if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) ret = *(uint32_t *) &dev->array[addr - biosaddr]; @@ -456,7 +504,7 @@ sst_add_mappings(sst_t *dev) static void * sst_init(const device_t *info) { - FILE *f; + FILE *fp; sst_t *dev = malloc(sizeof(sst_t)); memset(dev, 0, sizeof(sst_t)); @@ -472,6 +520,8 @@ sst_init(const device_t *info) dev->id = (info->local >> 8) & 0xff; dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020); dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512); + if (dev->manufacturer == AMD) + dev->is_39 = 1; dev->size = info->local & 0xffff0000; if ((dev->size == 0x20000) && (strstr(machine_get_internal_name_ex(machine), "xi8088")) && !xi8088_bios_128kb()) @@ -484,11 +534,11 @@ sst_init(const device_t *info) sst_add_mappings(dev); - f = nvr_fopen(flash_path, "rb"); - if (f) { - if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size) + fp = nvr_fopen(flash_path, "rb"); + if (fp) { + if (fread(&(dev->array[0x00000]), 1, dev->size, fp) != dev->size) pclog("Less than %i bytes read from the SST Flash ROM file\n", dev->size); - fclose(f); + fclose(fp); } else dev->dirty = 1; /* It is by definition dirty on creation. */ @@ -499,16 +549,16 @@ sst_init(const device_t *info) } static void -sst_close(void *p) +sst_close(void *priv) { - FILE *f; - sst_t *dev = (sst_t *) p; + FILE *fp; + sst_t *dev = (sst_t *) priv; if (dev->dirty) { - f = nvr_fopen(flash_path, "wb"); - if (f != NULL) { - fwrite(&(dev->array[0x00000]), dev->size, 1, f); - fclose(f); + fp = nvr_fopen(flash_path, "wb"); + if (fp != NULL) { + fwrite(&(dev->array[0x00000]), dev->size, 1, fp); + fclose(fp); } } @@ -932,3 +982,17 @@ const device_t sst_flash_49lf160_device = { .force_redraw = NULL, .config = NULL }; + +const device_t amd_flash_29f020a_device = { + .name = "AMD 29F020a Flash BIOS", + .internal_name = "amd_flash_29f020a", + .flags = 0, + .local = AMD | AMD29F020A | SIZE_2M, + .init = sst_init, + .close = sst_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 36a3a535b8..290486ec54 100644 --- a/src/minitrace/minitrace.c +++ b/src/minitrace/minitrace.c @@ -73,7 +73,7 @@ static int is_flushing = FALSE; static int events_in_progress = 0; static int64_t time_offset; static int first_line = 1; -static FILE *f; +static FILE *fp; static __thread int cur_thread_id; // Thread local storage static int cur_process_id; static pthread_mutex_t mutex; @@ -235,9 +235,9 @@ void mtr_init_from_stream(void *stream) { event_buffer = (raw_event_t *)malloc(INTERNAL_MINITRACE_BUFFER_SIZE * sizeof(raw_event_t)); flush_buffer = (raw_event_t *)malloc(INTERNAL_MINITRACE_BUFFER_SIZE * sizeof(raw_event_t)); event_count = 0; - f = (FILE *)stream; + fp = (FILE *) stream; const char *header = "{\"traceEvents\":[\n"; - fwrite(header, 1, strlen(header), f); + fwrite(header, 1, strlen(header), fp); time_offset = (uint64_t)(mtr_time_s() * 1000000); first_line = 1; pthread_mutex_init(&mutex, 0); @@ -258,11 +258,11 @@ void mtr_shutdown(void) { mtr_flush_with_state(TRUE); - fwrite("\n]}\n", 1, 4, f); - fclose(f); + fwrite("\n]}\n", 1, 4, fp); + fclose(fp); pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&event_mutex); - f = 0; + fp = 0; free(event_buffer); event_buffer = 0; for (uint8_t i = 0; i < STRING_POOL_SIZE; i++) { @@ -393,6 +393,9 @@ void mtr_flush_with_state(int is_last) { case 'X': snprintf(id_buf, ARRAY_SIZE(id_buf), ",\"dur\":%i", (int)raw->a_double); break; + + default: + break; } } else { id_buf[0] = 0; diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 54ec1edcec..b0ba913d57 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -14,22 +14,15 @@ # set(net_sources) list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c - net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c) + net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c + net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c) -option(SLIRP_EXTERNAL "Link against the system-provided libslirp library" OFF) -mark_as_advanced(SLIRP_EXTERNAL) +find_package(PkgConfig REQUIRED) +pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) +target_link_libraries(86Box PkgConfig::SLIRP) -if(SLIRP_EXTERNAL) - find_package(PkgConfig REQUIRED) - pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) - target_link_libraries(86Box PkgConfig::SLIRP) - - if(WIN32) - target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi iconv) - endif() -else() - add_subdirectory(slirp) - target_link_libraries(86Box slirp) +if(WIN32) + target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi iconv) endif() if (HAIKU) diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c index 0c73ea028a..868ee036f2 100644 --- a/src/network/net_3c501.c +++ b/src/network/net_3c501.c @@ -56,8 +56,8 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> #include <86box/bswap.h> +#include <86box/plat_unused.h> /* Maximum number of times we report a link down to the guest (failure to send frame) */ #define ELNK_MAX_LINKDOWN_REPORTED 3 @@ -192,7 +192,7 @@ typedef struct ELNK_INTR_STAT { uint8_t unused : 5; } EL_INTR_STAT; -typedef struct { +typedef struct threec501_t { uint32_t base_address; int base_irq; uint32_t bios_addr; @@ -372,8 +372,8 @@ elnkR3HardReset(threec501_t *dev) static __inline int padr_match(threec501_t *dev, const uint8_t *buf) { - struct ether_header *hdr = (struct ether_header *) buf; - int result; + const struct ether_header *hdr = (const struct ether_header *) buf; + int result; /* Checks own + broadcast as well as own + multicast. */ result = (dev->RcvCmd.adr_match >= EL_ADRM_BCAST) && !memcmp(hdr->ether_dhost, dev->aStationAddr, 6); @@ -387,9 +387,10 @@ padr_match(threec501_t *dev, const uint8_t *buf) static __inline int padr_bcast(threec501_t *dev, const uint8_t *buf) { - static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - struct ether_header *hdr = (struct ether_header *) buf; - int result = (dev->RcvCmd.adr_match == EL_ADRM_BCAST) && !memcmp(hdr->ether_dhost, aBCAST, 6); + static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + const struct ether_header *hdr = (const struct ether_header *) buf; + int result = (dev->RcvCmd.adr_match == EL_ADRM_BCAST) && !memcmp(hdr->ether_dhost, aBCAST, 6); + return result; } @@ -399,8 +400,9 @@ padr_bcast(threec501_t *dev, const uint8_t *buf) static __inline int padr_mcast(threec501_t *dev, const uint8_t *buf) { - struct ether_header *hdr = (struct ether_header *) buf; - int result = (dev->RcvCmd.adr_match == EL_ADRM_MCAST) && ETHER_IS_MULTICAST(hdr->ether_dhost); + const struct ether_header *hdr = (const struct ether_header *) buf; + int result = (dev->RcvCmd.adr_match == EL_ADRM_MCAST) && ETHER_IS_MULTICAST(hdr->ether_dhost); + return result; } @@ -692,7 +694,6 @@ elnkAsyncTransmit(threec501_t *dev) #ifdef ENABLE_3COM501_LOG threec501_log("3Com501: illegal giant frame (%u bytes) -> signalling error\n", cb); #endif - ; } } else { /* Signal a transmit error pretending there was a collision. */ @@ -921,6 +922,9 @@ threec501_read(uint16_t addr, void *priv) retval = dev->abPacketBuf[ELNK_GP(dev)]; dev->uGPBufPtr = (dev->uGPBufPtr + 1) & ELNK_GP_MASK; break; + + default: + break; } elnkUpdateIrq(dev); @@ -1007,6 +1011,9 @@ threec501_write(uint16_t addr, uint8_t value, void *priv) dev->abPacketBuf[ELNK_GP(dev)] = value; dev->uGPBufPtr = (dev->uGPBufPtr + 1) & ELNK_GP_MASK; break; + + default: + break; } #ifdef ENABLE_3COM501_LOG @@ -1068,7 +1075,7 @@ elnkR3TimerRestore(void *priv) } static void * -threec501_nic_init(const device_t *info) +threec501_nic_init(UNUSED(const device_t *info)) { uint32_t mac; threec501_t *dev; diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index ce4650456f..11e823326e 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -60,10 +60,10 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_dp8390.h> -#include <86box/net_3c503.h> #include <86box/bswap.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct threec503_t { dp8390_t *dp8390; mem_mapping_t ram_mapping; uint32_t base_address; @@ -129,6 +129,9 @@ threec503_interrupt(void *priv, int set) case 5: dev->regs.idcfr = 0x80; break; + + default: + break; } if (set) @@ -151,7 +154,7 @@ threec503_ram_write(uint32_t addr, uint8_t val, void *priv) static uint8_t threec503_ram_read(uint32_t addr, void *priv) { - threec503_t *dev = (threec503_t *) priv; + const threec503_t *dev = (threec503_t *) priv; if ((addr & 0x3fff) >= 0x2000) return 0xff; @@ -174,6 +177,9 @@ threec503_set_drq(threec503_t *dev) case 3: dev->regs.idcfr = 4; break; + + default: + break; } } @@ -223,6 +229,9 @@ threec503_nic_lo_read(uint16_t addr, void *priv) case 0x03: retval = 0xff; break; + + default: + break; } break; @@ -237,6 +246,9 @@ threec503_nic_lo_read(uint16_t addr, void *priv) case 0x03: retval = 0xff; break; + + default: + break; } return retval; @@ -272,6 +284,9 @@ threec503_nic_lo_write(uint16_t addr, uint8_t val, void *priv) case 0x03: break; + + default: + break; } break; @@ -279,6 +294,9 @@ threec503_nic_lo_write(uint16_t addr, uint8_t val, void *priv) case 0x02: case 0x03: break; + + default: + break; } threec503_log("3Com503: write addr %x, value %x\n", addr, val); @@ -338,7 +356,6 @@ threec503_nic_hi_read(uint16_t addr, void *priv) } return dev->regs.bcfr; - break; case 0x04: switch (dev->bios_addr) { @@ -357,10 +374,12 @@ threec503_nic_hi_read(uint16_t addr, void *priv) case 0xc8000: dev->regs.pcfr = 0x10; break; + + default: + break; } return dev->regs.pcfr; - break; case 0x05: return dev->regs.gacfr; @@ -397,6 +416,9 @@ threec503_nic_hi_read(uint16_t addr, void *priv) threec503_set_drq(dev); return dp8390_chipmem_read(dev->dp8390, dev->regs.da++, 1); + + default: + break; } return 0; @@ -527,6 +549,9 @@ threec503_nic_hi_write(uint16_t addr, uint8_t val, void *priv) dp8390_chipmem_write(dev->dp8390, dev->regs.da++, val, 1); break; + + default: + break; } } @@ -543,7 +568,7 @@ threec503_nic_ioset(threec503_t *dev, uint16_t addr) } static void * -threec503_nic_init(const device_t *info) +threec503_nic_init(UNUSED(const device_t *info)) { uint32_t mac; threec503_t *dev; @@ -605,7 +630,9 @@ threec503_nic_init(const device_t *info) threec503_ram_read, NULL, NULL, threec503_ram_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, dev); - // mem_mapping_disable(&dev->ram_mapping); +#if 0 + mem_mapping_disable(&dev->ram_mapping); +#endif dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */ /* Attach ourselves to the network module. */ diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index a1fa4b3364..1c308e9135 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -29,6 +29,7 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_dp8390.h> +#include <86box/plat_unused.h> static void dp8390_tx(dp8390_t *dev, uint32_t val); static int dp8390_rx_common(void *priv, uint8_t *buf, int io_len); @@ -62,10 +63,10 @@ static int mcast_index(const void *dst) { #define POLYNOMIAL 0x04c11db6 - uint32_t crc = 0xffffffffL; - int carry; - uint8_t b; - uint8_t *ep = (uint8_t *) dst; + uint32_t crc = 0xffffffffL; + int carry; + uint8_t b; + const uint8_t *ep = (const uint8_t *) dst; for (int8_t i = 6; --i >= 0;) { b = *ep++; @@ -242,7 +243,7 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) } static void -dp8390_tx(dp8390_t *dev, uint32_t val) +dp8390_tx(dp8390_t *dev, UNUSED(uint32_t val)) { dev->CR.tx_packet = 0; dev->TSR.tx_ok = 1; @@ -408,7 +409,7 @@ dp8390_rx_common(void *priv, uint8_t *buf, int io_len) int dp8390_rx(void *priv, uint8_t *buf, int io_len) { - dp8390_t *dev = (dp8390_t *) priv; + const dp8390_t *dev = (dp8390_t *) priv; if ((dev->DCR.loop == 0) || (dev->TCR.loop_cntl != 0)) return 0; @@ -506,7 +507,7 @@ dp8390_page0_read(dp8390_t *dev, uint32_t off, unsigned int len) } void -dp8390_page0_write(dp8390_t *dev, uint32_t off, uint32_t val, unsigned len) +dp8390_page0_write(dp8390_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) { uint8_t val2; @@ -697,7 +698,7 @@ dp8390_page0_write(dp8390_t *dev, uint32_t off, uint32_t val, unsigned len) /* Handle reads/writes to the first page of the DS8390 register file. */ uint32_t -dp8390_page1_read(dp8390_t *dev, uint32_t off, unsigned int len) +dp8390_page1_read(dp8390_t *dev, uint32_t off, UNUSED(unsigned int len)) { dp8390_log("DP8390: Page1 read from register 0x%02x, len=%u\n", off, len); @@ -734,7 +735,7 @@ dp8390_page1_read(dp8390_t *dev, uint32_t off, unsigned int len) } void -dp8390_page1_write(dp8390_t *dev, uint32_t off, uint32_t val, unsigned len) +dp8390_page1_write(dp8390_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) { dp8390_log("DP8390: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", off, len, val); @@ -778,7 +779,7 @@ dp8390_page1_write(dp8390_t *dev, uint32_t off, uint32_t val, unsigned len) /* Handle reads/writes to the second page of the DS8390 register file. */ uint32_t -dp8390_page2_read(dp8390_t *dev, uint32_t off, unsigned int len) +dp8390_page2_read(dp8390_t *dev, uint32_t off, UNUSED(unsigned int len)) { dp8390_log("DP8390: Page2 read from register 0x%02x, len=%u\n", off, len); @@ -835,7 +836,7 @@ dp8390_page2_read(dp8390_t *dev, uint32_t off, unsigned int len) } void -dp8390_page2_write(dp8390_t *dev, uint32_t off, uint32_t val, unsigned len) +dp8390_page2_write(dp8390_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) { /* Maybe all writes here should be BX_PANIC()'d, since they affect internal operation, but let them through for now @@ -999,7 +1000,7 @@ dp8390_soft_reset(dp8390_t *dev) } static void * -dp8390_init(const device_t *info) +dp8390_init(UNUSED(const device_t *info)) { dp8390_t *dp8390 = (dp8390_t *) malloc(sizeof(dp8390_t)); memset(dp8390, 0, sizeof(dp8390_t)); diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c new file mode 100644 index 0000000000..6812637178 --- /dev/null +++ b/src/network/net_eeprom_nmc93cxx.c @@ -0,0 +1,284 @@ +/* + * 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. + * + * Emulation of National Semiconductors NMC93Cxx EEPROMs. + * + * + * Authors: Cacodemon345 + * + * Copyright 2023 Cacodemon345 + */ + +/* Ported over from QEMU */ + +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/vid_ati_eeprom.h> +#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/plat_unused.h> + +struct nmc93cxx_eeprom_t { + ati_eeprom_t dev; + uint8_t addrbits; + uint16_t size; + char filename[1024]; +}; + +typedef struct nmc93cxx_eeprom_t nmc93cxx_eeprom_t; + +#ifdef ENABLE_NMC93CXX_EEPROM_LOG +int nmc93cxx_eeprom_do_log = ENABLE_NMC93CXX_EEPROM_LOG; + +static void +nmc93cxx_eeprom_log(int lvl, const char *fmt, ...) +{ + va_list ap; + + if (nmc93cxx_eeprom_do_log >= lvl) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define nmc93cxx_eeprom_log(lvl, fmt, ...) +#endif + +static void * +nmc93cxx_eeprom_init_params(UNUSED(const device_t *info), void *params) +{ + uint16_t nwords = 64; + uint8_t addrbits = 6; + uint8_t filldefault = 1; + nmc93cxx_eeprom_params_t *params_details = (nmc93cxx_eeprom_params_t *) params; + nmc93cxx_eeprom_t *eeprom = NULL; + if (!params) + return NULL; + + nwords = params_details->nwords; + + switch (nwords) { + case 16: + case 64: + addrbits = 6; + break; + case 128: + case 256: + addrbits = 8; + break; + default: + nwords = 64; + addrbits = 6; + break; + } + eeprom = calloc(1, sizeof(nmc93cxx_eeprom_t) + ((nwords + 1) * 2)); + if (!eeprom) + 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); + } + } + + if (filldefault) { + memcpy(eeprom->dev.data, params_details->default_content, nwords * sizeof(uint16_t)); + } + + return eeprom; +} + +void +nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi) +{ + 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; + } + } else if (command == 3) { + /* Erase word. */ + eeprom->dev.data[address] = 0xffff; + } else if (tick >= 2 + 2 + eeprom->addrbits + 16) { + if (command == 1) { + /* Write word. */ + eeprom->dev.data[address] &= eeprom->dev.dat; + } else if (command == 0 && subcommand == 1) { + /* Write all. */ + for (address = 0; address < eeprom->size; address++) { + eeprom->dev.data[address] &= eeprom->dev.dat; + } + } + } + } + /* 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 + } + } 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"); + } + } else if (tick < 2 + 2) { + /* Got 2 start bits, transfer 2 opcode bits. */ + tick++; + command <<= 1; + if (eedi) { + command += 1; + } + } 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; + } + } else { + /* Read, write or erase word. */ + eeprom->dev.dat = eeprom->dev.data[address]; + } + } + } else if (tick < 2 + 2 + eeprom->addrbits + 16) { + /* Transfer 16 data bits. */ + tick++; + if (command == 2) { + /* Read word. */ + eedo = ((eeprom->dev.dat & 0x8000) != 0); + } + eeprom->dev.dat <<= 1; + eeprom->dev.dat += eedi; + } else { + nmc93cxx_eeprom_log(1, "additional unneeded tick, not processed\n"); + } + } + /* 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) +{ + /* Return status of pin DO (0 or 1). */ + return eeprom->dev.out; +} + +static void +nmc93cxx_eeprom_close(void *priv) +{ + nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; + FILE *fp = nvr_fopen(eeprom->filename, "wb"); + if (fp) { + fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fclose(fp); + } + free(priv); +} + +uint16_t * +nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) +{ + if (UNLIKELY(!eeprom)) + return NULL; + /* Get EEPROM data array. */ + return &eeprom->dev.data[0]; +} + +const device_t nmc93cxx_device = { + .name = "National Semiconductor NMC93Cxx", + .internal_name = "nmc93cxx", + .flags = DEVICE_EXTPARAMS, + .local = 0, + .init_ext = nmc93cxx_eeprom_init_params, + .close = nmc93cxx_eeprom_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/network/net_event.c b/src/network/net_event.c index 6e68f1fe34..c39c12254b 100644 --- a/src/network/net_event.c +++ b/src/network/net_event.c @@ -7,6 +7,7 @@ #endif #include <86box/net_event.h> +#include <86box/plat_unused.h> #ifndef _WIN32 static void @@ -40,7 +41,7 @@ net_event_set(net_evt_t *event) } void -net_event_clear(net_evt_t *event) +net_event_clear(UNUSED(net_evt_t *event)) { #ifdef _WIN32 /* Do nothing on WIN32 since we use an auto-reset event */ diff --git a/src/network/net_l80225.c b/src/network/net_l80225.c new file mode 100644 index 0000000000..6493edec6d --- /dev/null +++ b/src/network/net_l80225.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/dma.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/network.h> + +uint16_t +l80225_mii_readw(uint16_t *regs, uint16_t addr) +{ + switch (addr) { + case 0x1: + return 0x782D; + case 0x2: + return 0b10110; + case 0x3: + return 0xF830; + case 0x5: + return 0x41E1; + case 0x18: + return 0xC0; + default: + return regs[addr]; + } + return 0; +} + +void +l80225_mii_writew(uint16_t *regs, uint16_t addr, uint16_t val) +{ + regs[addr] = val; +} diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 263d389703..03327ac0c7 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -68,6 +68,8 @@ #include <86box/net_ne2000.h> #include <86box/bswap.h> #include <86box/isapnp.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> /* ROM BIOS file paths. */ #define ROM_PATH_NE1000 "roms/network/ne1000/ne1000.rom" @@ -80,46 +82,47 @@ #define PCI_DEVID 0x8029 /* RTL8029AS */ #define PCI_REGSIZE 256 /* size of PCI space */ -static uint8_t rtl8019as_pnp_rom[] = { - 0x4a, 0x8c, 0x80, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* RTL8019, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x22, 0x00, 'R', 'E', 'A', 'L', 'T', 'E', 'K', ' ', 'P', 'L', 'U', 'G', ' ', '&', ' ', 'P', 'L', 'A', 'Y', ' ', 'E', 'T', 'H', 'E', 'R', 'N', 'E', 'T', ' ', 'C', 'A', 'R', 'D', 0x00, /* ANSI identifier */ +typedef struct nic_t { + dp8390_t *dp8390; - 0x16, 0x4a, 0x8c, 0x80, 0x19, 0x02, 0x00, /* logical device RTL8019 */ - 0x1c, 0x41, 0xd0, 0x80, 0xd6, /* compatible device PNP80D6 */ - 0x47, 0x00, 0x20, 0x02, 0x80, 0x03, 0x20, 0x20, /* I/O 0x220-0x380, decodes 10-bit, 32-byte alignment, 32 addresses */ - 0x23, 0x38, 0x9e, 0x01, /* IRQ 3/4/5/9/10/11/12/15, high true edge sensitive */ + const char *name; - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ -}; + uint8_t pnp_csnsav; + uint8_t pci_slot; + uint8_t irq_state; + uint8_t pad; + + /* RTL8019AS/RTL8029AS registers */ + uint8_t config0; + uint8_t config2; + uint8_t config3; + uint8_t _9346cr; + + uint8_t pci_regs[PCI_REGSIZE]; + uint8_t eeprom[128]; /* for RTL8029AS */ + + uint8_t maclocal[6]; /* configured MAC (local) address */ + + /* POS registers, MCA boards only */ + uint8_t pos_regs[8]; -typedef struct { - dp8390_t *dp8390; - const char *name; int board; - int is_pci, is_mca, is_8bit; - uint32_t base_address; + int is_pci; + int is_mca; + int is_8bit; int base_irq; - uint32_t bios_addr, - bios_size, - bios_mask; - int card; /* PCI card slot */ - int has_bios, pad; - bar_t pci_bar[2]; - uint8_t pci_regs[PCI_REGSIZE]; - uint8_t eeprom[128]; /* for RTL8029AS */ - rom_t bios_rom; - void *pnp_card; - uint8_t pnp_csnsav; - uint8_t maclocal[6]; /* configured MAC (local) address */ + int has_bios; - /* RTL8019AS/RTL8029AS registers */ - uint8_t config0, config2, config3; - uint8_t _9346cr; - uint32_t pad0; + uint32_t base_address; + uint32_t bios_addr; + uint32_t bios_size; + uint32_t bios_mask; - /* POS registers, MCA boards only */ - uint8_t pos_regs[8]; + bar_t pci_bar[2]; + + rom_t bios_rom; + + void *pnp_card; } nic_t; #ifdef ENABLE_NE2K_LOG @@ -147,9 +150,9 @@ nic_interrupt(void *priv, int set) if (dev->is_pci) { if (set) - pci_set_irq(dev->card, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else - pci_clear_irq(dev->card, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } else { if (set) picint(1 << dev->base_irq); @@ -308,7 +311,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) /* Writes to this page are illegal. */ static uint32_t -page3_read(nic_t *dev, uint32_t off, unsigned int len) +page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len)) { if (dev->board >= NE2K_RTL8019AS) switch (off) { @@ -346,7 +349,7 @@ page3_read(nic_t *dev, uint32_t off, unsigned int len) } static void -page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) { if (dev->board >= NE2K_RTL8019AS) { nelog(3, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", @@ -521,7 +524,7 @@ nic_pnp_read_vendor_reg(uint8_t ld, uint8_t reg, void *priv) if (ld != 0) return 0x00; - nic_t *dev = (nic_t *) priv; + const nic_t *dev = (nic_t *) priv; switch (reg) { case 0xF0: @@ -535,6 +538,9 @@ nic_pnp_read_vendor_reg(uint8_t ld, uint8_t reg, void *priv) case 0xF5: return dev->pnp_csnsav; + + default: + break; } return 0x00; @@ -623,10 +629,10 @@ nic_update_bios(nic_t *dev) } static uint8_t -nic_pci_read(int func, int addr, void *priv) +nic_pci_read(UNUSED(int func), int addr, void *priv) { - nic_t *dev = (nic_t *) priv; - uint8_t ret = 0x00; + const nic_t *dev = (nic_t *) priv; + uint8_t ret = 0x00; switch (addr) { case 0x00: /* PCI_VID_LO */ @@ -707,6 +713,9 @@ nic_pci_read(int func, int addr, void *priv) case 0x3D: /* PCI_IPR */ ret = dev->pci_regs[addr]; break; + + default: + break; } nelog(2, "%s: PCI_Read(%d, %04x) = %02x\n", dev->name, func, addr, ret); @@ -715,7 +724,7 @@ nic_pci_read(int func, int addr, void *priv) } static void -nic_pci_write(int func, int addr, uint8_t val, void *priv) +nic_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { nic_t *dev = (nic_t *) priv; uint8_t valxor; @@ -737,7 +746,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x10: /* PCI_BAR */ val &= 0xe0; /* 0xe0 acc to RTL DS */ val |= 0x01; /* re-enable IOIN bit */ - /*FALLTHROUGH*/ + fallthrough; case 0x11: /* PCI_BAR */ case 0x12: /* PCI_BAR */ @@ -767,7 +776,9 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x32: /* PCI_ROMBAR */ case 0x33: /* PCI_ROMBAR */ dev->pci_bar[1].addr_regs[addr & 3] = val; - /* dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; */ +#if 0 + dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; +#endif dev->pci_bar[1].addr &= 0xffff8001; dev->bios_addr = dev->pci_bar[1].addr & 0xffff8000; nic_update_bios(dev); @@ -778,6 +789,9 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) dev->base_irq = val; dev->pci_regs[addr] = dev->base_irq; return; + + default: + break; } } @@ -785,7 +799,7 @@ static void nic_rom_init(nic_t *dev, char *s) { uint32_t temp; - FILE *f; + FILE *fp; if (s == NULL) return; @@ -793,10 +807,10 @@ nic_rom_init(nic_t *dev, char *s) if (dev->bios_addr == 0) return; - if ((f = rom_fopen(s, "rb")) != NULL) { - fseek(f, 0L, SEEK_END); - temp = ftell(f); - fclose(f); + if ((fp = rom_fopen(s, "rb")) != NULL) { + fseek(fp, 0L, SEEK_END); + temp = ftell(fp); + fclose(fp); dev->bios_size = 0x10000; if (temp <= 0x8000) dev->bios_size = 0x8000; @@ -823,7 +837,7 @@ nic_rom_init(nic_t *dev, char *s) static uint8_t nic_mca_read(int port, void *priv) { - nic_t *dev = (nic_t *) priv; + const nic_t *dev = (nic_t *) priv; return (dev->pos_regs[port & 7]); } @@ -888,7 +902,7 @@ nic_mca_write(int port, uint8_t val, void *priv) static uint8_t nic_mca_feedb(void *priv) { - nic_t *dev = (nic_t *) priv; + const nic_t *dev = (nic_t *) priv; return (dev->pos_regs[2] & 0x01); } @@ -920,7 +934,7 @@ nic_init(const device_t *info) if (dev->board != NE2K_ETHERNEXT_MC) { dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); - if (dev->board == NE2K_NE2000) { + if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT)) { dev->bios_addr = device_get_config_hex20("bios_addr"); dev->has_bios = !!dev->bios_addr; } else { @@ -966,6 +980,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); break; + case NE2K_NE1000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + dev->is_8bit = 1; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); + break; + case NE2K_NE2000: dev->maclocal[0] = 0x00; /* 00:00:D8 (Novell OID) */ dev->maclocal[1] = 0x00; @@ -975,6 +999,15 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_NE2000_COMPAT: + dev->maclocal[0] = 0x00; /* 00:86:B0 (86Box OID) */ + dev->maclocal[1] = 0x86; + dev->maclocal[2] = 0xB0; + rom = ROM_PATH_NE2000; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); + break; + case NE2K_ETHERNEXT_MC: dev->maclocal[0] = 0x00; /* 00:00:D8 (Networth Inc. OID) */ dev->maclocal[1] = 0x00; @@ -986,6 +1019,16 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; + case NE2K_DE220P: + dev->maclocal[0] = 0x00; /* 00:80:C8 (D-Link OID) */ + dev->maclocal[1] = 0x80; + dev->maclocal[2] = 0xC8; + rom = NULL; + dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CLEAR_IRQ); + dp8390_set_id(dev->dp8390, 0x50, 0x70); + dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); + break; + case NE2K_RTL8019AS: case NE2K_RTL8029AS: dev->is_pci = (dev->board == NE2K_RTL8029AS) ? 1 : 0; @@ -1000,6 +1043,9 @@ nic_init(const device_t *info) dp8390_set_id(dev->dp8390, 0x50, (dev->board == NE2K_RTL8019AS) ? 0x70 : 0x43); dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); break; + + default: + break; } memcpy(dev->dp8390->physaddr, dev->maclocal, sizeof(dev->maclocal)); @@ -1013,7 +1059,7 @@ nic_init(const device_t *info) * Make this device known to the I/O system. * PnP and PCI devices start with address spaces inactive. */ - if (dev->board < NE2K_RTL8019AS && dev->board != NE2K_ETHERNEXT_MC) + if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC)) nic_ioset(dev, dev->base_address); /* Set up our BIOS ROM space, if any. */ @@ -1064,8 +1110,7 @@ nic_init(const device_t *info) mem_mapping_disable(&dev->bios_rom.mapping); /* Add device to the PCI bus, keep its slot number. */ - dev->card = pci_add_card(PCI_ADD_NORMAL, - nic_pci_read, nic_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev, &dev->pci_slot); } /* Initialize the RTL8029 EEPROM. */ @@ -1079,9 +1124,44 @@ nic_init(const device_t *info) dev->eeprom[0x78] = dev->eeprom[0x7C] = (PCI_VENDID & 0xff); dev->eeprom[0x79] = dev->eeprom[0x7D] = (PCI_VENDID >> 8); } else { - memcpy(&dev->eeprom[0x12], rtl8019as_pnp_rom, sizeof(rtl8019as_pnp_rom)); + const char *pnp_rom_file = NULL; + int pnp_rom_len = 0x4a; + switch (dev->board) { + case NE2K_RTL8019AS: + pnp_rom_file = "roms/network/rtl8019as/RTL8019A.BIN"; + break; + + case NE2K_DE220P: + pnp_rom_file = "roms/network/de220p/dlk2201a.bin"; + pnp_rom_len = 0x43; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(&dev->eeprom[0x12], 1, pnp_rom_len, fp) == pnp_rom_len) + pnp_rom = &dev->eeprom[0x12]; + fclose(fp); + } + } - dev->pnp_card = isapnp_add_card(&dev->eeprom[0x12], sizeof(rtl8019as_pnp_rom), nic_pnp_config_changed, nic_pnp_csn_changed, nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, dev); + switch (info->local) { + case NE2K_RTL8019AS: + case NE2K_DE220P: + dev->pnp_card = isapnp_add_card(pnp_rom, pnp_rom_len, + nic_pnp_config_changed, nic_pnp_csn_changed, + nic_pnp_read_vendor_reg, nic_pnp_write_vendor_reg, + dev); + break; + + default: + break; + } } } @@ -1108,6 +1188,18 @@ nic_close(void *priv) free(dev); } +static int +rtl8019as_available(void) +{ + return rom_present("roms/network/rtl8019as/RTL8019A.BIN"); +} + +static int +de220p_available(void) +{ + return rom_present("roms/network/de220p/dlk2201a.bin"); +} + // clang-format off static const device_config_t ne1000_config[] = { { @@ -1119,12 +1211,69 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne1000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, { .description = "" } }, }, @@ -1137,12 +1286,13 @@ static const device_config_t ne1000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, - { .description = "IRQ 10", .value = 10 }, - { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 9", .value = 9 }, { .description = "" } }, }, @@ -1166,12 +1316,85 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x360", .value = 0x360 }, + { .description = "" } + }, + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 10, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0x00000 }, + { .description = "D000", .value = 0xD0000 }, + { .description = "D800", .value = 0xD8000 }, + { .description = "C800", .value = 0xC8000 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t ne2000_compat_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x300, + .file_filter = "", + .spinner = { 0 }, + .selection = { + /* Source: Windows 95 .INF file. */ + { .description = "0x200", .value = 0x200 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, { .description = "0x280", .value = 0x280 }, + { .description = "0x2a0", .value = 0x2a0 }, + { .description = "0x2c0", .value = 0x2c0 }, + { .description = "0x2e0", .value = 0x2e0 }, { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, { .description = "0x380", .value = 0x380 }, + { .description = "0x3a0", .value = 0x3a0 }, + { .description = "0x3c0", .value = 0x3c0 }, + { .description = "0x3e0", .value = 0x3e0 }, { .description = "" } }, }, @@ -1184,12 +1407,18 @@ static const device_config_t ne2000_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "IRQ 2", .value = 2 }, + /* Source: Windows 95 .INF file - not giving impossible IRQ's + such as 6, 8, or 13. */ { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 14", .value = 14 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -1262,7 +1491,7 @@ static const device_config_t mca_mac_config[] = { const device_t ne1000_device = { .name = "Novell NE1000", - .internal_name = "ne1k", + .internal_name = "novell_ne1k", .flags = DEVICE_ISA, .local = NE2K_NE1000, .init = nic_init, @@ -1274,9 +1503,23 @@ const device_t ne1000_device = { .config = ne1000_config }; +const device_t ne1000_compat_device = { + .name = "NE1000 Compatible", + .internal_name = "ne1k", + .flags = DEVICE_ISA, + .local = NE2K_NE1000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne1000_compat_config +}; + const device_t ne2000_device = { .name = "Novell NE2000", - .internal_name = "ne2k", + .internal_name = "novell_ne2k", .flags = DEVICE_ISA | DEVICE_AT, .local = NE2K_NE2000, .init = nic_init, @@ -1288,6 +1531,20 @@ const device_t ne2000_device = { .config = ne2000_config }; +const device_t ne2000_compat_device = { + .name = "NE2000 Compatible", + .internal_name = "ne2k", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_NE2000_COMPAT, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ne2000_compat_config +}; + const device_t ethernext_mc_device = { .name = "NetWorth EtherNext/MC", .internal_name = "ethernextmc", @@ -1310,7 +1567,21 @@ const device_t rtl8019as_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + { .available = rtl8019as_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rtl8019as_config +}; + +const device_t de220p_device = { + .name = "D-Link DE-220P", + .internal_name = "de220p", + .flags = DEVICE_ISA | DEVICE_AT, + .local = NE2K_DE220P, + .init = nic_init, + .close = nic_close, + .reset = NULL, + { .available = de220p_available }, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8019as_config diff --git a/src/network/net_null.c b/src/network/net_null.c index 27a0d4da77..6fb3f34405 100644 --- a/src/network/net_null.c +++ b/src/network/net_null.c @@ -37,6 +37,7 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_event.h> +#include <86box/plat_unused.h> enum { NET_EVENT_STOP = 0, @@ -53,7 +54,7 @@ enum { #define NULL_PKT_BATCH NET_QUEUE_LEN -typedef struct { +typedef struct net_null_t { uint8_t mac_addr[6]; netcard_t *card; thread_t *poll_tid; @@ -158,7 +159,7 @@ net_null_thread(void *priv) #endif void * -net_null_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char *netdrv_errbuf) +net_null_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), UNUSED(char *netdrv_errbuf)) { net_null_log("Null Network: Init\n"); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index b9e2f32e8c..e1747580b1 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -122,15 +122,15 @@ struct pcap_if { }; struct pcap_send_queue { - u_int maxlen; /* Maximum size of the queue, in bytes. This + unsigned int maxlen; /* Maximum size of the queue, in bytes. This variable contains the size of the buffer field. */ - u_int len; /* Current size of the queue, in bytes. */ + unsigned int len; /* Current size of the queue, in bytes. */ char *buffer; /* Buffer containing the packets to be sent. */ }; typedef struct pcap_send_queue pcap_send_queue; -typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes); +typedef void (*pcap_handler)(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *bytes); #endif typedef struct { @@ -169,15 +169,15 @@ static int (*f_pcap_setnonblock)(void *, int, char *); static int (*f_pcap_set_immediate_mode)(void *, int); static int (*f_pcap_set_promisc)(void *, int); static int (*f_pcap_set_snaplen)(void *, int); -static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user); +static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, unsigned char *user); static void *(*f_pcap_create)(const char *, char *); static int (*f_pcap_activate)(void *); static void *(*f_pcap_geterr)(void *); #ifdef _WIN32 static HANDLE (*f_pcap_getevent)(void *); static int (*f_pcap_sendqueue_queue)(void *, void *, void *); -static u_int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); -static void *(*f_pcap_sendqueue_alloc)(u_int memsize); +static unsigned int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); +static void *(*f_pcap_sendqueue_alloc)(unsigned int memsize); static void (*f_pcap_sendqueue_destroy)(void *); #else static int (*f_pcap_get_selectable_fd)(void *); @@ -247,7 +247,7 @@ net_pcap_in(void *pcap, uint8_t *bufp, int len) if (pcap == NULL) return; - f_pcap_sendpacket((void *) pcap, bufp, len); + f_pcap_sendpacket(pcap, bufp, len); } void @@ -268,7 +268,7 @@ net_pcap_thread(void *priv) HANDLE events[NET_EVENT_MAX]; events[NET_EVENT_STOP] = net_event_get_handle(&pcap->stop_event); events[NET_EVENT_TX] = net_event_get_handle(&pcap->tx_event); - events[NET_EVENT_RX] = f_pcap_getevent((void *) pcap->pcap); + events[NET_EVENT_RX] = f_pcap_getevent(pcap->pcap); bool run = true; @@ -294,7 +294,10 @@ net_pcap_thread(void *priv) break; case NET_EVENT_RX: - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); + break; + + default: break; } } @@ -338,7 +341,7 @@ net_pcap_thread(void *priv) } if (pfd[NET_EVENT_RX].revents & POLLIN) { - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); } } @@ -467,22 +470,22 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char * return NULL; } - if (f_pcap_setnonblock((void *) pcap->pcap, 1, errbuf) != 0) + if (f_pcap_setnonblock(pcap->pcap, 1, errbuf) != 0) pcap_log("PCAP: failed nonblock %s\n", errbuf); - if (f_pcap_set_immediate_mode((void *) pcap->pcap, 1) != 0) + if (f_pcap_set_immediate_mode(pcap->pcap, 1) != 0) pcap_log("PCAP: error setting immediate mode\n"); - if (f_pcap_set_promisc((void *) pcap->pcap, 1) != 0) + if (f_pcap_set_promisc(pcap->pcap, 1) != 0) pcap_log("PCAP: error enabling promiscuous mode\n"); - if (f_pcap_set_snaplen((void *) pcap->pcap, NET_MAX_FRAME) != 0) + if (f_pcap_set_snaplen(pcap->pcap, NET_MAX_FRAME) != 0) pcap_log("PCAP: error setting snaplen\n"); - if (f_pcap_activate((void *) pcap->pcap) != 0) { + if (f_pcap_activate(pcap->pcap) != 0) { snprintf(errbuf_prep, NET_DRV_ERRBUF_SIZE, "%s", (char *)f_pcap_geterr(pcap->pcap)); net_pcap_error(netdrv_errbuf, errbuf_prep); - f_pcap_close((void *) pcap->pcap); + f_pcap_close(pcap->pcap); free(pcap); return NULL; } @@ -494,18 +497,18 @@ net_pcap_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char * "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - if (f_pcap_compile((void *) pcap->pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - if (f_pcap_setfilter((void *) pcap->pcap, &fp) != 0) { + if (f_pcap_compile(pcap->pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { + if (f_pcap_setfilter(pcap->pcap, &fp) != 0) { snprintf(errbuf_prep, NET_DRV_ERRBUF_SIZE, "Error installing filter (%s)\n", filter_exp); net_pcap_error(netdrv_errbuf, errbuf_prep); - f_pcap_close((void *) pcap->pcap); + f_pcap_close(pcap->pcap); free(pcap); return NULL; } } else { - snprintf(errbuf_prep, NET_DRV_ERRBUF_SIZE, "Could not compile filter (%s) : %s!\n", filter_exp, (char *)f_pcap_geterr((void *) pcap->pcap)); + snprintf(errbuf_prep, NET_DRV_ERRBUF_SIZE, "Could not compile filter (%s) : %s!\n", filter_exp, (char *)f_pcap_geterr(pcap->pcap)); net_pcap_error(netdrv_errbuf, errbuf_prep); - f_pcap_close((void *) pcap->pcap); + f_pcap_close(pcap->pcap); free(pcap); return NULL; } @@ -554,7 +557,7 @@ net_pcap_close(void *priv) f_pcap_sendqueue_destroy((void *) pcap->pcap_queue); #endif /* OK, now shut down Pcap itself. */ - f_pcap_close((void *) pcap->pcap); + f_pcap_close(pcap->pcap); net_event_close(&pcap->tx_event); net_event_close(&pcap->stop_event); diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index b1ea475ae6..9ddcfe29d6 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -47,6 +47,8 @@ #include <86box/network.h> #include <86box/net_pcnet.h> #include <86box/bswap.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> /* PCI info. */ #define PCI_VENDID 0x1022 /* AMD */ @@ -215,7 +217,8 @@ typedef struct { uint32_t base_address; int base_irq; int dma_channel; - int card; /* PCI card slot */ + uint8_t pci_slot; /* PCI card slot */ + uint8_t irq_state; int xmit_pos; /** Register Address Pointer */ uint32_t u32RAP; @@ -412,9 +415,9 @@ pcnet_do_irq(nic_t *dev, int issue) { if (dev->is_pci) { if (issue) - pci_set_irq(dev->card, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else - pci_clear_irq(dev->card, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } else { if (issue) picint(1 << dev->base_irq); @@ -744,11 +747,12 @@ static const uint32_t crctab[256] = }; static __inline int -padr_match(nic_t *dev, const uint8_t *buf, int size) +padr_match(nic_t *dev, const uint8_t *buf, UNUSED(int size)) { - struct ether_header *hdr = (struct ether_header *) buf; - int result; - uint8_t padr[6]; + const struct ether_header *hdr = (const struct ether_header *) buf; + int result; + uint8_t padr[6]; + padr[0] = dev->aCSR[12] & 0xff; padr[1] = dev->aCSR[12] >> 8; padr[2] = dev->aCSR[13] & 0xff; @@ -768,19 +772,22 @@ padr_match(nic_t *dev, const uint8_t *buf, int size) } static __inline int -padr_bcast(nic_t *dev, const uint8_t *buf, size_t size) +padr_bcast(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { - static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - struct ether_header *hdr = (struct ether_header *) buf; - int result = !CSR_DRCVBC(dev) && !memcmp(hdr->ether_dhost, aBCAST, 6); + static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + const struct ether_header *hdr = (const struct ether_header *) buf; + int result = !CSR_DRCVBC(dev) && !memcmp(hdr->ether_dhost, aBCAST, 6); + pcnet_log(3, "%s: padr_bcast result=%d\n", dev->name, result); + return result; } static int -ladr_match(nic_t *dev, const uint8_t *buf, size_t size) +ladr_match(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { - struct ether_header *hdr = (struct ether_header *) buf; + const struct ether_header *hdr = (const struct ether_header *) buf; + if ((hdr->ether_dhost[0] & 0x01) && ((uint64_t *) &dev->aCSR[8])[0] != 0LL) { int index; uint8_t ladr[8]; @@ -859,7 +866,10 @@ pcnetSoftReset(nic_t *dev) case DEV_AM79C960_VLB: case DEV_AM79C961: dev->aCSR[88] = 0x3003; - dev->aCSR[89] = 0x0262; + dev->aCSR[89] = 0x0000; + break; + + default: break; } @@ -1263,14 +1273,14 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) ++; pcnet_log(2, "%s: pcnetReceiveNoSync: packet missed\n", dev->name); } else { - RTNETETHERHDR *pEth = (RTNETETHERHDR *) buf; - int fStrip = 0; - size_t len_802_3; - uint8_t *src = &dev->abRecvBuf[8]; - uint32_t crda = CSR_CRDA(dev); - uint32_t next_crda; - RMD rmd; - RMD next_rmd; + const RTNETETHERHDR *pEth = (RTNETETHERHDR *) buf; + int fStrip = 0; + size_t len_802_3; + uint8_t *src = &dev->abRecvBuf[8]; + uint32_t crda = CSR_CRDA(dev); + uint32_t next_crda; + RMD rmd; + RMD next_rmd; /* * Ethernet framing considers these two octets to be @@ -1297,8 +1307,8 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) while (size < 60) src[size++] = 0; - uint32_t fcs = UINT32_MAX; - uint8_t *p = src; + uint32_t fcs = UINT32_MAX; + const uint8_t *p = src; while (p != &src[size]) CRC(fcs, *p++); @@ -1308,7 +1318,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) size += 4; } - cbPacket = (int) size; + cbPacket = size; pcnetRmdLoad(dev, &rmd, PHYSADDR(dev, crda), 0); /* if (!CSR_LAPPEN(dev)) */ @@ -1680,9 +1690,9 @@ pcnetPollRxTx(nic_t *dev) } static void -pcnetPollTimer(void *p) +pcnetPollTimer(void *priv) { - nic_t *dev = (nic_t *) p; + nic_t *dev = (nic_t *) priv; timer_advance_u64(&dev->timer, 2000 * TIMER_USEC); @@ -1989,7 +1999,7 @@ pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val) break; } dev->aCSR[58] = val; - /* fall through */ + fallthrough; case BCR_LNKST: case BCR_LED1: case BCR_LED2: @@ -2223,6 +2233,9 @@ pcnet_word_write(nic_t *dev, uint32_t addr, uint16_t val) case 0x06: pcnet_bcr_writew(dev, dev->u32RAP, val); break; + + default: + break; } } } @@ -2238,6 +2251,9 @@ pcnet_byte_read(nic_t *dev, uint32_t addr) pcnetSoftReset(dev); val = 0; break; + + default: + break; } } @@ -2275,6 +2291,9 @@ pcnet_word_read(nic_t *dev, uint32_t addr) case 0x06: val = pcnet_bcr_readw(dev, dev->u32RAP); break; + + default: + break; } } @@ -2302,6 +2321,9 @@ pcnet_dword_write(nic_t *dev, uint32_t addr, uint32_t val) case 0x0c: pcnet_bcr_writew(dev, dev->u32RAP, val & 0xffff); break; + + default: + break; } } else if ((addr & 0x0f) == 0) { /* switch device to dword i/o mode */ @@ -2334,6 +2356,9 @@ pcnet_dword_read(nic_t *dev, uint32_t addr) case 0x0c: val = pcnet_bcr_readw(dev, dev->u32RAP); break; + + default: + break; } } @@ -2540,9 +2565,9 @@ pcnet_ioset(nic_t *dev, uint16_t addr, int len) } static void -pcnet_pci_write(int func, int addr, uint8_t val, void *p) +pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - nic_t *dev = (nic_t *) p; + nic_t *dev = (nic_t *) priv; uint8_t valxor; pcnet_log(4, "%s: Write value %02X to register %02X\n", dev->name, val, addr & 0xff); @@ -2616,13 +2641,16 @@ pcnet_pci_write(int func, int addr, uint8_t val, void *p) dev->base_irq = val; pcnet_pci_regs[addr] = val; return; + + default: + break; } } static uint8_t -pcnet_pci_read(int func, int addr, void *p) +pcnet_pci_read(UNUSED(int func), int addr, void *priv) { - nic_t *dev = (nic_t *) p; + const nic_t *dev = (nic_t *) priv; pcnet_log(4, "%s: Read to register %02X\n", dev->name, addr & 0xff); @@ -2687,6 +2715,9 @@ pcnet_pci_read(int func, int addr, void *p) return 0x06; case 0x3F: return 0xff; + + default: + break; } return 0; @@ -2731,7 +2762,7 @@ pcnet_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) static uint8_t pcnet_pnp_read_vendor_reg(uint8_t ld, uint8_t reg, void *priv) { - nic_t *dev = (nic_t *) priv; + const nic_t *dev = (nic_t *) priv; if (!ld && (reg == 0xf0)) return dev->aPROM[50]; @@ -2865,7 +2896,7 @@ pcnet_init(const device_t *info) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->name = info->name; - dev->board = info->local; + dev->board = info->local & 0xff; dev->is_pci = !!(info->flags & DEVICE_PCI); dev->is_vlb = !!(info->flags & DEVICE_VLB); @@ -2966,8 +2997,10 @@ pcnet_init(const device_t *info) pcnet_pci_regs[0x04] = 3; /* Add device to the PCI bus, keep its slot number. */ - dev->card = pci_add_card(PCI_ADD_NORMAL, - pcnet_pci_read, pcnet_pci_write, dev); + if (info->local & 0x0100) + pci_add_card(PCI_ADD_NETWORK, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); } else if (dev->board == DEV_AM79C961) { dev->dma_channel = -1; @@ -3071,9 +3104,12 @@ static const device_config_t pcnet_isa_config[] = { { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -3086,6 +3122,7 @@ static const device_config_t pcnet_isa_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { + { .description = "DMA 0", .value = 0 }, { .description = "DMA 3", .value = 3 }, { .description = "DMA 5", .value = 5 }, { .description = "DMA 6", .value = 6 }, @@ -3132,9 +3169,12 @@ static const device_config_t pcnet_vlb_config[] = { { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 15", .value = 15 }, { .description = "" } }, }, @@ -3232,3 +3272,17 @@ const device_t pcnet_am79c973_device = { .force_redraw = NULL, .config = pcnet_pci_config }; + +const device_t pcnet_am79c973_onboard_device = { + .name = "AMD PCnet-FAST III", + .internal_name = "pcnetfast_onboard", + .flags = DEVICE_PCI, + .local = DEV_AM79C973 | 0x0100, + .init = pcnet_init, + .close = pcnet_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pcnet_pci_config +}; diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 58274e62a4..41e5502a67 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -34,7 +34,7 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_plip.h> +#include <86box/plat_unused.h> enum { PLIP_START = 0x00, @@ -57,20 +57,28 @@ enum { PLIP_END = 0x40 }; -typedef struct -{ +typedef struct plip_t { uint8_t mac[6]; void *lpt; pc_timer_t rx_timer; pc_timer_t timeout_timer; - uint8_t status, ctrl; - - uint8_t state, ack, tx_checksum, tx_checksum_calc, *tx_pkt; - uint16_t tx_len, tx_ptr; - - uint8_t *rx_pkt, rx_checksum, rx_return_state; - uint16_t rx_len, rx_ptr; + uint8_t status; + uint8_t ctrl; + + uint8_t state; + uint8_t ack; + uint8_t tx_checksum; + uint8_t tx_checksum_calc; + uint8_t *tx_pkt; + uint16_t tx_len; + uint16_t tx_ptr; + + uint8_t *rx_pkt; + uint8_t rx_checksum; + uint8_t rx_return_state; + uint16_t rx_len; + uint16_t rx_ptr; netcard_t *card; } plip_t; @@ -334,6 +342,9 @@ plip_write_data(uint8_t val, void *priv) /* Disengage timeout timer. */ timer_disable(&dev->timeout_timer); return; + + default: + break; } /* Engage timeout timer unless otherwise specified. */ @@ -356,7 +367,7 @@ plip_write_ctrl(uint8_t val, void *priv) static uint8_t plip_read_status(void *priv) { - plip_t *dev = (plip_t *) priv; + const plip_t *dev = (plip_t *) priv; plip_log(3, "PLIP: read_status() = %02X\n", dev->status); @@ -454,7 +465,7 @@ plip_lpt_init(void *lpt) } static void * -plip_net_init(const device_t *info) +plip_net_init(UNUSED(const device_t *info)) { plip_log(1, "PLIP: net_init()"); diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c new file mode 100644 index 0000000000..a7c007115c --- /dev/null +++ b/src/network/net_rtl8139.c @@ -0,0 +1,3334 @@ +/* + * 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. + * + * Emulation of Realtek RTL8139C+ NIC. + * + * Authors: Igor Kovalenko, + * Mark Malakanov, + * Jurgen Lock, + * Frediano Ziglio, + * Benjamin Poirier. + * Cacodemon345, + * + * Copyright 2006-2023 Igor Kovalenko. + * Copyright 2006-2023 Mark Malakanov. + * Copyright 2006-2023 Jurgen Lock. + * Copyright 2010-2023 Frediano Ziglio. + * Copyright 2011-2023 Benjamin Poirier. + * Copyright 2023 Cacodemon345. + */ +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/random.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/dma.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/network.h> +#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/bswap.h> +#include <86box/nvr.h> +#include "cpu.h" +#include <86box/plat_unused.h> + +#define PCI_PERIOD 30 /* 30 ns period = 33.333333 Mhz frequency */ + +#define SET_MASKED(input, mask, curr) \ + (((input) & ~(mask)) | ((curr) & (mask))) + +/* arg % size for size which is a power of 2 */ +#define MOD2(input, size) \ + ((input) & (size - 1)) + +#define ETHER_TYPE_LEN 2 + +#define VLAN_TCI_LEN 2 +#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN) + +#ifdef ENABLE_RTL8139_LOG +int rtl8139_do_log = ENABLE_RTL8139_LOG; + +static void +rtl8139_log(const char *fmt, ...) +{ + va_list ap; + + if (rtl8139_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define rtl8139_log(fmt, ...) +#endif + +struct RTL8139State; +typedef struct RTL8139State RTL8139State; + +/* Symbolic offsets to registers. */ +enum RTL8139_registers { + MAC0 = 0, /* Ethernet hardware address. */ + MAR0 = 8, /* Multicast filter. */ + TxStatus0 = 0x10, /* Transmit status (Four 32bit registers). C mode only */ + /* Dump Tally Conter control register(64bit). C+ mode only */ + TxAddr0 = 0x20, /* Tx descriptors (also four 32bit). */ + RxBuf = 0x30, + ChipCmd = 0x37, + RxBufPtr = 0x38, + RxBufAddr = 0x3A, + IntrMask = 0x3C, + IntrStatus = 0x3E, + TxConfig = 0x40, + RxConfig = 0x44, + Timer = 0x48, /* A general-purpose counter. */ + RxMissed = 0x4C, /* 24 bits valid, write clears. */ + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + FlashReg = 0x54, + MediaStatus = 0x58, + Config3 = 0x59, + Config4 = 0x5A, /* absent on RTL-8139A */ + HltClk = 0x5B, + MultiIntr = 0x5C, + PCIRevisionID = 0x5E, + TxSummary = 0x60, /* TSAD register. Transmit Status of All Descriptors*/ + BasicModeCtrl = 0x62, + BasicModeStatus = 0x64, + NWayAdvert = 0x66, + NWayLPAR = 0x68, + NWayExpansion = 0x6A, + /* Undocumented registers, but required for proper operation. */ + FIFOTMS = 0x70, /* FIFO Control and test. */ + CSCR = 0x74, /* Chip Status and Configuration Register. */ + PARA78 = 0x78, + PARA7c = 0x7c, /* Magic transceiver parameter register. */ + Config5 = 0xD8, /* absent on RTL-8139A */ + /* C+ mode */ + TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */ + RxMaxSize = 0xDA, /* Max size of an Rx packet (8169 only) */ + CpCmd = 0xE0, /* C+ Command register (C+ mode only) */ + IntrMitigate = 0xE2, /* rx/tx interrupt mitigation control */ + RxRingAddrLO = 0xE4, /* 64-bit start addr of Rx ring */ + RxRingAddrHI = 0xE8, /* 64-bit start addr of Rx ring */ + TxThresh = 0xEC, /* Early Tx threshold */ +}; + +enum ClearBitMasks { + MultiIntrClear = 0xF000, + ChipCmdClear = 0xE2, + Config1Clear = (1 << 7) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 1), +}; + +enum ChipCmdBits { + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, +}; + +/* C+ mode */ +enum CplusCmdBits { + CPlusRxVLAN = 0x0040, /* enable receive VLAN detagging */ + CPlusRxChkSum = 0x0020, /* enable receive checksum offloading */ + CPlusRxEnb = 0x0002, + CPlusTxEnb = 0x0001, +}; + +/* Interrupt register bits, using my own meaningful names. */ +enum IntrStatusBits { + PCIErr = 0x8000, + PCSTimeout = 0x4000, + RxFIFOOver = 0x40, + RxUnderrun = 0x20, /* Packet Underrun / Link Change */ + RxOverflow = 0x10, + TxErr = 0x08, + TxOK = 0x04, + RxErr = 0x02, + RxOK = 0x01, + + RxAckBits = RxFIFOOver | RxOverflow | RxOK, +}; + +enum TxStatusBits { + TxHostOwns = 0x2000, + TxUnderrun = 0x4000, + TxStatOK = 0x8000, + TxOutOfWindow = 0x20000000, + TxAborted = 0x40000000, + TxCarrierLost = 0x80000000, +}; +enum RxStatusBits { + RxMulticast = 0x8000, + RxPhysical = 0x4000, + RxBroadcast = 0x2000, + RxBadSymbol = 0x0020, + RxRunt = 0x0010, + RxTooLong = 0x0008, + RxCRCErr = 0x0004, + RxBadAlign = 0x0002, + RxStatusOK = 0x0001, +}; + +/* Bits in RxConfig. */ +enum rx_mode_bits { + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, +}; + +/* Bits in TxConfig. */ +enum tx_config_bits { + + /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */ + TxIFGShift = 24, + TxIFG84 = (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */ + TxIFG88 = (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */ + TxIFG92 = (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */ + TxIFG96 = (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */ + + TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */ + TxCRC = (1 << 16), /* DISABLE appending CRC to end of Tx packets */ + TxClearAbt = (1 << 0), /* Clear abort (WO) */ + TxDMAShift = 8, /* DMA burst value (0-7) is shifted this many bits */ + TxRetryShift = 4, /* TXRR value (0-15) is shifted this many bits */ + + TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */ +}; + +/* Transmit Status of All Descriptors (TSAD) Register */ +enum TSAD_bits { + TSAD_TOK3 = 1 << 15, // TOK bit of Descriptor 3 + TSAD_TOK2 = 1 << 14, // TOK bit of Descriptor 2 + TSAD_TOK1 = 1 << 13, // TOK bit of Descriptor 1 + TSAD_TOK0 = 1 << 12, // TOK bit of Descriptor 0 + TSAD_TUN3 = 1 << 11, // TUN bit of Descriptor 3 + TSAD_TUN2 = 1 << 10, // TUN bit of Descriptor 2 + TSAD_TUN1 = 1 << 9, // TUN bit of Descriptor 1 + TSAD_TUN0 = 1 << 8, // TUN bit of Descriptor 0 + TSAD_TABT3 = 1 << 07, // TABT bit of Descriptor 3 + TSAD_TABT2 = 1 << 06, // TABT bit of Descriptor 2 + TSAD_TABT1 = 1 << 05, // TABT bit of Descriptor 1 + TSAD_TABT0 = 1 << 04, // TABT bit of Descriptor 0 + TSAD_OWN3 = 1 << 03, // OWN bit of Descriptor 3 + TSAD_OWN2 = 1 << 02, // OWN bit of Descriptor 2 + TSAD_OWN1 = 1 << 01, // OWN bit of Descriptor 1 + TSAD_OWN0 = 1 << 00, // OWN bit of Descriptor 0 +}; + +/* Bits in Config1 */ +enum Config1Bits { + Cfg1_PM_Enable = 0x01, + Cfg1_VPD_Enable = 0x02, + Cfg1_PIO = 0x04, + Cfg1_MMIO = 0x08, + LWAKE = 0x10, /* not on 8139, 8139A */ + Cfg1_Driver_Load = 0x20, + Cfg1_LED0 = 0x40, + Cfg1_LED1 = 0x80, + SLEEP = (1 << 1), /* only on 8139, 8139A */ + PWRDN = (1 << 0), /* only on 8139, 8139A */ +}; + +/* Bits in Config3 */ +enum Config3Bits { + Cfg3_FBtBEn = (1 << 0), /* 1 = Fast Back to Back */ + Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */ + Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */ + Cfg3_CardB_En = (1 << 3), /* 1 = enable CardBus registers */ + Cfg3_LinkUp = (1 << 4), /* 1 = wake up on link up */ + Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */ + Cfg3_PARM_En = (1 << 6), /* 0 = software can set twister parameters */ + Cfg3_GNTSel = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */ +}; + +/* Bits in Config4 */ +enum Config4Bits { + LWPTN = (1 << 2), /* not on 8139, 8139A */ +}; + +/* Bits in Config5 */ +enum Config5Bits { + Cfg5_PME_STS = (1 << 0), /* 1 = PCI reset resets PME_Status */ + Cfg5_LANWake = (1 << 1), /* 1 = enable LANWake signal */ + Cfg5_LDPS = (1 << 2), /* 0 = save power when link is down */ + Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */ + Cfg5_UWF = (1 << 4), /* 1 = accept unicast wakeup frame */ + Cfg5_MWF = (1 << 5), /* 1 = accept multicast wakeup frame */ + Cfg5_BWF = (1 << 6), /* 1 = accept broadcast wakeup frame */ +}; + +enum RxConfigBits { + /* rx fifo threshold */ + RxCfgFIFOShift = 13, + RxCfgFIFONone = (7 << RxCfgFIFOShift), + + /* Max DMA burst */ + RxCfgDMAShift = 8, + RxCfgDMAUnlimited = (7 << RxCfgDMAShift), + + /* rx ring buffer length */ + RxCfgRcv8K = 0, + RxCfgRcv16K = (1 << 11), + RxCfgRcv32K = (1 << 12), + RxCfgRcv64K = (1 << 11) | (1 << 12), + + /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */ + RxNoWrap = (1 << 7), +}; + +/* Twister tuning parameters from RealTek. + Completely undocumented, but required to tune bad links on some boards. */ +#if 0 +enum CSCRBits { + CSCR_LinkOKBit = 0x0400, + CSCR_LinkChangeBit = 0x0800, + CSCR_LinkStatusBits = 0x0f000, + CSCR_LinkDownOffCmd = 0x003c0, + CSCR_LinkDownCmd = 0x0f3c0, +#endif +enum CSCRBits { + CSCR_Testfun = 1 << 15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */ + CSCR_Cable_Changed = 1 << 11, /* Undocumented: 1 = Cable status changed, 0 = No change */ + CSCR_Cable = 1 << 10, /* Undocumented: 1 = Cable connected, 0 = Cable disconnected */ + CSCR_LD = 1 << 9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/ + CSCR_HEART_BIT = 1 << 8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/ + CSCR_JBEN = 1 << 7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/ + CSCR_F_LINK_100 = 1 << 6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/ + CSCR_F_Connect = 1 << 5, /* Assertion of this bit forces the disconnect function to be bypassed. def 0*/ + CSCR_Con_status = 1 << 3, /* This bit indicates the status of the connection. 1 = valid connected link detected; 0 = disconnected link detected. RO def 0*/ + CSCR_Con_status_En = 1 << 2, /* Assertion of this bit configures LED1 pin to indicate connection status. def 0*/ + CSCR_PASS_SCR = 1 << 0, /* Bypass Scramble, def 0*/ +}; + +enum Cfg9346Bits { + Cfg9346_Normal = 0x00, + Cfg9346_Autoload = 0x40, + Cfg9346_Programming = 0x80, + Cfg9346_ConfigWrite = 0xC0, +}; + +typedef enum { + CH_8139 = 0, + CH_8139_K, + CH_8139A, + CH_8139A_G, + CH_8139B, + CH_8130, + CH_8139C, + CH_8100, + CH_8100B_8139D, + CH_8101, +} chip_t; + +enum chip_flags { + HasHltClk = (1 << 0), + HasLWake = (1 << 1), +}; + +#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \ + (b30 << 30 | b29 << 29 | b28 << 28 | b27 << 27 | b26 << 26 | b23 << 23 | b22 << 22) +#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1) + +#define RTL8139_PCI_REVID_8139 0x10 +#define RTL8139_PCI_REVID_8139CPLUS 0x20 + +#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS + +#pragma pack(push, 1) +typedef struct RTL8139TallyCounters { + /* Tally counters */ + uint64_t TxOk; + uint64_t RxOk; + uint64_t TxERR; + uint32_t RxERR; + uint16_t MissPkt; + uint16_t FAE; + uint32_t Tx1Col; + uint32_t TxMCol; + uint64_t RxOkPhy; + uint64_t RxOkBrd; + uint32_t RxOkMul; + uint16_t TxAbt; + uint16_t TxUndrn; +} RTL8139TallyCounters; +#pragma pack(pop) + +/* Clears all tally counters */ +static void RTL8139TallyCounters_clear(RTL8139TallyCounters *counters); + +struct RTL8139State { + /*< private >*/ + uint8_t pci_slot; + uint8_t inst; + uint8_t irq_state; + uint8_t pad; + /*< public >*/ + + uint8_t phys[8]; /* mac address */ + uint8_t mult[8]; /* multicast mask array */ + uint8_t pci_conf[256]; + + uint32_t TxStatus[4]; /* TxStatus0 in C mode*/ /* also DTCCR[0] and DTCCR[1] in C+ mode */ + uint32_t TxAddr[4]; /* TxAddr0 */ + uint32_t RxBuf; /* Receive buffer */ + uint32_t RxBufferSize; /* internal variable, receive ring buffer size in C mode */ + uint32_t RxBufPtr; + uint32_t RxBufAddr; + + uint16_t IntrStatus; + uint16_t IntrMask; + + uint32_t TxConfig; + uint32_t RxConfig; + uint32_t RxMissed; + + uint16_t CSCR; + + uint8_t Cfg9346; + uint8_t Config0; + uint8_t Config1; + uint8_t Config3; + uint8_t Config4; + uint8_t Config5; + + uint8_t clock_enabled; + uint8_t bChipCmdState; + + uint16_t MultiIntr; + + uint16_t BasicModeCtrl; + uint16_t BasicModeStatus; + uint16_t NWayAdvert; + uint16_t NWayLPAR; + uint16_t NWayExpansion; + + uint16_t CpCmd; + + uint8_t TxThresh; + uint8_t pci_latency; + + netcard_t *nic; + + /* C ring mode */ + uint32_t currTxDesc; + + /* C+ mode */ + uint32_t cplus_enabled; + + uint32_t currCPlusRxDesc; + uint32_t currCPlusTxDesc; + + uint32_t RxRingAddrLO; + uint32_t RxRingAddrHI; + + uint32_t TCTR; + uint32_t TimerInt; + int64_t TCTR_base; + + /* Tally counters */ + RTL8139TallyCounters tally_counters; + + /* Non-persistent data */ + uint8_t *cplus_txbuffer; + int cplus_txbuffer_len; + int cplus_txbuffer_offset; + + uint32_t mem_base; + + /* PCI interrupt timer */ + pc_timer_t timer; + + mem_mapping_t bar_mem; + + /* Support migration to/from old versions */ + int rtl8139_mmio_io_addr_dummy; + + nmc93cxx_eeprom_t *eeprom; + uint8_t eeprom_data[128]; +}; + +/* Writes tally counters to memory via DMA */ +static void RTL8139TallyCounters_dma_write(RTL8139State *s, uint32_t tc_addr); + +static void +rtl8139_update_irq(RTL8139State *s) +{ + uint8_t d = s->pci_slot; + int isr; + + isr = (s->IntrStatus & s->IntrMask) & 0xffff; + + rtl8139_log("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus, + s->IntrMask); + + if (isr != 0) + pci_set_irq(d, PCI_INTA, &s->irq_state); + else + pci_clear_irq(d, PCI_INTA, &s->irq_state); +} + +static int +rtl8139_RxWrap(RTL8139State *s) +{ + /* wrapping enabled; assume 1.5k more buffer space if size < 65536 */ + return (s->RxConfig & (1 << 7)); +} + +static int +rtl8139_receiver_enabled(RTL8139State *s) +{ + return s->bChipCmdState & CmdRxEnb; +} + +static int +rtl8139_transmitter_enabled(RTL8139State *s) +{ + return s->bChipCmdState & CmdTxEnb; +} + +static int +rtl8139_cp_receiver_enabled(RTL8139State *s) +{ + return s->CpCmd & CPlusRxEnb; +} + +static int +rtl8139_cp_transmitter_enabled(RTL8139State *s) +{ + return s->CpCmd & CPlusTxEnb; +} + +static void +rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) +{ + if (s->RxBufAddr + size > s->RxBufferSize) { + int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize); + + /* write packet data */ + if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s))) { + rtl8139_log(">>> rx packet wrapped in buffer at %d\n", size - wrapped); + + if (size > wrapped) { + dma_bm_write(s->RxBuf + s->RxBufAddr, + buf, size - wrapped, 1); + } + + /* reset buffer pointer */ + s->RxBufAddr = 0; + + dma_bm_write(s->RxBuf + s->RxBufAddr, + buf + (size - wrapped), wrapped, 1); + + s->RxBufAddr = wrapped; + + return; + } + } + + /* non-wrapping path or overwrapping enabled */ + dma_bm_write(s->RxBuf + s->RxBufAddr, buf, size, 1); + + s->RxBufAddr += size; +} + +static __inline uint32_t +rtl8139_addr64(uint32_t low, UNUSED(uint32_t high)) +{ + return low; +} + +/* Workaround for buggy guest driver such as linux who allocates rx + * rings after the receiver were enabled. */ +static bool +rtl8139_cp_rx_valid(RTL8139State *s) +{ + return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0); +} + +static bool +rtl8139_can_receive(RTL8139State *s) +{ + int avail; + + /* Receive (drop) packets if card is disabled. */ + if (!s->clock_enabled) { + return true; + } + if (!rtl8139_receiver_enabled(s)) { + return true; + } + + if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) { + /* ??? Flow control not implemented in c+ mode. + This is a hack to work around slirp deficiencies anyway. */ + return true; + } + + avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, + s->RxBufferSize); + return avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow); +} + +/* From FreeBSD */ +/* XXX: optimize */ +static uint32_t +net_crc32(const uint8_t *p, int len) +{ + uint32_t crc; + int carry; + uint8_t b; + + crc = 0xffffffff; + for (int i = 0; i < len; i++) { + b = *p++; + for (uint8_t j = 0; j < 8; j++) { + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); + crc <<= 1; + b >>= 1; + if (carry) { + crc = ((crc ^ 0x04c11db6) | carry); + } + } + } + + return crc; +} + +uint32_t +net_crc32_le(const uint8_t *p, int len) +{ + uint32_t crc; + int carry; + uint8_t b; + + crc = 0xffffffff; + for (int i = 0; i < len; i++) { + b = *p++; + for (uint8_t j = 0; j < 8; j++) { + carry = (crc & 0x1) ^ (b & 0x01); + crc >>= 1; + b >>= 1; + if (carry) { + crc ^= 0xedb88320; + } + } + } + + return crc; +} + +#define ETH_ALEN 6 +static int +rtl8139_do_receive(void *priv, uint8_t *buf, int size_) +{ + RTL8139State *s = (RTL8139State *) priv; + /* size is the length of the buffer passed to the driver */ + size_t size = size_; + const uint8_t *dot1q_buf = NULL; + + uint32_t packet_header = 0; + uint8_t buf1[60 + VLAN_HLEN]; + + static const uint8_t broadcast_macaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + rtl8139_log(">>> received len=%u\n", (uint32_t) size); + + if (!rtl8139_can_receive(s)) + return 0; + + /* test if board clock is stopped */ + if (!s->clock_enabled) { + rtl8139_log("stopped ==========================\n"); + return -1; + } + + /* first check if receiver is enabled */ + + if (!rtl8139_receiver_enabled(s)) { + rtl8139_log("receiver disabled ================\n"); + return -1; + } + + /* XXX: check this */ + if (s->RxConfig & AcceptAllPhys) { + /* promiscuous: receive all */ + rtl8139_log(">>> packet received in promiscuous mode\n"); + + } else { + if (!memcmp(buf, broadcast_macaddr, 6)) { + /* broadcast address */ + if (!(s->RxConfig & AcceptBroadcast)) { + rtl8139_log(">>> broadcast packet rejected\n"); + + /* update tally counter */ + ++s->tally_counters.RxERR; + + return size; + } + + packet_header |= RxBroadcast; + + rtl8139_log(">>> broadcast packet received\n"); + + /* update tally counter */ + ++s->tally_counters.RxOkBrd; + + } else if (buf[0] & 0x01) { + /* multicast */ + if (!(s->RxConfig & AcceptMulticast)) { + rtl8139_log(">>> multicast packet rejected\n"); + + /* update tally counter */ + ++s->tally_counters.RxERR; + + return size; + } + + int mcast_idx = net_crc32(buf, ETH_ALEN) >> 26; + + if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) { + rtl8139_log(">>> multicast address mismatch\n"); + + /* update tally counter */ + ++s->tally_counters.RxERR; + + return size; + } + + packet_header |= RxMulticast; + + rtl8139_log(">>> multicast packet received\n"); + + /* update tally counter */ + ++s->tally_counters.RxOkMul; + + } else if (s->phys[0] == buf[0] && s->phys[1] == buf[1] && s->phys[2] == buf[2] && s->phys[3] == buf[3] && s->phys[4] == buf[4] && s->phys[5] == buf[5]) { + /* match */ + if (!(s->RxConfig & AcceptMyPhys)) { + rtl8139_log(">>> rejecting physical address matching packet\n"); + + /* update tally counter */ + ++s->tally_counters.RxERR; + + return size; + } + + packet_header |= RxPhysical; + + rtl8139_log(">>> physical address matching packet received\n"); + + /* update tally counter */ + ++s->tally_counters.RxOkPhy; + + } else { + + rtl8139_log(">>> unknown packet\n"); + + /* update tally counter */ + ++s->tally_counters.RxERR; + + return size; + } + } + + if (size < 60 + VLAN_HLEN) { + memcpy(buf1, buf, size); + memset(buf1 + size, 0, 60 + VLAN_HLEN - size); + buf = buf1; + if (size < 60) { + size = 60; + } + } + + if (rtl8139_cp_receiver_enabled(s)) { + if (!rtl8139_cp_rx_valid(s)) { + return size; + } + + rtl8139_log("in C+ Rx mode ================\n"); + + /* begin C+ receiver mode */ + +/* w0 ownership flag */ +#define CP_RX_OWN (1 << 31) +/* w0 end of ring flag */ +#define CP_RX_EOR (1 << 30) +/* w0 bits 0...12 : buffer size */ +#define CP_RX_BUFFER_SIZE_MASK ((1 << 13) - 1) +/* w1 tag available flag */ +#define CP_RX_TAVA (1 << 16) +/* w1 bits 0...15 : VLAN tag */ +#define CP_RX_VLAN_TAG_MASK ((1 << 16) - 1) + /* w2 low 32bit of Rx buffer ptr */ + /* w3 high 32bit of Rx buffer ptr */ + + int descriptor = s->currCPlusRxDesc; + uint32_t cplus_rx_ring_desc; + + cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI); + cplus_rx_ring_desc += 16 * descriptor; + + rtl8139_log("+++ C+ mode reading RX descriptor %d from host memory at " + "%08x %08x = " + "0x%8X" + "\n", + descriptor, s->RxRingAddrHI, + s->RxRingAddrLO, cplus_rx_ring_desc); + + uint32_t val; + uint32_t rxdw0; + uint32_t rxdw1; + uint32_t rxbufLO; + uint32_t rxbufHI; + + dma_bm_read(cplus_rx_ring_desc, (uint8_t *) &val, 4, 4); + rxdw0 = val; + dma_bm_read(cplus_rx_ring_desc + 4, (uint8_t *) &val, 4, 4); + rxdw1 = val; + dma_bm_read(cplus_rx_ring_desc + 8, (uint8_t *) &val, 4, 4); + rxbufLO = val; + dma_bm_read(cplus_rx_ring_desc + 12, (uint8_t *) &val, 4, 4); + rxbufHI = val; + + rtl8139_log("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", + descriptor, rxdw0, rxdw1, rxbufLO, rxbufHI); + + if (!(rxdw0 & CP_RX_OWN)) { + rtl8139_log("C+ Rx mode : descriptor %d is owned by host\n", + descriptor); + + s->IntrStatus |= RxOverflow; + ++s->RxMissed; + + /* update tally counter */ + ++s->tally_counters.RxERR; + ++s->tally_counters.MissPkt; + + rtl8139_update_irq(s); + return size_; + } + + uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK; + + /* write VLAN info to descriptor variables. */ + if (s->CpCmd & CPlusRxVLAN && bswap16(*((uint16_t *) &buf[ETH_ALEN * 2])) == 0x8100) { + dot1q_buf = &buf[ETH_ALEN * 2]; + size -= VLAN_HLEN; + /* if too small buffer, use the tailroom added duing expansion */ + if (size < 60) { + size = 60; + } + + rxdw1 &= ~CP_RX_VLAN_TAG_MASK; + /* BE + ~le_to_cpu()~ + cpu_to_le() = BE */ + rxdw1 |= CP_RX_TAVA | *((uint16_t *) (&dot1q_buf[ETHER_TYPE_LEN])); + + rtl8139_log("C+ Rx mode : extracted vlan tag with tci: " + "%u\n", + bswap16(*((uint16_t *) &dot1q_buf[ETHER_TYPE_LEN]))); + } else { + /* reset VLAN tag flag */ + rxdw1 &= ~CP_RX_TAVA; + } + + /* TODO: scatter the packet over available receive ring descriptors space */ + + if (size + 4 > rx_space) { + rtl8139_log("C+ Rx mode : descriptor %d size %d received %u + 4\n", + descriptor, rx_space, (uint32_t) size); + + s->IntrStatus |= RxOverflow; + ++s->RxMissed; + + /* update tally counter */ + ++s->tally_counters.RxERR; + ++s->tally_counters.MissPkt; + + rtl8139_update_irq(s); + return size_; + } + + uint32_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); + + /* receive/copy to target memory */ + if (dot1q_buf) { + dma_bm_write(rx_addr, buf, 2 * ETH_ALEN, 1); + dma_bm_write(rx_addr + 2 * ETH_ALEN, + buf + 2 * ETH_ALEN + VLAN_HLEN, + size - 2 * ETH_ALEN, 1); + } else { + dma_bm_write(rx_addr, buf, size, 1); + } + + if (s->CpCmd & CPlusRxChkSum) { + /* do some packet checksumming */ + } + + /* write checksum */ + val = (net_crc32_le(buf, size_)); + dma_bm_write(rx_addr + size, (uint8_t *) &val, 4, 4); + +/* first segment of received packet flag */ +#define CP_RX_STATUS_FS (1 << 29) +/* last segment of received packet flag */ +#define CP_RX_STATUS_LS (1 << 28) +/* multicast packet flag */ +#define CP_RX_STATUS_MAR (1 << 26) +/* physical-matching packet flag */ +#define CP_RX_STATUS_PAM (1 << 25) +/* broadcast packet flag */ +#define CP_RX_STATUS_BAR (1 << 24) +/* runt packet flag */ +#define CP_RX_STATUS_RUNT (1 << 19) +/* crc error flag */ +#define CP_RX_STATUS_CRC (1 << 18) +/* IP checksum error flag */ +#define CP_RX_STATUS_IPF (1 << 15) +/* UDP checksum error flag */ +#define CP_RX_STATUS_UDPF (1 << 14) +/* TCP checksum error flag */ +#define CP_RX_STATUS_TCPF (1 << 13) + + /* transfer ownership to target */ + rxdw0 &= ~CP_RX_OWN; + + /* set first segment bit */ + rxdw0 |= CP_RX_STATUS_FS; + + /* set last segment bit */ + rxdw0 |= CP_RX_STATUS_LS; + + /* set received packet type flags */ + if (packet_header & RxBroadcast) + rxdw0 |= CP_RX_STATUS_BAR; + if (packet_header & RxMulticast) + rxdw0 |= CP_RX_STATUS_MAR; + if (packet_header & RxPhysical) + rxdw0 |= CP_RX_STATUS_PAM; + + /* set received size */ + rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK; + rxdw0 |= (size + 4); + + /* update ring data */ + val = rxdw0; + dma_bm_write(cplus_rx_ring_desc, (uint8_t *) &val, 4, 4); + val = rxdw1; + dma_bm_write(cplus_rx_ring_desc + 4, (uint8_t *) &val, 4, 4); + + /* update tally counter */ + ++s->tally_counters.RxOk; + + /* seek to next Rx descriptor */ + if (rxdw0 & CP_RX_EOR) { + s->currCPlusRxDesc = 0; + } else { + ++s->currCPlusRxDesc; + } + + rtl8139_log("done C+ Rx mode ----------------\n"); + + } else { + rtl8139_log("in ring Rx mode ================\n"); + + /* begin ring receiver mode */ + int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize); + + /* if receiver buffer is empty then avail == 0 */ + +#define RX_ALIGN(x) (((x) + 3) & ~0x3) + + if (avail != 0 && RX_ALIGN(size + 8) >= avail) { + rtl8139_log("rx overflow: rx buffer length %d head 0x%04x " + "read 0x%04x === available 0x%04x need 0x%04zx\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8); + + s->IntrStatus |= RxOverflow; + ++s->RxMissed; + rtl8139_update_irq(s); + return 0; + } + + packet_header |= RxStatusOK; + + packet_header |= (((size + 4) << 16) & 0xffff0000); + + /* write header */ + uint32_t val = packet_header; + + rtl8139_write_buffer(s, (uint8_t *) &val, 4); + + rtl8139_write_buffer(s, buf, size); + + /* write checksum */ + val = (net_crc32_le(buf, size)); + rtl8139_write_buffer(s, (uint8_t *) &val, 4); + + /* correct buffer write pointer */ + s->RxBufAddr = MOD2(RX_ALIGN(s->RxBufAddr), s->RxBufferSize); + + /* now we can signal we have received something */ + + rtl8139_log("received: rx buffer length %d head 0x%04x read 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); + } + + s->IntrStatus |= RxOK; + + { + rtl8139_update_irq(s); + } + + return size_; +} + +static void +rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize) +{ + s->RxBufferSize = bufferSize; + s->RxBufPtr = 0; + s->RxBufAddr = 0; +} + +static void +rtl8139_reset_phy(RTL8139State *s) +{ + s->BasicModeStatus = 0x7809; + s->BasicModeStatus |= 0x0020; /* autonegotiation completed */ + /* preserve link state */ + s->BasicModeStatus |= (net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) ? 0 : 0x04; + + s->NWayAdvert = 0x05e1; /* all modes, full duplex */ + s->NWayLPAR = 0x05e1; /* all modes, full duplex */ + s->NWayExpansion = 0x0001; /* autonegotiation supported */ + + s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD; +} + +static void +rtl8139_reset(void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + /* reset interrupt mask */ + s->IntrStatus = 0; + s->IntrMask = 0; + + rtl8139_update_irq(s); + + /* mark all status registers as owned by host */ + for (uint8_t i = 0; i < 4; ++i) { + s->TxStatus[i] = TxHostOwns; + } + + s->currTxDesc = 0; + s->currCPlusRxDesc = 0; + s->currCPlusTxDesc = 0; + + s->RxRingAddrLO = 0; + s->RxRingAddrHI = 0; + + s->RxBuf = 0; + + rtl8139_reset_rxring(s, 8192); + + /* ACK the reset */ + s->TxConfig = 0; + +#if 0 +// s->TxConfig |= HW_REVID(1, 0, 0, 0, 0, 0, 0); // RTL-8139 HasHltClk + s->clock_enabled = 0; +#else + s->TxConfig |= HW_REVID(1, 1, 1, 0, 1, 1, 0); // RTL-8139C+ HasLWake + s->clock_enabled = 1; +#endif + + s->bChipCmdState = CmdReset; /* RxBufEmpty bit is calculated on read from ChipCmd */ + + /* set initial state data */ + s->Config0 = 0x0; /* No boot ROM */ + s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */ + s->Config3 = 0x1; /* fast back-to-back compatible */ + s->Config5 = 0x0; + + s->CpCmd = 0x0; /* reset C+ mode */ + s->cplus_enabled = 0; + +#if 0 + s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation + s->BasicModeCtrl = 0x2100; // 100Mbps, full duplex +#endif + s->BasicModeCtrl = 0x1000; // autonegotiation + + rtl8139_reset_phy(s); + + /* also reset timer and disable timer interrupt */ + s->TCTR = 0; + s->TimerInt = 0; + s->TCTR_base = 0; +#if 0 + rtl8139_set_next_tctr_time(s); +#endif + + /* reset tally counters */ + RTL8139TallyCounters_clear(&s->tally_counters); +} + +static void +RTL8139TallyCounters_clear(RTL8139TallyCounters *counters) +{ + counters->TxOk = 0; + counters->RxOk = 0; + counters->TxERR = 0; + counters->RxERR = 0; + counters->MissPkt = 0; + counters->FAE = 0; + counters->Tx1Col = 0; + counters->TxMCol = 0; + counters->RxOkPhy = 0; + counters->RxOkBrd = 0; + counters->RxOkMul = 0; + counters->TxAbt = 0; + counters->TxUndrn = 0; +} + +static void +RTL8139TallyCounters_dma_write(RTL8139State *s, uint32_t tc_addr) +{ + RTL8139TallyCounters *tally_counters = &s->tally_counters; + + dma_bm_write(tc_addr, (uint8_t *) tally_counters, sizeof(RTL8139TallyCounters), 1); +} + +static void +rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("ChipCmd write val=0x%08x\n", val); + + if (val & CmdReset) { + rtl8139_log("ChipCmd reset\n"); + rtl8139_reset(s); + } + if (val & CmdRxEnb) { + rtl8139_log("ChipCmd enable receiver\n"); + + s->currCPlusRxDesc = 0; + } + if (val & CmdTxEnb) { + rtl8139_log("ChipCmd enable transmitter\n"); + + s->currCPlusTxDesc = 0; + } + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xe3, s->bChipCmdState); + + /* Deassert reset pin before next read */ + val &= ~CmdReset; + + s->bChipCmdState = val; +} + +static int +rtl8139_RxBufferEmpty(RTL8139State *s) +{ + int unread = MOD2(s->RxBufferSize + s->RxBufAddr - s->RxBufPtr, s->RxBufferSize); + + if (unread != 0) { + rtl8139_log("receiver buffer data available 0x%04x\n", unread); + return 0; + } + + rtl8139_log("receiver buffer is empty\n"); + + return 1; +} + +static uint32_t +rtl8139_ChipCmd_read(RTL8139State *s) +{ + uint32_t ret = s->bChipCmdState; + + if (rtl8139_RxBufferEmpty(s)) + ret |= RxBufEmpty; + + rtl8139_log("ChipCmd read val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_CpCmd_write(RTL8139State *s, uint32_t val) +{ + val &= 0xffff; + + rtl8139_log("C+ command register write(w) val=0x%04x\n", val); + + s->cplus_enabled = 1; + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xff84, s->CpCmd); + + s->CpCmd = val; +} + +static uint32_t +rtl8139_CpCmd_read(RTL8139State *s) +{ + uint32_t ret = s->CpCmd; + + rtl8139_log("C+ command register read(w) val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_IntrMitigate_write(UNUSED(RTL8139State *s), uint32_t val) +{ + rtl8139_log("C+ IntrMitigate register write(w) val=0x%04x\n", val); +} + +static uint32_t +rtl8139_IntrMitigate_read(UNUSED(RTL8139State *s)) +{ + uint32_t ret = 0; + + rtl8139_log("C+ IntrMitigate register read(w) val=0x%04x\n", ret); + + return ret; +} + +static int +rtl8139_config_writable(RTL8139State *s) +{ + if ((s->Cfg9346 & 0xc0) == 0xc0) + return 1; + + rtl8139_log("Configuration registers are write-protected\n"); + + return 0; +} + +static void +rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val) +{ + val &= 0xffff; + + rtl8139_log("BasicModeCtrl register write(w) val=0x%04x\n", val); + + /* mask unwritable bits */ + uint32_t mask = 0xccff; + + if (1 || !rtl8139_config_writable(s)) { + /* Speed setting and autonegotiation enable bits are read-only */ + mask |= 0x3000; + /* Duplex mode setting is read-only */ + mask |= 0x0100; + } + + if (val & 0x8000) { + /* Reset PHY */ + rtl8139_reset_phy(s); + } + + val = SET_MASKED(val, mask, s->BasicModeCtrl); + + s->BasicModeCtrl = val; +} + +static uint32_t +rtl8139_BasicModeCtrl_read(RTL8139State *s) +{ + uint32_t ret = s->BasicModeCtrl; + + rtl8139_log("BasicModeCtrl register read(w) val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val) +{ + val &= 0xffff; + + rtl8139_log("BasicModeStatus register write(w) val=0x%04x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xff3f, s->BasicModeStatus); + + s->BasicModeStatus = val; +} + +static uint32_t +rtl8139_BasicModeStatus_read(RTL8139State *s) +{ + uint32_t ret = s->BasicModeStatus; + + rtl8139_log("BasicModeStatus register read(w) val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Cfg9346 write val=0x%02x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0x31, s->Cfg9346); + + uint32_t opmode = val & 0xc0; + uint32_t eeprom_val = val & 0xf; + + if (opmode == 0x80) { + /* eeprom access */ + nmc93cxx_eeprom_write(s->eeprom, + !!(eeprom_val & 0x08), + !!(eeprom_val & 0x04), + !!(eeprom_val & 0x02)); + } else if (opmode == 0x40) { + /* Reset. */ + val = 0; + rtl8139_reset(s); + } + + s->Cfg9346 = val; +} + +static uint32_t +rtl8139_Cfg9346_read(RTL8139State *s) +{ + uint32_t ret = s->Cfg9346; + + uint32_t opmode = ret & 0xc0; + + if (opmode == 0x80) { + if (nmc93cxx_eeprom_read(s->eeprom)) + ret |= 0x01; + else + ret &= ~0x01; + } + + rtl8139_log("Cfg9346 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_Config0_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Config0 write val=0x%02x\n", val); + + if (!rtl8139_config_writable(s)) { + return; + } + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xf8, s->Config0); + + s->Config0 = val; +} + +static uint32_t +rtl8139_Config0_read(RTL8139State *s) +{ + uint32_t ret = s->Config0; + + rtl8139_log("Config0 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_Config1_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Config1 write val=0x%02x\n", val); + + if (!rtl8139_config_writable(s)) { + return; + } + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xC, s->Config1); + + s->Config1 = val; +} + +static uint32_t +rtl8139_Config1_read(RTL8139State *s) +{ + uint32_t ret = s->Config1; + + rtl8139_log("Config1 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_Config3_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Config3 write val=0x%02x\n", val); + + if (!rtl8139_config_writable(s)) { + return; + } + + /* mask unwritable bits */ + val = SET_MASKED(val, 0x8F, s->Config3); + + s->Config3 = val; +} + +static uint32_t +rtl8139_Config3_read(RTL8139State *s) +{ + uint32_t ret = s->Config3; + + rtl8139_log("Config3 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_Config4_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Config4 write val=0x%02x\n", val); + + if (!rtl8139_config_writable(s)) { + return; + } + + /* mask unwritable bits */ + val = SET_MASKED(val, 0x0a, s->Config4); + + s->Config4 = val; +} + +static uint32_t +rtl8139_Config4_read(RTL8139State *s) +{ + uint32_t ret = s->Config4; + + rtl8139_log("Config4 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_Config5_write(RTL8139State *s, uint32_t val) +{ + val &= 0xff; + + rtl8139_log("Config5 write val=0x%02x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0x80, s->Config5); + + s->Config5 = val; +} + +static uint32_t +rtl8139_Config5_read(RTL8139State *s) +{ + uint32_t ret = s->Config5; + + rtl8139_log("Config5 read val=0x%02x\n", ret); + + return ret; +} + +static void +rtl8139_TxConfig_write(RTL8139State *s, uint32_t val) +{ + if (!rtl8139_transmitter_enabled(s)) { + rtl8139_log("transmitter disabled; no TxConfig write val=0x%08x\n", val); + return; + } + + rtl8139_log("TxConfig write val=0x%08x\n", val); + + val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig); + + s->TxConfig = val; +} + +static void +rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val) +{ + rtl8139_log("RTL8139C TxConfig via write(b) val=0x%02x\n", val); + + uint32_t tc = s->TxConfig; + + tc &= 0xFFFFFF00; + tc |= (val & 0x000000FF); + rtl8139_TxConfig_write(s, tc); +} + +static uint32_t +rtl8139_TxConfig_read(RTL8139State *s) +{ + uint32_t ret = s->TxConfig; + + rtl8139_log("TxConfig read val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_RxConfig_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("RxConfig write val=0x%08x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xf0fc0040, s->RxConfig); + + s->RxConfig = val; + + /* reset buffer size and read/write pointers */ + rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3)); + + rtl8139_log("RxConfig write reset buffer size to %d\n", s->RxBufferSize); +} + +static uint32_t +rtl8139_RxConfig_read(RTL8139State *s) +{ + uint32_t ret = s->RxConfig; + + rtl8139_log("RxConfig read val=0x%08x\n", ret); + + return ret; +} + +void +rtl8139_network_rx_put(netcard_t *card, uint8_t *bufp, int len) +{ + (void) network_rx_put(card, bufp, len); +} + +static void +rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size, + UNUSED(int do_interrupt), const uint8_t *dot1q_buf) +{ + void (*network_func)(netcard_t *, uint8_t *, int) = (TxLoopBack == (s->TxConfig & TxLoopBack)) ? rtl8139_network_rx_put : network_tx; + if (!size) { + rtl8139_log("+++ empty ethernet frame\n"); + return; + } + + if (dot1q_buf && size >= ETH_ALEN * 2) { + network_func(s->nic, buf, ETH_ALEN * 2); + network_func(s->nic, (uint8_t *) dot1q_buf, VLAN_HLEN); + network_func(s->nic, buf + ETH_ALEN * 2, size - ETH_ALEN * 2); + return; + } + + network_func(s->nic, buf, size); + return; +} + +static int +rtl8139_transmit_one(RTL8139State *s, int descriptor) +{ + int txsize = s->TxStatus[descriptor] & 0x1fff; + uint8_t txbuffer[0x2000]; + + if (!rtl8139_transmitter_enabled(s)) { + rtl8139_log("+++ cannot transmit from descriptor %d: transmitter " + "disabled\n", descriptor); + return 0; + } + + if (s->TxStatus[descriptor] & TxHostOwns) { + rtl8139_log("+++ cannot transmit from descriptor %d: owned by host " + "(%08x)\n", descriptor, s->TxStatus[descriptor]); + return 0; + } + + rtl8139_log("+++ transmitting from descriptor %d\n", descriptor); + + rtl8139_log("+++ transmit reading %d bytes from host memory at 0x%08x\n", + txsize, s->TxAddr[descriptor]); + + dma_bm_read(s->TxAddr[descriptor], txbuffer, txsize, 1); + + /* Mark descriptor as transferred */ + s->TxStatus[descriptor] |= TxHostOwns; + s->TxStatus[descriptor] |= TxStatOK; + + rtl8139_transfer_frame(s, txbuffer, txsize, 0, NULL); + + rtl8139_log("+++ transmitted %d bytes from descriptor %d\n", txsize, + descriptor); + + /* update interrupt */ + s->IntrStatus |= TxOK; + rtl8139_update_irq(s); + + return 1; +} + +#define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off))) + +/* produces ones' complement sum of data */ +static uint16_t +ones_complement_sum(uint8_t *data, size_t len) +{ + uint32_t result = 0; + + for (; len > 1; data += 2, len -= 2) { + result += *(uint16_t *) data; + } + + /* add the remainder byte */ + if (len) { + uint8_t odd[2] = { *data, 0 }; + result += *(uint16_t *) odd; + } + + while (result >> 16) + result = (result & 0xffff) + (result >> 16); + + return result; +} + +static uint16_t +ip_checksum(void *data, size_t len) +{ + return ~ones_complement_sum((uint8_t *) data, len); +} + +/* TODO: Replace these with equivalents in 86Box if applicable. */ +struct ip_header { + uint8_t ip_ver_len; /* version and header length */ + uint8_t ip_tos; /* type of service */ + uint16_t ip_len; /* total length */ + uint16_t ip_id; /* identification */ + uint16_t ip_off; /* fragment offset field */ + uint8_t ip_ttl; /* time to live */ + uint8_t ip_p; /* protocol */ + uint16_t ip_sum; /* checksum */ + uint32_t ip_src, ip_dst; /* source and destination address */ +}; + +typedef struct tcp_header { + uint16_t th_sport; /* source port */ + uint16_t th_dport; /* destination port */ + uint32_t th_seq; /* sequence number */ + uint32_t th_ack; /* acknowledgment number */ + uint16_t th_offset_flags; /* data offset, reserved 6 bits, */ + /* TCP protocol flags */ + uint16_t th_win; /* window */ + uint16_t th_sum; /* checksum */ + uint16_t th_urp; /* urgent pointer */ +} tcp_header; + +typedef struct ip_pseudo_header { + uint32_t ip_src; + uint32_t ip_dst; + uint8_t zeros; + uint8_t ip_proto; + uint16_t ip_payload; +} ip_pseudo_header; + +typedef struct udp_header { + uint16_t uh_sport; /* source port */ + uint16_t uh_dport; /* destination port */ + uint16_t uh_ulen; /* udp length */ + uint16_t uh_sum; /* udp checksum */ +} udp_header; + +#define ETH_HLEN 14 +#define ETH_P_IP (0x0800) +#define IP_PROTO_TCP (6) +#define IP_PROTO_UDP (17) +#define IP_HEADER_VERSION_4 (4) +#define TH_PUSH 0x08 +#define TH_FIN 0x01 + +#define IP_HDR_GET_LEN(p) \ + ((*(uint8_t *) ((p + __builtin_offsetof(struct ip_header, ip_ver_len))) & 0x0F) << 2) + +#define IP_HEADER_VERSION(ip) \ + (((ip)->ip_ver_len >> 4) & 0xf) + +#define TCP_HEADER_DATA_OFFSET(tcp) \ + (((be16_to_cpu((tcp)->th_offset_flags) >> 12) & 0xf) << 2) + +static int +rtl8139_cplus_transmit_one(RTL8139State *s) +{ + if (!rtl8139_transmitter_enabled(s)) { + rtl8139_log("+++ C+ mode: transmitter disabled\n"); + return 0; + } + + if (!rtl8139_cp_transmitter_enabled(s)) { + rtl8139_log("+++ C+ mode: C+ transmitter disabled\n"); + return 0; + } + int descriptor = s->currCPlusTxDesc; + + uint32_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); + + /* Normal priority ring */ + cplus_tx_ring_desc += 16 * descriptor; + + rtl8139_log("+++ C+ mode reading TX descriptor %d from host memory at " + "%08x %08x = 0x%08X\n", descriptor, s->TxAddr[1], + s->TxAddr[0], cplus_tx_ring_desc); + + uint32_t val; + uint32_t txdw0; + uint32_t txdw1; + uint32_t txbufLO; + uint32_t txbufHI; + + dma_bm_read(cplus_tx_ring_desc, (uint8_t *) &val, 4, 4); + txdw0 = le32_to_cpu(val); + dma_bm_read(cplus_tx_ring_desc + 4, (uint8_t *) &val, 4, 4); + txdw1 = le32_to_cpu(val); + dma_bm_read(cplus_tx_ring_desc + 8, (uint8_t *) &val, 4, 4); + txbufLO = le32_to_cpu(val); + dma_bm_read(cplus_tx_ring_desc + 12, (uint8_t *) &val, 4, 4); + txbufHI = le32_to_cpu(val); + + rtl8139_log("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor, + txdw0, txdw1, txbufLO, txbufHI); + +/* w0 ownership flag */ +#define CP_TX_OWN (1 << 31) +/* w0 end of ring flag */ +#define CP_TX_EOR (1 << 30) +/* first segment of received packet flag */ +#define CP_TX_FS (1 << 29) +/* last segment of received packet flag */ +#define CP_TX_LS (1 << 28) +/* large send packet flag */ +#define CP_TX_LGSEN (1 << 27) +/* large send MSS mask, bits 16...26 */ +#define CP_TC_LGSEN_MSS_SHIFT 16 +#define CP_TC_LGSEN_MSS_MASK ((1 << 11) - 1) + +/* IP checksum offload flag */ +#define CP_TX_IPCS (1 << 18) +/* UDP checksum offload flag */ +#define CP_TX_UDPCS (1 << 17) +/* TCP checksum offload flag */ +#define CP_TX_TCPCS (1 << 16) + +/* w0 bits 0...15 : buffer size */ +#define CP_TX_BUFFER_SIZE (1 << 16) +#define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1) +/* w1 add tag flag */ +#define CP_TX_TAGC (1 << 17) +/* w1 bits 0...15 : VLAN tag (big endian) */ +#define CP_TX_VLAN_TAG_MASK ((1 << 16) - 1) +/* w2 low 32bit of Rx buffer ptr */ +/* w3 high 32bit of Rx buffer ptr */ + +/* set after transmission */ +/* FIFO underrun flag */ +#define CP_TX_STATUS_UNF (1 << 25) +/* transmit error summary flag, valid if set any of three below */ +#define CP_TX_STATUS_TES (1 << 23) +/* out-of-window collision flag */ +#define CP_TX_STATUS_OWC (1 << 22) +/* link failure flag */ +#define CP_TX_STATUS_LNKF (1 << 21) +/* excessive collisions flag */ +#define CP_TX_STATUS_EXC (1 << 20) + + if (!(txdw0 & CP_TX_OWN)) { + rtl8139_log("C+ Tx mode : descriptor %d is owned by host\n", descriptor); + return 0; + } + + rtl8139_log("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor); + + if (txdw0 & CP_TX_FS) { + rtl8139_log("+++ C+ Tx mode : descriptor %d is first segment " + "descriptor\n", descriptor); + + /* reset internal buffer offset */ + s->cplus_txbuffer_offset = 0; + } + + int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK; + uint32_t tx_addr = rtl8139_addr64(txbufLO, txbufHI); + + /* make sure we have enough space to assemble the packet */ + if (!s->cplus_txbuffer) { + s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE; + s->cplus_txbuffer = calloc(s->cplus_txbuffer_len, 1); + s->cplus_txbuffer_offset = 0; + + rtl8139_log("+++ C+ mode transmission buffer allocated space %d\n", + s->cplus_txbuffer_len); + } + + if (s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) { + /* The spec didn't tell the maximum size, stick to CP_TX_BUFFER_SIZE */ + txsize = s->cplus_txbuffer_len - s->cplus_txbuffer_offset; + rtl8139_log("+++ C+ mode transmission buffer overrun, truncated descriptor" + "length to %d\n", txsize); + } + + /* append more data to the packet */ + + rtl8139_log("+++ C+ mode transmit reading %d bytes from host memory at " + "%08X to offset %d\n", txsize, tx_addr, s->cplus_txbuffer_offset); + + dma_bm_read(tx_addr, + s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize, 1); + s->cplus_txbuffer_offset += txsize; + + /* seek to next Rx descriptor */ + if (txdw0 & CP_TX_EOR) { + s->currCPlusTxDesc = 0; + } else { + ++s->currCPlusTxDesc; + if (s->currCPlusTxDesc >= 64) + s->currCPlusTxDesc = 0; + } + + /* Build the Tx Status Descriptor */ + uint32_t tx_status = txdw0; + + /* transfer ownership to target */ + tx_status &= ~CP_TX_OWN; + + /* reset error indicator bits */ + tx_status &= ~CP_TX_STATUS_UNF; + tx_status &= ~CP_TX_STATUS_TES; + tx_status &= ~CP_TX_STATUS_OWC; + tx_status &= ~CP_TX_STATUS_LNKF; + tx_status &= ~CP_TX_STATUS_EXC; + + /* update ring data */ + val = cpu_to_le32(tx_status); + dma_bm_write(cplus_tx_ring_desc, (uint8_t *) &val, 4, 4); + + /* Now decide if descriptor being processed is holding the last segment of packet */ + if (txdw0 & CP_TX_LS) { + uint8_t dot1q_buffer_space[VLAN_HLEN]; + uint16_t *dot1q_buffer; + + rtl8139_log("+++ C+ Tx mode : descriptor %d is last segment descriptor\n", + descriptor); + + /* can transfer fully assembled packet */ + + uint8_t *saved_buffer = s->cplus_txbuffer; + int saved_size = s->cplus_txbuffer_offset; + int saved_buffer_len = s->cplus_txbuffer_len; + + /* create vlan tag */ + if (txdw1 & CP_TX_TAGC) { + /* the vlan tag is in BE byte order in the descriptor + * BE + le_to_cpu() + ~swap()~ = cpu */ + rtl8139_log("+++ C+ Tx mode : inserting vlan tag with " + "tci: %u\n", bswap16(txdw1 & CP_TX_VLAN_TAG_MASK)); + + dot1q_buffer = (uint16_t *) dot1q_buffer_space; + dot1q_buffer[0] = cpu_to_be16(0x8100); + /* BE + le_to_cpu() + ~cpu_to_le()~ = BE */ + dot1q_buffer[1] = cpu_to_le16(txdw1 & CP_TX_VLAN_TAG_MASK); + } else { + dot1q_buffer = NULL; + } + + /* reset the card space to protect from recursive call */ + s->cplus_txbuffer = NULL; + s->cplus_txbuffer_offset = 0; + s->cplus_txbuffer_len = 0; + + if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN)) { + rtl8139_log("+++ C+ mode offloaded task checksum\n"); + + /* Large enough for Ethernet and IP headers? */ + if (saved_size < ETH_HLEN + sizeof(struct ip_header)) { + goto skip_offload; + } + + /* ip packet header */ + struct ip_header *ip = NULL; + int hlen = 0; + uint8_t ip_protocol = 0; + uint16_t ip_data_len = 0; + + uint8_t *eth_payload_data = NULL; + size_t eth_payload_len = 0; + + int proto = be16_to_cpu(*(uint16_t *) (saved_buffer + 12)); + if (proto != ETH_P_IP) { + goto skip_offload; + } + + rtl8139_log("+++ C+ mode has IP packet\n"); + + /* Note on memory alignment: eth_payload_data is 16-bit aligned + * since saved_buffer is allocated with g_malloc() and ETH_HLEN is + * even. 32-bit accesses must use ldl/stl wrappers to avoid + * unaligned accesses. + */ + eth_payload_data = saved_buffer + ETH_HLEN; + eth_payload_len = saved_size - ETH_HLEN; + + ip = (struct ip_header *) eth_payload_data; + + if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { + rtl8139_log("+++ C+ mode packet has bad IP version %d " + "expected %d\n", IP_HEADER_VERSION(ip), + IP_HEADER_VERSION_4); + goto skip_offload; + } + + hlen = IP_HDR_GET_LEN(ip); + if (hlen < sizeof(struct ip_header) || hlen > eth_payload_len) { + goto skip_offload; + } + + ip_protocol = ip->ip_p; + + ip_data_len = be16_to_cpu(ip->ip_len); + if (ip_data_len < hlen || ip_data_len > eth_payload_len) { + goto skip_offload; + } + ip_data_len -= hlen; + + if (!(txdw0 & CP_TX_LGSEN) && (txdw0 & CP_TX_IPCS)) { + rtl8139_log("+++ C+ mode need IP checksum\n"); + + ip->ip_sum = 0; + ip->ip_sum = ip_checksum(ip, hlen); + rtl8139_log("+++ C+ mode IP header len=%d checksum=%04x\n", + hlen, ip->ip_sum); + } + + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) { + /* Large enough for the TCP header? */ + if (ip_data_len < sizeof(tcp_header)) { + goto skip_offload; + } + + int large_send_mss = (txdw0 >> CP_TC_LGSEN_MSS_SHIFT) & CP_TC_LGSEN_MSS_MASK; + if (large_send_mss == 0) { + goto skip_offload; + } + + rtl8139_log("+++ C+ mode offloaded task TSO IP data %d " + "frame data %d specified MSS=%d\n", + ip_data_len, saved_size - ETH_HLEN, large_send_mss); + + /* maximum IP header length is 60 bytes */ + uint8_t saved_ip_header[60]; + + /* save IP header template; data area is used in tcp checksum calculation */ + memcpy(saved_ip_header, eth_payload_data, hlen); + + /* a placeholder for checksum calculation routine in tcp case */ + uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +#if 0 + size_t data_to_checksum_len = eth_payload_len - hlen + 12; +#endif + + /* pointer to TCP header */ + tcp_header *p_tcp_hdr = (tcp_header *) (eth_payload_data + hlen); + + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + + /* Invalid TCP data offset? */ + if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { + goto skip_offload; + } + + int tcp_data_len = ip_data_len - tcp_hlen; + + rtl8139_log("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " + "data len %d\n", ip_data_len, tcp_hlen, tcp_data_len); + + /* note the cycle below overwrites IP header data, + but restores it from saved_ip_header before sending packet */ + + int is_last_frame = 0; + + for (int tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += large_send_mss) { + uint16_t chunk_size = large_send_mss; + + /* check if this is the last frame */ + if (tcp_send_offset + large_send_mss >= tcp_data_len) { + is_last_frame = 1; + chunk_size = tcp_data_len - tcp_send_offset; + } + +#if 0 + rtl8139_log("+++ C+ mode TSO TCP seqno %08x\n", + ldl_be_p(&p_tcp_hdr->th_seq)); +#endif + + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); + + rtl8139_log("+++ C+ mode TSO calculating TCP checksum for " + "packet with %d bytes data\n", tcp_hlen + chunk_size); + + if (tcp_send_offset) { + memcpy((uint8_t *) p_tcp_hdr + tcp_hlen, (uint8_t *) p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); + } + +#define TCP_FLAGS_ONLY(flags) ((flags) &0x3f) +#define TCP_HEADER_CLEAR_FLAGS(tcp, off) ((tcp)->th_offset_flags &= cpu_to_be16(~TCP_FLAGS_ONLY(off))) + /* keep PUSH and FIN flags only for the last frame */ + if (!is_last_frame) { + TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TH_PUSH | TH_FIN); + } + + /* recalculate TCP checksum */ + ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *) data_to_checksum; + p_tcpip_hdr->zeros = 0; + p_tcpip_hdr->ip_proto = IP_PROTO_TCP; + p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); + + p_tcp_hdr->th_sum = 0; + + int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); + rtl8139_log("+++ C+ mode TSO TCP checksum %04x\n", tcp_checksum); + + p_tcp_hdr->th_sum = tcp_checksum; + + /* restore IP header */ + memcpy(eth_payload_data, saved_ip_header, hlen); + + /* set IP data length and recalculate IP checksum */ + ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); + + /* increment IP id for subsequent frames */ + ip->ip_id = cpu_to_be16(tcp_send_offset / large_send_mss + be16_to_cpu(ip->ip_id)); + + ip->ip_sum = 0; + ip->ip_sum = ip_checksum(eth_payload_data, hlen); + rtl8139_log("+++ C+ mode TSO IP header len=%d checksum=%04x\n", + hlen, ip->ip_sum); + + int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; + rtl8139_log("+++ C+ mode TSO transferring packet size %d\n", + tso_send_size); + rtl8139_transfer_frame(s, saved_buffer, tso_send_size, + 0, (uint8_t *) dot1q_buffer); + + /* add transferred count to TCP sequence number */ +#if 0 + stl_be_p(&p_tcp_hdr->th_seq, + chunk_size + ldl_be_p(&p_tcp_hdr->th_seq)); +#endif + p_tcp_hdr->th_seq = bswap32(chunk_size + bswap32(p_tcp_hdr->th_seq)); + } + + /* Stop sending this frame */ + saved_size = 0; + } else if (!(txdw0 & CP_TX_LGSEN) && (txdw0 & (CP_TX_TCPCS | CP_TX_UDPCS))) { + rtl8139_log("+++ C+ mode need TCP or UDP checksum\n"); + + /* maximum IP header length is 60 bytes */ + uint8_t saved_ip_header[60]; + memcpy(saved_ip_header, eth_payload_data, hlen); + + uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +#if 0 + size_t data_to_checksum_len = eth_payload_len - hlen + 12; +#endif + + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); + + if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) { + rtl8139_log("+++ C+ mode calculating TCP checksum for " + "packet with %d bytes data\n", ip_data_len); + + ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *) data_to_checksum; + p_tcpip_hdr->zeros = 0; + p_tcpip_hdr->ip_proto = IP_PROTO_TCP; + p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); + + tcp_header *p_tcp_hdr = (tcp_header *) (data_to_checksum + 12); + + p_tcp_hdr->th_sum = 0; + + int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); + rtl8139_log("+++ C+ mode TCP checksum %04x\n", tcp_checksum); + + p_tcp_hdr->th_sum = tcp_checksum; + } else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) { + rtl8139_log("+++ C+ mode calculating UDP checksum for " + "packet with %d bytes data\n", ip_data_len); + + ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *) data_to_checksum; + p_udpip_hdr->zeros = 0; + p_udpip_hdr->ip_proto = IP_PROTO_UDP; + p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); + + udp_header *p_udp_hdr = (udp_header *) (data_to_checksum + 12); + + p_udp_hdr->uh_sum = 0; + + int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); + rtl8139_log("+++ C+ mode UDP checksum %04x\n", udp_checksum); + + p_udp_hdr->uh_sum = udp_checksum; + } + + /* restore IP header */ + memcpy(eth_payload_data, saved_ip_header, hlen); + } + } + +skip_offload: + /* update tally counter */ + ++s->tally_counters.TxOk; + + rtl8139_log("+++ C+ mode transmitting %d bytes packet\n", saved_size); + + rtl8139_transfer_frame(s, saved_buffer, saved_size, 1, + (uint8_t *) dot1q_buffer); + + /* restore card space if there was no recursion and reset offset */ + if (!s->cplus_txbuffer) { + s->cplus_txbuffer = saved_buffer; + s->cplus_txbuffer_len = saved_buffer_len; + s->cplus_txbuffer_offset = 0; + } else + free(saved_buffer); + } else { + rtl8139_log("+++ C+ mode transmission continue to next descriptor\n"); + } + + return 1; +} + +static void +rtl8139_cplus_transmit(RTL8139State *s) +{ + int txcount = 0; + + while (txcount < 64 && rtl8139_cplus_transmit_one(s)) { + ++txcount; + } + + /* Mark transfer completed */ + if (!txcount) { + rtl8139_log("C+ mode : transmitter queue stalled, current TxDesc = %d\n", + s->currCPlusTxDesc); + } else { + /* update interrupt status */ + s->IntrStatus |= TxOK; + rtl8139_update_irq(s); + } +} + +static void +rtl8139_transmit(RTL8139State *s) +{ + int descriptor = s->currTxDesc; + int txcount = 0; + + /*while*/ + if (rtl8139_transmit_one(s, descriptor)) { + ++s->currTxDesc; + s->currTxDesc %= 4; + ++txcount; + } + + /* Mark transfer completed */ + if (!txcount) { + rtl8139_log("transmitter queue stalled, current TxDesc = %d\n", + s->currTxDesc); + } +} + +static void +rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32_t val) +{ + int descriptor = txRegOffset / 4; + + /* handle C+ transmit mode register configuration */ + + if (s->cplus_enabled) { + rtl8139_log("RTL8139C+ DTCCR write offset=0x%x val=0x%08x " + "descriptor=%d\n", txRegOffset, val, descriptor); + + /* handle Dump Tally Counters command */ + s->TxStatus[descriptor] = val; + + if (descriptor == 0 && (val & 0x8)) { + uint32_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]); + + /* dump tally counters to specified memory location */ + RTL8139TallyCounters_dma_write(s, tc_addr); + + /* mark dump completed */ + s->TxStatus[0] &= ~0x8; + } + + return; + } + + rtl8139_log("TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", + txRegOffset, val, descriptor); + + /* mask only reserved bits */ + val &= ~0xff00c000; /* these bits are reset on write */ + val = SET_MASKED(val, 0x00c00000, s->TxStatus[descriptor]); + + s->TxStatus[descriptor] = val; + + /* attempt to start transmission */ + rtl8139_transmit(s); +} + +static uint32_t +rtl8139_TxStatus_TxAddr_read(UNUSED(RTL8139State *s), uint32_t regs[], + uint32_t base, uint8_t addr, + int size) +{ + uint32_t reg = (addr - base) / 4; + uint32_t offset = addr & 0x3; + uint32_t ret = 0; + + if (addr & (size - 1)) { + rtl8139_log("not implemented read for TxStatus/TxAddr " + "addr=0x%x size=0x%x\n", addr, size); + return ret; + } + + switch (size) { + case 1: /* fall through */ + case 2: /* fall through */ + case 4: + ret = (regs[reg] >> offset * 8) & (((uint64_t) 1 << (size * 8)) - 1); + rtl8139_log("TxStatus/TxAddr[%d] read addr=0x%x size=0x%x val=0x%08x\n", + reg, addr, size, ret); + break; + + default: + rtl8139_log("unsupported size 0x%x of TxStatus/TxAddr reading\n", size); + break; + } + + return ret; +} + +static uint16_t +rtl8139_TSAD_read(RTL8139State *s) +{ + uint16_t ret = 0; + + /* Simulate TSAD, it is read only anyway */ + + ret = ((s->TxStatus[3] & TxStatOK) ? TSAD_TOK3 : 0) + | ((s->TxStatus[2] & TxStatOK) ? TSAD_TOK2 : 0) + | ((s->TxStatus[1] & TxStatOK) ? TSAD_TOK1 : 0) + | ((s->TxStatus[0] & TxStatOK) ? TSAD_TOK0 : 0) + + | ((s->TxStatus[3] & TxUnderrun) ? TSAD_TUN3 : 0) + | ((s->TxStatus[2] & TxUnderrun) ? TSAD_TUN2 : 0) + | ((s->TxStatus[1] & TxUnderrun) ? TSAD_TUN1 : 0) + | ((s->TxStatus[0] & TxUnderrun) ? TSAD_TUN0 : 0) + + | ((s->TxStatus[3] & TxAborted) ? TSAD_TABT3 : 0) + | ((s->TxStatus[2] & TxAborted) ? TSAD_TABT2 : 0) + | ((s->TxStatus[1] & TxAborted) ? TSAD_TABT1 : 0) + | ((s->TxStatus[0] & TxAborted) ? TSAD_TABT0 : 0) + + | ((s->TxStatus[3] & TxHostOwns) ? TSAD_OWN3 : 0) + | ((s->TxStatus[2] & TxHostOwns) ? TSAD_OWN2 : 0) + | ((s->TxStatus[1] & TxHostOwns) ? TSAD_OWN1 : 0) + | ((s->TxStatus[0] & TxHostOwns) ? TSAD_OWN0 : 0); + + rtl8139_log("TSAD read val=0x%04x\n", ret); + + return ret; +} + +static uint16_t +rtl8139_CSCR_read(RTL8139State *s) +{ + static uint16_t old_ret = 0xffff; + uint16_t ret = s->CSCR | + ((net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) ? 0 : CSCR_Cable); + + if (old_ret != 0xffff) { + ret &= ~CSCR_Cable_Changed; + if ((ret ^ old_ret) & CSCR_Cable) + ret |= CSCR_Cable_Changed; + } + + old_ret = ret; + + rtl8139_log("CSCR read val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val) +{ + rtl8139_log("TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val); + + s->TxAddr[txAddrOffset / 4] = val; +} + +static uint32_t +rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset) +{ + uint32_t ret = s->TxAddr[txAddrOffset / 4]; + + rtl8139_log("TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret); + + return ret; +} + +static void +rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("RxBufPtr write val=0x%04x\n", val); + + /* this value is off by 16 */ + s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize); + + rtl8139_log(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); +} + +static uint32_t +rtl8139_RxBufPtr_read(RTL8139State *s) +{ + /* this value is off by 16 */ + uint32_t ret = s->RxBufPtr - 0x10; + + rtl8139_log("RxBufPtr read val=0x%04x\n", ret); + + return ret; +} + +static uint32_t +rtl8139_RxBufAddr_read(RTL8139State *s) +{ + /* this value is NOT off by 16 */ + uint32_t ret = s->RxBufAddr; + + rtl8139_log("RxBufAddr read val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_RxBuf_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("RxBuf write val=0x%08x\n", val); + + s->RxBuf = val; + + /* may need to reset rxring here */ +} + +static uint32_t +rtl8139_RxBuf_read(RTL8139State *s) +{ + uint32_t ret = s->RxBuf; + + rtl8139_log("RxBuf read val=0x%08x\n", ret); + + return ret; +} + +static void +rtl8139_IntrMask_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("IntrMask write(w) val=0x%04x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0x1e00, s->IntrMask); + + s->IntrMask = val; + + rtl8139_update_irq(s); +} + +static uint32_t +rtl8139_IntrMask_read(RTL8139State *s) +{ + uint32_t ret = s->IntrMask; + + rtl8139_log("IntrMask read(w) val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("IntrStatus write(w) val=0x%04x\n", val); + +#if 0 + + /* writing to ISR has no effect */ + + return; + +#else + uint16_t newStatus = s->IntrStatus & ~val; + + /* mask unwritable bits */ + newStatus = SET_MASKED(newStatus, 0x1e00, s->IntrStatus); + + /* writing 1 to interrupt status register bit clears it */ + s->IntrStatus = 0; + rtl8139_update_irq(s); + + s->IntrStatus = newStatus; + rtl8139_update_irq(s); + +#endif +} + +static uint32_t +rtl8139_IntrStatus_read(RTL8139State *s) +{ + uint32_t ret = s->IntrStatus; + + rtl8139_log("IntrStatus read(w) val=0x%04x\n", ret); + +#if 0 + + /* reading ISR clears all interrupts */ + s->IntrStatus = 0; + + rtl8139_update_irq(s); + +#endif + + return ret; +} + +static void +rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val) +{ + rtl8139_log("MultiIntr write(w) val=0x%04x\n", val); + + /* mask unwritable bits */ + val = SET_MASKED(val, 0xf000, s->MultiIntr); + + s->MultiIntr = val; +} + +static uint32_t +rtl8139_MultiIntr_read(RTL8139State *s) +{ + uint32_t ret = s->MultiIntr; + + rtl8139_log("MultiIntr read(w) val=0x%04x\n", ret); + + return ret; +} + +static void +rtl8139_io_writeb(uint32_t addr, uint8_t val, void *priv) +{ + RTL8139State *s = priv; + + addr &= 0xFF; + switch (addr) { + case MAC0 ... MAC0 + 4: + s->phys[addr - MAC0] = val; + break; + case MAC0 + 5: + s->phys[addr - MAC0] = val; + break; + case MAC0 + 6 ... MAC0 + 7: + /* reserved */ + break; + case MAR0 ... MAR0 + 7: + s->mult[addr - MAR0] = val; + break; + case ChipCmd: + rtl8139_ChipCmd_write(s, val); + break; + case Cfg9346: + rtl8139_Cfg9346_write(s, val); + break; + case TxConfig: /* windows driver sometimes writes using byte-lenth call */ + rtl8139_TxConfig_writeb(s, val); + break; + case Config0: + rtl8139_Config0_write(s, val); + break; + case Config1: + rtl8139_Config1_write(s, val); + break; + case Config3: + rtl8139_Config3_write(s, val); + break; + case Config4: + rtl8139_Config4_write(s, val); + break; + case Config5: + rtl8139_Config5_write(s, val); + break; + case MediaStatus: + /* ignore */ + rtl8139_log("not implemented write(b) to MediaStatus val=0x%02x\n", val); + break; + + case HltClk: + rtl8139_log("HltClk write val=0x%08x\n", val); + if (val == 'R') { + s->clock_enabled = 1; + } else if (val == 'H') { + s->clock_enabled = 0; + } + break; + + case TxThresh: + rtl8139_log("C+ TxThresh write(b) val=0x%02x\n", val); + s->TxThresh = val; + break; + + case TxPoll: + rtl8139_log("C+ TxPoll write(b) val=0x%02x\n", val); + if (val & (1 << 7)) { + rtl8139_log("C+ TxPoll high priority transmission (not " + "implemented)\n"); +#if 0 + rtl8139_cplus_transmit(s); +#endif + } + if (val & (1 << 6)) { + rtl8139_log("C+ TxPoll normal priority transmission\n"); + rtl8139_cplus_transmit(s); + } + + break; + + default: + rtl8139_log("not implemented write(b) addr=0x%x val=0x%02x\n", addr, val); + break; + } +} + +static void +rtl8139_io_writew(uint32_t addr, uint16_t val, void *priv) +{ + RTL8139State *s = priv; + + addr &= 0xFF; + switch (addr) { + case IntrMask: + rtl8139_IntrMask_write(s, val); + break; + + case IntrStatus: + rtl8139_IntrStatus_write(s, val); + break; + + case MultiIntr: + rtl8139_MultiIntr_write(s, val); + break; + + case RxBufPtr: + rtl8139_RxBufPtr_write(s, val); + break; + + case BasicModeCtrl: + rtl8139_BasicModeCtrl_write(s, val); + break; + case BasicModeStatus: + rtl8139_BasicModeStatus_write(s, val); + break; + case NWayAdvert: + rtl8139_log("NWayAdvert write(w) val=0x%04x\n", val); + s->NWayAdvert = val; + break; + case NWayLPAR: + rtl8139_log("forbidden NWayLPAR write(w) val=0x%04x\n", val); + break; + case NWayExpansion: + rtl8139_log("NWayExpansion write(w) val=0x%04x\n", val); + s->NWayExpansion = val; + break; + + case CpCmd: + rtl8139_CpCmd_write(s, val); + break; + + case IntrMitigate: + rtl8139_IntrMitigate_write(s, val); + break; + + default: + rtl8139_log("ioport write(w) addr=0x%x val=0x%04x via write(b)\n", + addr, val); + + rtl8139_io_writeb(addr, val & 0xff, priv); + rtl8139_io_writeb(addr + 1, (val >> 8) & 0xff, priv); + break; + } +} + +/* TODO: Implement timer. */ + +static void +rtl8139_io_writel(uint32_t addr, uint32_t val, void *priv) +{ + RTL8139State *s = priv; + + addr &= 0xFF; + switch (addr) { + case RxMissed: + rtl8139_log("RxMissed clearing on write\n"); + s->RxMissed = 0; + break; + + case TxConfig: + rtl8139_TxConfig_write(s, val); + break; + + case RxConfig: + rtl8139_RxConfig_write(s, val); + break; + + case TxStatus0 ... TxStatus0 + 4 * 4 - 1: + rtl8139_TxStatus_write(s, addr - TxStatus0, val); + break; + + case TxAddr0 ... TxAddr0 + 4 * 4 - 1: + rtl8139_TxAddr_write(s, addr - TxAddr0, val); + break; + + case RxBuf: + rtl8139_RxBuf_write(s, val); + break; + + case RxRingAddrLO: + rtl8139_log("C+ RxRing low bits write val=0x%08x\n", val); + s->RxRingAddrLO = val; + break; + + case RxRingAddrHI: + rtl8139_log("C+ RxRing high bits write val=0x%08x\n", val); + s->RxRingAddrHI = val; + break; + + case Timer: + rtl8139_log("TCTR Timer reset on write\n"); + s->TCTR = 0; +#if 0 + s->TCTR_base = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + rtl8139_set_next_tctr_time(s); +#endif + break; + + case FlashReg: + rtl8139_log("FlashReg TimerInt write val=0x%08x\n", val); + if (s->TimerInt != val) + s->TimerInt = val; + break; + + default: + rtl8139_log("ioport write(l) addr=0x%x val=0x%08x via write(b)\n", + addr, val); + rtl8139_io_writeb(addr, val & 0xff, priv); + rtl8139_io_writeb(addr + 1, (val >> 8) & 0xff, priv); + rtl8139_io_writeb(addr + 2, (val >> 16) & 0xff, priv); + rtl8139_io_writeb(addr + 3, (val >> 24) & 0xff, priv); + break; + } +} + +static uint8_t +rtl8139_io_readb(uint32_t addr, void *priv) +{ + RTL8139State *s = priv; + uint8_t ret; + + addr &= 0xFF; + switch (addr) { + case MAC0 ... MAC0 + 5: + ret = s->phys[addr - MAC0]; + break; + case MAC0 + 6 ... MAC0 + 7: + ret = 0; + break; + case MAR0 ... MAR0 + 7: + ret = s->mult[addr - MAR0]; + break; + case TxStatus0 ... TxStatus0 + 4 * 4 - 1: + ret = rtl8139_TxStatus_TxAddr_read(s, s->TxStatus, TxStatus0, + addr, 1); + break; + case ChipCmd: + ret = rtl8139_ChipCmd_read(s); + break; + case Cfg9346: + ret = rtl8139_Cfg9346_read(s); + break; + case Config0: + ret = rtl8139_Config0_read(s); + break; + case Config1: + ret = rtl8139_Config1_read(s); + break; + case Config3: + ret = rtl8139_Config3_read(s); + break; + case Config4: + ret = rtl8139_Config4_read(s); + break; + case Config5: + ret = rtl8139_Config5_read(s); + break; + + case MediaStatus: + /* The LinkDown bit of MediaStatus is inverse with link status */ + ret = 0xd0 | (~s->BasicModeStatus & 0x04); + rtl8139_log("MediaStatus read 0x%x\n", ret); + break; + + case HltClk: + ret = s->clock_enabled; + rtl8139_log("HltClk read 0x%x\n", ret); + break; + + case PCIRevisionID: + ret = RTL8139_PCI_REVID; + rtl8139_log("PCI Revision ID read 0x%x\n", ret); + break; + + case TxThresh: + ret = s->TxThresh; + rtl8139_log("C+ TxThresh read(b) val=0x%02x\n", ret); + break; + + case 0x43: /* Part of TxConfig register. Windows driver tries to read it */ + ret = s->TxConfig >> 24; + rtl8139_log("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret); + break; + + case CSCR: + ret = rtl8139_CSCR_read(s) & 0xff; + break; + case CSCR + 1: + ret = rtl8139_CSCR_read(s) >> 8; + break; + + default: + rtl8139_log("not implemented read(b) addr=0x%x\n", addr); + ret = 0; + break; + } + + return ret; +} + +static uint16_t +rtl8139_io_readw(uint32_t addr, void *priv) +{ + RTL8139State *s = priv; + uint16_t ret; + + addr &= 0xFF; + switch (addr) { + case TxAddr0 ... TxAddr0 + 4 * 4 - 1: + ret = rtl8139_TxStatus_TxAddr_read(s, s->TxAddr, TxAddr0, addr, 2); + break; + case IntrMask: + ret = rtl8139_IntrMask_read(s); + break; + + case IntrStatus: + ret = rtl8139_IntrStatus_read(s); + break; + + case MultiIntr: + ret = rtl8139_MultiIntr_read(s); + break; + + case RxBufPtr: + ret = rtl8139_RxBufPtr_read(s); + break; + + case RxBufAddr: + ret = rtl8139_RxBufAddr_read(s); + break; + + case BasicModeCtrl: + ret = rtl8139_BasicModeCtrl_read(s); + break; + case BasicModeStatus: + ret = rtl8139_BasicModeStatus_read(s); + break; + case NWayAdvert: + ret = s->NWayAdvert; + rtl8139_log("NWayAdvert read(w) val=0x%04x\n", ret); + break; + case NWayLPAR: + ret = s->NWayLPAR; + rtl8139_log("NWayLPAR read(w) val=0x%04x\n", ret); + break; + case NWayExpansion: + ret = s->NWayExpansion; + rtl8139_log("NWayExpansion read(w) val=0x%04x\n", ret); + break; + + case CpCmd: + ret = rtl8139_CpCmd_read(s); + break; + + case IntrMitigate: + ret = rtl8139_IntrMitigate_read(s); + break; + + case TxSummary: + ret = rtl8139_TSAD_read(s); + break; + + case CSCR: + ret = rtl8139_CSCR_read(s); + break; + + default: + rtl8139_log("ioport read(w) addr=0x%x via read(b)\n", addr); + + ret = rtl8139_io_readb(addr, priv); + ret |= rtl8139_io_readb(addr + 1, priv) << 8; + + rtl8139_log("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret); + break; + } + + return ret; +} + +static uint32_t +rtl8139_io_readl(uint32_t addr, void *priv) +{ + RTL8139State *s = priv; + uint32_t ret; + + addr &= 0xFF; + switch (addr) { + case RxMissed: + ret = s->RxMissed; + + rtl8139_log("RxMissed read val=0x%08x\n", ret); + break; + + case TxConfig: + ret = rtl8139_TxConfig_read(s); + break; + + case RxConfig: + ret = rtl8139_RxConfig_read(s); + break; + + case TxStatus0 ... TxStatus0 + 4 * 4 - 1: + ret = rtl8139_TxStatus_TxAddr_read(s, s->TxStatus, TxStatus0, + addr, 4); + break; + + case TxAddr0 ... TxAddr0 + 4 * 4 - 1: + ret = rtl8139_TxAddr_read(s, addr - TxAddr0); + break; + + case RxBuf: + ret = rtl8139_RxBuf_read(s); + break; + + case RxRingAddrLO: + ret = s->RxRingAddrLO; + rtl8139_log("C+ RxRing low bits read val=0x%08x\n", ret); + break; + + case RxRingAddrHI: + ret = s->RxRingAddrHI; + rtl8139_log("C+ RxRing high bits read val=0x%08x\n", ret); + break; + + case Timer: +#if 0 + ret = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->TCTR_base) / + PCI_PERIOD; +#endif + ret = s->TCTR; + rtl8139_log("TCTR Timer read val=0x%08x\n", ret); + break; + + case FlashReg: + ret = s->TimerInt; + rtl8139_log("FlashReg TimerInt read val=0x%08x\n", ret); + break; + + default: + rtl8139_log("ioport read(l) addr=0x%x via read(b)\n", addr); + + ret = rtl8139_io_readb(addr, priv); + ret |= rtl8139_io_readb(addr + 1, priv) << 8; + ret |= rtl8139_io_readb(addr + 2, priv) << 16; + ret |= rtl8139_io_readb(addr + 3, priv) << 24; + + rtl8139_log("read(l) addr=0x%x val=%08x\n", addr, ret); + break; + } + + return ret; +} + +static uint32_t +rtl8139_io_readl_ioport(uint16_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + ret = rtl8139_io_readl(addr, priv); + + rtl8139_log("[%04X:%08X] [RLI] %04X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static uint16_t +rtl8139_io_readw_ioport(uint16_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + ret = rtl8139_io_readw(addr, priv); + + rtl8139_log("[%04X:%08X] [RWI] %04X = %04X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static uint8_t +rtl8139_io_readb_ioport(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + + ret = rtl8139_io_readb(addr, priv); + + rtl8139_log("[%04X:%08X] [RBI] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static void +rtl8139_io_writel_ioport(uint16_t addr, uint32_t val, void *priv) +{ + rtl8139_log("[%04X:%08X] [WLI] %04X = %08X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writel(addr, val, priv); +} + +static void +rtl8139_io_writew_ioport(uint16_t addr, uint16_t val, void *priv) +{ + rtl8139_log("[%04X:%08X] [WWI] %04X = %04X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writew(addr, val, priv); +} + +static void +rtl8139_io_writeb_ioport(uint16_t addr, uint8_t val, void *priv) +{ + rtl8139_log("[%04X:%08X] [WBI] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writeb(addr, val, priv); +} + +static uint32_t +rtl8139_io_readl_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + uint32_t ret = 0xffffffff; + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readl(addr, priv); + + rtl8139_log("[%04X:%08X] [RLM] %08X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; + } + +static uint16_t +rtl8139_io_readw_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + uint16_t ret = 0xffff; + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readw(addr, priv); + + rtl8139_log("[%04X:%08X] [RWM] %08X = %04X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static uint8_t +rtl8139_io_readb_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + uint8_t ret = 0xff; + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readb(addr, priv); + + rtl8139_log("[%04X:%08X] [RBM] %08X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static void +rtl8139_io_writel_mem(uint32_t addr, uint32_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + rtl8139_log("[%04X:%08X] [WLM] %08X = %08X\n", CS, cpu_state.pc, addr, val); + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writel(addr, val, priv); +} + +static void +rtl8139_io_writew_mem(uint32_t addr, uint16_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + rtl8139_log("[%04X:%08X] [WWM] %08X = %04X\n", CS, cpu_state.pc, addr, val); + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writew(addr, val, priv); +} + +static void +rtl8139_io_writeb_mem(uint32_t addr, uint8_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + rtl8139_log("[%04X:%08X] [WBM] %08X = %02X\n", CS, cpu_state.pc, addr, val); + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writeb(addr, val, priv); +} + +static int +rtl8139_set_link_status(void *priv, uint32_t link_state) +{ + RTL8139State *s = (RTL8139State *) priv; + + if (link_state & NET_LINK_DOWN) { + s->BasicModeStatus &= ~0x04; + } else { + s->BasicModeStatus |= 0x04; + } + + s->IntrStatus |= RxUnderrun; + rtl8139_update_irq(s); + return 0; +} + +static void +rtl8139_timer(void *priv) +{ + RTL8139State *s = priv; + + timer_on_auto(&s->timer, 1000000.0 / ((double) cpu_pci_speed)); + + if (!s->clock_enabled) { + rtl8139_log(">>> timer: clock is not running\n"); + return; + } + + s->TCTR++; + + if (s->TCTR == s->TimerInt && s->TimerInt != 0) { + s->IntrStatus |= PCSTimeout; + rtl8139_update_irq(s); + } +} + +static uint8_t +rtl8139_pci_read(UNUSED(int func), int addr, void *priv) +{ + const RTL8139State *s = (RTL8139State *) priv; + + switch (addr) { + default: + return s->pci_conf[addr & 0xFF]; + case 0x00: + return 0xEC; + case 0x01: + return 0x10; + case 0x02: + return 0x39; + case 0x03: + return 0x81; + case 0x07: + return 0x02; + case 0x06: + return 0x80; + case 0x05: + return s->pci_conf[addr & 0xFF] & 1; + case 0x08: + return 0x20; + case 0x09: + return 0x0; + case 0x0a: + return 0x0; + case 0x0b: + return 0x2; + case 0x0d: + return s->pci_latency; + case 0x10: + return 1; + case 0x14: + return 0; + case 0x15: +#ifdef USE_256_BYTE_BAR + return s->pci_conf[addr & 0xFF]; +#else + return s->pci_conf[addr & 0xFF] & 0xf0; +#endif + case 0x2c: + return 0xEC; + case 0x2d: + return 0x10; + case 0x2e: + return 0x39; + case 0x2f: + return 0x81; + case 0x34: + return 0xdc; + case 0x3d: + return PCI_INTA; + } +} + +static void +rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + switch (addr) { + case 0x04: + mem_mapping_disable(&s->bar_mem); + io_removehandler((s->pci_conf[0x11] << 8), 256, + rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, + rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, + priv); + s->pci_conf[addr & 0xFF] = val; + if (val & PCI_COMMAND_IO) + io_sethandler((s->pci_conf[0x11] << 8), 256, + rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, + rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, + priv); + if ((val & PCI_COMMAND_MEM) && s->bar_mem.size) + mem_mapping_enable(&s->bar_mem); + break; + case 0x05: + s->pci_conf[addr & 0xFF] = val & 1; + break; + case 0x0c: + s->pci_conf[addr & 0xFF] = val; + break; + case 0x0d: + s->pci_latency = val; + break; + case 0x10: + case 0x11: + io_removehandler((s->pci_conf[0x11] << 8), 256, + rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, + rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, + priv); + s->pci_conf[addr & 0xFF] = val; + rtl8139_log("New I/O base: %04X\n", s->pci_conf[0x11] << 8); + if (s->pci_conf[0x4] & PCI_COMMAND_IO) + io_sethandler((s->pci_conf[0x11] << 8), 256, + rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, + rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, + priv); + break; +#ifndef USE_256_BYTE_BAR + case 0x14: +#endif + case 0x15: + case 0x16: + case 0x17: + s->pci_conf[addr & 0xFF] = val; + s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24); +#ifndef USE_256_BYTE_BAR + s->mem_base &= 0xfffff000; +#endif + rtl8139_log("New memory base: %08X\n", s->mem_base); + if (s->pci_conf[0x4] & PCI_COMMAND_MEM) +#ifdef USE_256_BYTE_BAR + mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | + (s->pci_conf[0x17] << 24), 256); +#else + mem_mapping_set_addr(&s->bar_mem, ((s->pci_conf[0x15] & 0xf0) << 8) | + (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 4096); +#endif + break; + case 0x3c: + s->pci_conf[addr & 0xFF] = val; + break; + } +} + +static void * +nic_init(const device_t *info) +{ + RTL8139State *s = calloc(1, sizeof(RTL8139State)); + nmc93cxx_eeprom_params_t params; + char eeprom_filename[1024] = { 0 }; + char filename[1024] = { 0 }; + uint8_t *mac_bytes; + uint16_t *eep_data; + uint32_t mac; + + mem_mapping_add(&s->bar_mem, 0, 0, + rtl8139_io_readb_mem, rtl8139_io_readw_mem, rtl8139_io_readl_mem, + rtl8139_io_writeb_mem, rtl8139_io_writew_mem, rtl8139_io_writel_mem, + NULL, MEM_MAPPING_EXTERNAL, s); + pci_add_card(PCI_ADD_NORMAL, rtl8139_pci_read, rtl8139_pci_write, s, &s->pci_slot); + s->inst = device_get_instance(); + + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_rtl8139c_plus_%d.nvr", s->inst); + + eep_data = (uint16_t *) s->eeprom_data; + + /* prepare eeprom */ + eep_data[0] = 0x8129; + + /* PCI vendor and device ID should be mirrored here */ + eep_data[1] = 0x10EC; + eep_data[2] = 0x8139; + + /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ +#ifdef USE_REALTEK_OID + eep_data[7] = 0xe000; + eep_data[8] = 0x124c; +#else + eep_data[7] = 0x1400; + eep_data[8] = 0x122a; +#endif + eep_data[9] = 0x1413; + + mac_bytes = (uint8_t *) &(eep_data[7]); + + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + mac_bytes[3] = random_generate(); + mac_bytes[4] = random_generate(); + mac_bytes[5] = random_generate(); + mac = (((int) mac_bytes[3]) << 16); + mac |= (((int) mac_bytes[4]) << 8); + mac |= ((int) mac_bytes[5]); + device_set_config_mac("mac", mac); + } else { + mac_bytes[3] = (mac >> 16) & 0xff; + mac_bytes[4] = (mac >> 8) & 0xff; + mac_bytes[5] = (mac & 0xff); + } + + 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.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + 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); + timer_on_auto(&s->timer, 1000000.0 / cpu_pci_speed); + + s->cplus_txbuffer = NULL; + s->cplus_txbuffer_len = 0; + s->cplus_txbuffer_offset = 0; + + return s; +} + +static void +nic_close(void *priv) +{ + free(priv); +} + +// clang-format off +static const device_config_t rtl8139c_config[] = { + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t rtl8139c_plus_device = { + .name = "Realtek RTL8139C+", + .internal_name = "rtl8139c+", + .flags = DEVICE_PCI, + .local = 0, + .init = nic_init, + .close = nic_close, + .reset = rtl8139_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = rtl8139c_config +}; diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 9e979c380e..6aff76a909 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -58,7 +58,7 @@ enum { NET_EVENT_MAX }; -typedef struct { +typedef struct net_slirp_t { Slirp *slirp; uint8_t mac_addr[6]; netcard_t *card; /* netcard attached to us */ @@ -68,9 +68,10 @@ typedef struct { netpkt_t pkt; netpkt_t pkt_tx_v[SLIRP_PKT_BATCH]; #ifdef _WIN32 - HANDLE sock_event; + HANDLE sock_event; #else - uint32_t pfd_len, pfd_size; + uint32_t pfd_len; + uint32_t pfd_size; struct pollfd *pfd; #endif } net_slirp_t; @@ -94,19 +95,19 @@ slirp_log(const char *fmt, ...) #endif static void -net_slirp_guest_error(const char *msg, void *opaque) +net_slirp_guest_error(UNUSED(const char *msg), UNUSED(void *opaque)) { slirp_log("SLiRP: guest_error(): %s\n", msg); } static int64_t -net_slirp_clock_get_ns(void *opaque) +net_slirp_clock_get_ns(UNUSED(void *opaque)) { return (int64_t) ((double) tsc / cpuclock * 1000000000.0); } static void * -net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque) +net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, UNUSED(void *opaque)) { pc_timer_t *timer = malloc(sizeof(pc_timer_t)); timer_add(timer, cb, cb_opaque, 0); @@ -114,14 +115,14 @@ net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, void *opaque) } static void -net_slirp_timer_free(void *timer, void *opaque) +net_slirp_timer_free(void *timer, UNUSED(void *opaque)) { timer_stop(timer); free(timer); } static void -net_slirp_timer_mod(void *timer, int64_t expire_timer, void *opaque) +net_slirp_timer_mod(void *timer, int64_t expire_timer, UNUSED(void *opaque)) { timer_on_auto(timer, expire_timer * 1000); } @@ -384,7 +385,7 @@ static int slirp_card_num = 2; /* Initialize SLiRP for use. */ void * -net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char *netdrv_errbuf) +net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { slirp_log("SLiRP: initializing...\n"); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); @@ -493,15 +494,3 @@ const netdrv_t net_slirp_drv = { &net_slirp_init, &net_slirp_close }; - -/* Stubs to stand in for the parts of libslirp we skip compiling. */ -void ncsi_input(void *slirp, const uint8_t *pkt, int pkt_len) {} -void ip6_init(void *slirp) {} -void in6_compute_ethaddr(struct in6_addr ip, uint8_t *eth) {} -bool in6_equal(const void *a, const void *b) { return 0; } -const struct in6_addr in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; -const struct in6_addr in6addr_loopback = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }; -void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr, - uint8_t ethaddr[6]) {} /* IPv6 */ -bool ndp_table_search(void *slirp, struct in6_addr ip_addr, uint8_t *out_ethaddr) { return 0; } -void tftp_input(void *srcsas, void *m) {} diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c new file mode 100644 index 0000000000..ffc342e81e --- /dev/null +++ b/src/network/net_tulip.c @@ -0,0 +1,1733 @@ +/* + * 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. + * + * Emulation of DECchip "Tulip" 21143 NIC. + * + * Authors: Sven Schnelle, + * Cacodemon345, + * + * Copyright 2019-2023 Sven Schnelle. + * Copyright 2023 Cacodemon345. + */ +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/random.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/dma.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/network.h> +#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/bswap.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + +#define ROM_PATH_DEC21140 "roms/network/dec21140/BIOS13502.BIN" + +#define CSR(_x) ((_x) << 3) + +#define BIT(x) (1 << x) + +#define CSR0_SWR BIT(0) +#define CSR0_BAR BIT(1) +#define CSR0_DSL_SHIFT 2 +#define CSR0_DSL_MASK 0x1f +#define CSR0_BLE BIT(7) +#define CSR0_PBL_SHIFT 8 +#define CSR0_PBL_MASK 0x3f +#define CSR0_CAC_SHIFT 14 +#define CSR0_CAC_MASK 0x3 +#define CSR0_DAS 0x10000 +#define CSR0_TAP_SHIFT 17 +#define CSR0_TAP_MASK 0x7 +#define CSR0_DBO 0x100000 +#define CSR1_TPD 0x01 +#define CSR0_RLE BIT(23) +#define CSR0_WIE BIT(24) + +#define CSR2_RPD 0x01 + +#define CSR5_TI BIT(0) +#define CSR5_TPS BIT(1) +#define CSR5_TU BIT(2) +#define CSR5_TJT BIT(3) +#define CSR5_LNP_ANC BIT(4) +#define CSR5_UNF BIT(5) +#define CSR5_RI BIT(6) +#define CSR5_RU BIT(7) +#define CSR5_RPS BIT(8) +#define CSR5_RWT BIT(9) +#define CSR5_ETI BIT(10) +#define CSR5_GTE BIT(11) +#define CSR5_LNF BIT(12) +#define CSR5_FBE BIT(13) +#define CSR5_ERI BIT(14) +#define CSR5_AIS BIT(15) +#define CSR5_NIS BIT(16) +#define CSR5_RS_SHIFT 17 +#define CSR5_RS_MASK 7 +#define CSR5_TS_SHIFT 20 +#define CSR5_TS_MASK 7 + +#define CSR5_TS_STOPPED 0 +#define CSR5_TS_RUNNING_FETCH 1 +#define CSR5_TS_RUNNING_WAIT_EOT 2 +#define CSR5_TS_RUNNING_READ_BUF 3 +#define CSR5_TS_RUNNING_SETUP 5 +#define CSR5_TS_SUSPENDED 6 +#define CSR5_TS_RUNNING_CLOSE 7 + +#define CSR5_RS_STOPPED 0 +#define CSR5_RS_RUNNING_FETCH 1 +#define CSR5_RS_RUNNING_CHECK_EOR 2 +#define CSR5_RS_RUNNING_WAIT_RECEIVE 3 +#define CSR5_RS_SUSPENDED 4 +#define CSR5_RS_RUNNING_CLOSE 5 +#define CSR5_RS_RUNNING_FLUSH 6 +#define CSR5_RS_RUNNING_QUEUE 7 + +#define CSR5_EB_SHIFT 23 +#define CSR5_EB_MASK 7 + +#define CSR5_GPI BIT(26) +#define CSR5_LC BIT(27) + +#define CSR6_HP BIT(0) +#define CSR6_SR BIT(1) +#define CSR6_HO BIT(2) +#define CSR6_PB BIT(3) +#define CSR6_IF BIT(4) +#define CSR6_SB BIT(5) +#define CSR6_PR BIT(6) +#define CSR6_PM BIT(7) +#define CSR6_FKD BIT(8) +#define CSR6_FD BIT(9) + +#define CSR6_OM_SHIFT 10 +#define CSR6_OM_MASK 3 +#define CSR6_OM_NORMAL 0 +#define CSR6_OM_INT_LOOPBACK 1 +#define CSR6_OM_EXT_LOOPBACK 2 + +#define CSR6_FC BIT(12) +#define CSR6_ST BIT(13) + +#define CSR6_TR_SHIFT 14 +#define CSR6_TR_MASK 3 +#define CSR6_TR_72 0 +#define CSR6_TR_96 1 +#define CSR6_TR_128 2 +#define CSR6_TR_160 3 + +#define CSR6_CA BIT(17) +#define CSR6_RA BIT(30) +#define CSR6_SC BIT(31) + +#define CSR7_TIM BIT(0) +#define CSR7_TSM BIT(1) +#define CSR7_TUM BIT(2) +#define CSR7_TJM BIT(3) +#define CSR7_LPM BIT(4) +#define CSR7_UNM BIT(5) +#define CSR7_RIM BIT(6) +#define CSR7_RUM BIT(7) +#define CSR7_RSM BIT(8) +#define CSR7_RWM BIT(9) +#define CSR7_TMM BIT(11) +#define CSR7_LFM BIT(12) +#define CSR7_SEM BIT(13) +#define CSR7_ERM BIT(14) +#define CSR7_AIM BIT(15) +#define CSR7_NIM BIT(16) + +#define CSR8_MISSED_FRAME_OVL BIT(16) +#define CSR8_MISSED_FRAME_CNT_MASK 0xffff + +#define CSR9_DATA_MASK 0xff +#define CSR9_SR_CS BIT(0) +#define CSR9_SR_SK BIT(1) +#define CSR9_SR_DI BIT(2) +#define CSR9_SR_DO BIT(3) +#define CSR9_REG BIT(10) +#define CSR9_SR BIT(11) +#define CSR9_BR BIT(12) +#define CSR9_WR BIT(13) +#define CSR9_RD BIT(14) +#define CSR9_MOD BIT(15) +#define CSR9_MDC BIT(16) +#define CSR9_MDO BIT(17) +#define CSR9_MII BIT(18) +#define CSR9_MDI BIT(19) + +#define CSR11_CON BIT(16) +#define CSR11_TIMER_MASK 0xffff + +#define CSR12_MRA BIT(0) +#define CSR12_LS100 BIT(1) +#define CSR12_LS10 BIT(2) +#define CSR12_APS BIT(3) +#define CSR12_ARA BIT(8) +#define CSR12_TRA BIT(9) +#define CSR12_NSN BIT(10) +#define CSR12_TRF BIT(11) +#define CSR12_ANS_SHIFT 12 +#define CSR12_ANS_MASK 7 +#define CSR12_LPN BIT(15) +#define CSR12_LPC_SHIFT 16 +#define CSR12_LPC_MASK 0xffff + +#define CSR13_SRL BIT(0) +#define CSR13_CAC BIT(2) +#define CSR13_AUI BIT(3) +#define CSR13_SDM_SHIFT 4 +#define CSR13_SDM_MASK 0xfff + +#define CSR14_ECEN BIT(0) +#define CSR14_LBK BIT(1) +#define CSR14_DREN BIT(2) +#define CSR14_LSE BIT(3) +#define CSR14_CPEN_SHIFT 4 +#define CSR14_CPEN_MASK 3 +#define CSR14_MBO BIT(6) +#define CSR14_ANE BIT(7) +#define CSR14_RSQ BIT(8) +#define CSR14_CSQ BIT(9) +#define CSR14_CLD BIT(10) +#define CSR14_SQE BIT(11) +#define CSR14_LTE BIT(12) +#define CSR14_APE BIT(13) +#define CSR14_SPP BIT(14) +#define CSR14_TAS BIT(15) + +#define CSR15_JBD BIT(0) +#define CSR15_HUJ BIT(1) +#define CSR15_JCK BIT(2) +#define CSR15_ABM BIT(3) +#define CSR15_RWD BIT(4) +#define CSR15_RWR BIT(5) +#define CSR15_LE1 BIT(6) +#define CSR15_LV1 BIT(7) +#define CSR15_TSCK BIT(8) +#define CSR15_FUSQ BIT(9) +#define CSR15_FLF BIT(10) +#define CSR15_LSD BIT(11) +#define CSR15_DPST BIT(12) +#define CSR15_FRL BIT(13) +#define CSR15_LE2 BIT(14) +#define CSR15_LV2 BIT(15) + +#define RDES0_OF BIT(0) +#define RDES0_CE BIT(1) +#define RDES0_DB BIT(2) +#define RDES0_RJ BIT(4) +#define RDES0_FT BIT(5) +#define RDES0_CS BIT(6) +#define RDES0_TL BIT(7) +#define RDES0_LS BIT(8) +#define RDES0_FS BIT(9) +#define RDES0_MF BIT(10) +#define RDES0_RF BIT(11) +#define RDES0_DT_SHIFT 12 +#define RDES0_DT_MASK 3 +#define RDES0_DE BIT(14) +#define RDES0_ES BIT(15) +#define RDES0_FL_SHIFT 16 +#define RDES0_FL_MASK 0x3fff +#define RDES0_FF BIT(30) +#define RDES0_OWN BIT(31) + +#define RDES1_BUF1_SIZE_SHIFT 0 +#define RDES1_BUF1_SIZE_MASK 0x7ff + +#define RDES1_BUF2_SIZE_SHIFT 11 +#define RDES1_BUF2_SIZE_MASK 0x7ff +#define RDES1_RCH BIT(24) +#define RDES1_RER BIT(25) + +#define TDES0_DE BIT(0) +#define TDES0_UF BIT(1) +#define TDES0_LF BIT(2) +#define TDES0_CC_SHIFT 3 +#define TDES0_CC_MASK 0xf +#define TDES0_HF BIT(7) +#define TDES0_EC BIT(8) +#define TDES0_LC BIT(9) +#define TDES0_NC BIT(10) +#define TDES0_LO BIT(11) +#define TDES0_TO BIT(14) +#define TDES0_ES BIT(15) +#define TDES0_OWN BIT(31) + +#define TDES1_BUF1_SIZE_SHIFT 0 +#define TDES1_BUF1_SIZE_MASK 0x7ff + +#define TDES1_BUF2_SIZE_SHIFT 11 +#define TDES1_BUF2_SIZE_MASK 0x7ff + +#define TDES1_FT0 BIT(22) +#define TDES1_DPD BIT(23) +#define TDES1_TCH BIT(24) +#define TDES1_TER BIT(25) +#define TDES1_AC BIT(26) +#define TDES1_SET BIT(27) +#define TDES1_FT1 BIT(28) +#define TDES1_FS BIT(29) +#define TDES1_LS BIT(30) +#define TDES1_IC BIT(31) + +#define ETH_ALEN 6 + +static bar_t tulip_pci_bar[3]; + +struct tulip_descriptor { + uint32_t status; + uint32_t control; + uint32_t buf_addr1; + uint32_t buf_addr2; +}; + +struct TULIPState { + uint8_t pci_slot; + uint8_t irq_state; + int PCIBase; + int MMIOBase; + const device_t *device_info; + uint16_t subsys_id; + uint16_t subsys_ven_id; + mem_mapping_t memory; + rom_t bios_rom; + netcard_t *nic; + nmc93cxx_eeprom_t *eeprom; + uint32_t csr[16]; + uint8_t pci_conf[256]; + uint16_t mii_regs[32]; + uint8_t eeprom_data[128]; + + /* state for MII */ + uint32_t old_csr9; + uint32_t mii_word; + uint32_t mii_bitcnt; + + /* 21040 ROM read address. */ + uint8_t rom_read_addr; + + uint32_t current_rx_desc; + uint32_t current_tx_desc; + + uint8_t rx_frame[2048]; + uint8_t tx_frame[2048]; + uint16_t tx_frame_len; + uint16_t rx_frame_len; + uint16_t rx_frame_size; + + uint32_t rx_status; + uint32_t bios_addr; + uint8_t filter[16][6]; + int has_bios; +}; + +typedef struct TULIPState TULIPState; + +static void +tulip_desc_read(TULIPState *s, uint32_t p, + struct tulip_descriptor *desc) +{ + desc->status = mem_readl_phys(p); + desc->control = mem_readl_phys(p + 4); + desc->buf_addr1 = mem_readl_phys(p + 8); + desc->buf_addr2 = mem_readl_phys(p + 12); + + if (s->csr[0] & CSR0_DBO) { + bswap32s(&desc->status); + bswap32s(&desc->control); + bswap32s(&desc->buf_addr1); + bswap32s(&desc->buf_addr2); + } +} + +static void +tulip_desc_write(TULIPState *s, uint32_t p, + struct tulip_descriptor *desc) +{ + if (s->csr[0] & CSR0_DBO) { + mem_writel_phys(p, bswap32(desc->status)); + mem_writel_phys(p + 4, bswap32(desc->control)); + mem_writel_phys(p + 8, bswap32(desc->buf_addr1)); + mem_writel_phys(p + 12, bswap32(desc->buf_addr2)); + } else { + mem_writel_phys(p, desc->status); + mem_writel_phys(p + 4, desc->control); + mem_writel_phys(p + 8, desc->buf_addr1); + mem_writel_phys(p + 12, desc->buf_addr2); + } +} + +static void +tulip_update_int(TULIPState *s) +{ + uint32_t ie = s->csr[5] & s->csr[7]; + bool assert = false; + + s->csr[5] &= ~(CSR5_AIS | CSR5_NIS); + + if (ie & (CSR5_TI | CSR5_TU | CSR5_RI | CSR5_GTE | CSR5_ERI)) { + s->csr[5] |= CSR5_NIS; + } + + if (ie & (CSR5_LC | CSR5_GPI | CSR5_FBE | CSR5_LNF | CSR5_ETI | CSR5_RWT | CSR5_RPS | CSR5_RU | CSR5_UNF | CSR5_LNP_ANC | CSR5_TJT | CSR5_TPS)) { + s->csr[5] |= CSR5_AIS; + } + + assert = s->csr[5] & s->csr[7] & (CSR5_AIS | CSR5_NIS); + if (!assert) + pci_clear_irq(s->pci_slot, PCI_INTA, &s->irq_state); + else + pci_set_irq(s->pci_slot, PCI_INTA, &s->irq_state); +} + +static bool +tulip_rx_stopped(TULIPState *s) +{ + return ((s->csr[5] >> CSR5_RS_SHIFT) & CSR5_RS_MASK) == CSR5_RS_STOPPED; +} + +static void +tulip_next_rx_descriptor(TULIPState *s, + struct tulip_descriptor *desc) +{ + if (desc->control & RDES1_RER) { + s->current_rx_desc = s->csr[3]; + } else if (desc->control & RDES1_RCH) { + s->current_rx_desc = desc->buf_addr2; + } else { + s->current_rx_desc += sizeof(struct tulip_descriptor) + (((s->csr[0] >> CSR0_DSL_SHIFT) & CSR0_DSL_MASK) << 2); + } + s->current_rx_desc &= ~3ULL; +} + +static void +tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc) +{ + int len1 = (desc->control >> RDES1_BUF1_SIZE_SHIFT) & RDES1_BUF1_SIZE_MASK; + int len2 = (desc->control >> RDES1_BUF2_SIZE_SHIFT) & RDES1_BUF2_SIZE_MASK; + int len; + + if (s->rx_frame_len && len1) { + if (s->rx_frame_len > len1) { + len = len1; + } else { + len = s->rx_frame_len; + } + + dma_bm_write(desc->buf_addr1, s->rx_frame + (s->rx_frame_size - s->rx_frame_len), len, 4); + s->rx_frame_len -= len; + } + + if (s->rx_frame_len && len2) { + if (s->rx_frame_len > len2) { + len = len2; + } else { + len = s->rx_frame_len; + } + + dma_bm_write(desc->buf_addr2, s->rx_frame + (s->rx_frame_size - s->rx_frame_len), len, 4); + s->rx_frame_len -= len; + } +} + +static bool +tulip_filter_address(TULIPState *s, const uint8_t *addr) +{ + static const char broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + bool ret = false; + + for (uint8_t i = 0; i < 16 && ret == false; i++) { + if (!memcmp(&s->filter[i], addr, ETH_ALEN)) { + ret = true; + } + } + + if (!memcmp(addr, broadcast, ETH_ALEN)) { + return true; + } + + if (s->csr[6] & (CSR6_PR | CSR6_RA)) { + /* Promiscuous mode enabled */ + s->rx_status |= RDES0_FF; + return true; + } + + if ((s->csr[6] & CSR6_PM) && (addr[0] & 1)) { + /* Pass all Multicast enabled */ + s->rx_status |= RDES0_MF; + return true; + } + + if (s->csr[6] & CSR6_IF) { + ret ^= true; + } + return ret; +} + +static int +tulip_receive(void *priv, uint8_t *buf, int size) +{ + struct tulip_descriptor desc; + TULIPState *s = (TULIPState *) priv; + + + if (size < 14 || size > sizeof(s->rx_frame) - 4 + || s->rx_frame_len || tulip_rx_stopped(s)) + return 0; + + if (!tulip_filter_address(s, buf)) { + //pclog("Not a filter address.\n"); + return 1; + } + + //pclog("Size = %d, FrameLen = %d, Buffer[%02x:%02x:%02x:%02x:%02x:%02x].\n", size, s->rx_frame_len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + do { + tulip_desc_read(s, s->current_rx_desc, &desc); + + if (!(desc.status & RDES0_OWN)) { + s->csr[5] |= CSR5_RU; + tulip_update_int(s); + return s->rx_frame_size - s->rx_frame_len; + } + desc.status = 0; + + if (!s->rx_frame_len) { + s->rx_frame_size = size + 4; + s->rx_status = RDES0_LS | ((s->rx_frame_size & RDES0_FL_MASK) << RDES0_FL_SHIFT); + desc.status |= RDES0_FS; + memcpy(s->rx_frame, buf, size); + s->rx_frame_len = s->rx_frame_size; + } + + tulip_copy_rx_bytes(s, &desc); + + if (!s->rx_frame_len) { + desc.status |= s->rx_status; + s->csr[5] |= CSR5_RI; + tulip_update_int(s); + } + tulip_desc_write(s, s->current_rx_desc, &desc); + tulip_next_rx_descriptor(s, &desc); + } while (s->rx_frame_len); + + return 1; +} + +static void +tulip_update_rs(TULIPState *s, int state) +{ + s->csr[5] &= ~(CSR5_RS_MASK << CSR5_RS_SHIFT); + s->csr[5] |= (state & CSR5_RS_MASK) << CSR5_RS_SHIFT; +} + +static const uint16_t tulip_mdi_default[] = { + /* MDI Registers 0 - 6, 7 */ + 0x3100, + 0xf02c, + 0x7810, + 0x0000, + 0x0501, + 0x4181, + 0x0000, + 0x0000, + /* MDI Registers 8 - 15 */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x3800, + 0x0000, + /* MDI Registers 16 - 31 */ + 0x0003, + 0x0600, + 0x0001, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + +/* Readonly mask for MDI (PHY) registers */ +extern uint16_t l80225_mii_readw(uint16_t* regs, uint16_t addr); +extern void l80225_mii_writew(uint16_t* regs, uint16_t addr, uint16_t val); + +static uint16_t +tulip_mii_read(TULIPState *s, int phy, int reg) +{ + uint16_t ret = 0; + if (phy == 1) { + ret = l80225_mii_readw(s->mii_regs, reg); + } + //pclog("MII read phy = %02x, regs = %x, reg = %x, ret = %04x.\n", phy, s->mii_regs, reg, ret); + return ret; +} + +static void +tulip_mii_write(TULIPState *s, int phy, int reg, uint16_t data) +{ + if (phy != 1) { + return; + } + + return l80225_mii_writew(s->mii_regs, reg, data); +} + +static void +tulip_mii(TULIPState *s) +{ + uint32_t changed = s->old_csr9 ^ s->csr[9]; + uint16_t data; + int op; + int phy; + int reg; + + if (!(changed & CSR9_MDC)) { + //pclog("No Change.\n"); + return; + } + + if (!(s->csr[9] & CSR9_MDC)) { + //pclog("No Change to MDC.\n"); + return; + } + + s->mii_bitcnt++; + s->mii_word <<= 1; + + if ((s->csr[9] & CSR9_MDO) && (s->mii_bitcnt < 16 || !(s->csr[9] & CSR9_MII))) { + /* write op or address bits */ + s->mii_word |= 1; + //pclog("WriteOp.\n"); + } + + if ((s->mii_bitcnt >= 16) && (s->csr[9] & CSR9_MII)) { + if (s->mii_word & 0x8000) { + s->csr[9] |= CSR9_MDI; + //pclog("CSR9 MDI set.\n"); + } else { + s->csr[9] &= ~CSR9_MDI; + //pclog("CSR9 MDI cleared.\n"); + } + } + + if (s->mii_word == 0xffffffff) { + s->mii_bitcnt = 0; + //pclog("BitCnt = 0.\n"); + } else if (s->mii_bitcnt == 16) { + op = (s->mii_word >> 12) & 0x0f; + phy = (s->mii_word >> 7) & 0x1f; + reg = (s->mii_word >> 2) & 0x1f; + + //pclog("BitCnt = 16, op=%d, phy=%x, reg=%x.\n"); + if (op == 6) { + s->mii_word = tulip_mii_read(s, phy, reg); + } + } else if (s->mii_bitcnt == 32) { + op = (s->mii_word >> 28) & 0x0f; + phy = (s->mii_word >> 23) & 0x1f; + reg = (s->mii_word >> 18) & 0x1f; + data = s->mii_word & 0xffff; + + //pclog("BitCnt = 32, op=%d, phy=%x, reg=%x.\n"); + if (op == 5) { + tulip_mii_write(s, phy, reg, data); + } + } +} + +static uint32_t +tulip_csr9_read(TULIPState *s) +{ + if (s->device_info->local == 3) { + return s->eeprom_data[s->rom_read_addr++]; + } + if (s->csr[9] & CSR9_SR) { + if (nmc93cxx_eeprom_read(s->eeprom)) { + s->csr[9] |= CSR9_SR_DO; + } else { + s->csr[9] &= ~CSR9_SR_DO; + } + } + + tulip_mii(s); + return s->csr[9]; +} + +static void +tulip_update_ts(TULIPState *s, int state) +{ + s->csr[5] &= ~(CSR5_TS_MASK << CSR5_TS_SHIFT); + s->csr[5] |= (state & CSR5_TS_MASK) << CSR5_TS_SHIFT; +} + +static uint32_t +tulip_read(uint32_t addr, void *opaque) +{ + TULIPState *s = opaque; + uint32_t data = 0; + addr &= 127; + + switch (addr) { + case CSR(9): + data = tulip_csr9_read(s); + break; + + case CSR(12): + if (s->device_info->local == 3) { + data = 0; + break; + } + /* Fake autocompletion complete until we have PHY emulation */ + data = 5 << CSR12_ANS_SHIFT; + break; + + default: + if (!(addr & 7)) + data = s->csr[addr >> 3]; + break; + } + //pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); + return data; +} + +static void +tulip_tx(TULIPState *s, struct tulip_descriptor *desc) +{ + //pclog("TX FrameLen = %d.\n", s->tx_frame_len); + if (s->tx_frame_len) { + 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)) { + //pclog("Transmit!.\n"); + network_tx(s->nic, s->tx_frame, s->tx_frame_len); + } + } + + if (desc->control & TDES1_IC) { + s->csr[5] |= CSR5_TI; + tulip_update_int(s); + } +} + +static int +tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc) +{ + int len1 = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK; + int len2 = (desc->control >> TDES1_BUF2_SIZE_SHIFT) & TDES1_BUF2_SIZE_MASK; + + if (s->tx_frame_len + len1 > sizeof(s->tx_frame)) { + return -1; + } + if (len1) { + dma_bm_read(desc->buf_addr1, + s->tx_frame + s->tx_frame_len, len1, 4); + s->tx_frame_len += len1; + } + + if (s->tx_frame_len + len2 > sizeof(s->tx_frame)) { + return -1; + } + if (len2) { + dma_bm_read(desc->buf_addr2, + s->tx_frame + s->tx_frame_len, len2, 4); + s->tx_frame_len += len2; + } + desc->status = (len1 + len2) ? 0 : 0x7fffffff; + + return 0; +} + +static void +tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n) +{ + int offset = n * 12; + + s->filter[n][0] = buf[offset]; + s->filter[n][1] = buf[offset + 1]; + + s->filter[n][2] = buf[offset + 4]; + s->filter[n][3] = buf[offset + 5]; + + s->filter[n][4] = buf[offset + 8]; + s->filter[n][5] = buf[offset + 9]; +} + +static void +tulip_setup_frame(TULIPState *s, + struct tulip_descriptor *desc) +{ + uint8_t buf[4096]; + int len = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK; + + if (len == 192) { + dma_bm_read(desc->buf_addr1, buf, len, 4); + for (uint8_t i = 0; i < 16; i++) { + tulip_setup_filter_addr(s, buf, i); + } + } + + desc->status = 0x7fffffff; + + if (desc->control & TDES1_IC) { + s->csr[5] |= CSR5_TI; + tulip_update_int(s); + } +} + +static void +tulip_next_tx_descriptor(TULIPState *s, + struct tulip_descriptor *desc) +{ + if (desc->control & TDES1_TER) { + s->current_tx_desc = s->csr[4]; + } else if (desc->control & TDES1_TCH) { + s->current_tx_desc = desc->buf_addr2; + } else { + s->current_tx_desc += sizeof(struct tulip_descriptor) + (((s->csr[0] >> CSR0_DSL_SHIFT) & CSR0_DSL_MASK) << 2); + } + s->current_tx_desc &= ~3ULL; +} + +static uint32_t +tulip_ts(TULIPState *s) +{ + return (s->csr[5] >> CSR5_TS_SHIFT) & CSR5_TS_MASK; +} + +static void +tulip_xmit_list_update(TULIPState *s) +{ +#define TULIP_DESC_MAX 128 + struct tulip_descriptor desc; + + if (tulip_ts(s) != CSR5_TS_SUSPENDED) { + return; + } + + for (uint8_t i = 0; i < TULIP_DESC_MAX; i++) { + tulip_desc_read(s, s->current_tx_desc, &desc); + + if (!(desc.status & TDES0_OWN)) { + tulip_update_ts(s, CSR5_TS_SUSPENDED); + s->csr[5] |= CSR5_TU; + tulip_update_int(s); + return; + } + + if (desc.control & TDES1_SET) { + tulip_setup_frame(s, &desc); + } else { + if (desc.control & TDES1_FS) { + s->tx_frame_len = 0; + } + + if (!tulip_copy_tx_buffers(s, &desc)) { + if (desc.control & TDES1_LS) { + tulip_tx(s, &desc); + } + } + } + tulip_desc_write(s, s->current_tx_desc, &desc); + tulip_next_tx_descriptor(s, &desc); + } +} + +static void +tulip_csr9_write(TULIPState *s, UNUSED(uint32_t old_val), + uint32_t new_val) +{ + if (new_val & CSR9_SR) { + nmc93cxx_eeprom_write(s->eeprom, + !!(new_val & CSR9_SR_CS), + !!(new_val & CSR9_SR_SK), + !!(new_val & CSR9_SR_DI)); + } +} + +static void +tulip_reset(void *priv) +{ + TULIPState *s = (TULIPState *) priv; + const uint16_t *eeprom_data = nmc93cxx_eeprom_data(s->eeprom); + s->csr[0] = 0xfe000000; + s->csr[1] = 0xffffffff; + s->csr[2] = 0xffffffff; + s->csr[5] = 0xfc000000; + s->csr[6] = 0x32000040; + s->csr[7] = 0xfffe0000; + s->csr[8] = 0x00000000; + s->csr[9] = 0xfff483ff; + s->csr[11] = 0xfffe0000; + s->csr[12] = 0xfffffec6; + s->csr[13] = 0xffff0000; + s->csr[14] = 0xffffffff; + s->csr[15] = 0x8ff00000; + if (s->device_info->local != 3) { + s->subsys_id = eeprom_data[1]; + s->subsys_ven_id = eeprom_data[0]; + } +} + +static void +tulip_write(uint32_t addr, uint32_t data, void *opaque) +{ + TULIPState *s = opaque; + addr &= 127; + + //pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); + switch (addr) { + case CSR(0): + s->csr[0] = data; + if (data & CSR0_SWR) { + tulip_reset(s); + tulip_update_int(s); + } + break; + + case CSR(1): + tulip_xmit_list_update(s); + break; + + case CSR(2): + break; + + case CSR(3): + s->csr[3] = data & ~3ULL; + s->current_rx_desc = s->csr[3]; + break; + + case CSR(4): + s->csr[4] = data & ~3ULL; + s->current_tx_desc = s->csr[4]; + tulip_xmit_list_update(s); + break; + + case CSR(5): + /* Status register, write clears bit */ + s->csr[5] &= ~(data & (CSR5_TI | CSR5_TPS | CSR5_TU | CSR5_TJT | CSR5_LNP_ANC | CSR5_UNF | CSR5_RI | CSR5_RU | CSR5_RPS | CSR5_RWT | CSR5_ETI | CSR5_GTE | CSR5_LNF | CSR5_FBE | CSR5_ERI | CSR5_AIS | CSR5_NIS | CSR5_GPI | CSR5_LC)); + tulip_update_int(s); + break; + + case CSR(6): + s->csr[6] = data; + if (s->csr[6] & CSR6_SR) { + tulip_update_rs(s, CSR5_RS_RUNNING_WAIT_RECEIVE); + } else { + tulip_update_rs(s, CSR5_RS_STOPPED); + } + + if (s->csr[6] & CSR6_ST) { + tulip_update_ts(s, CSR5_TS_SUSPENDED); + tulip_xmit_list_update(s); + } else { + tulip_update_ts(s, CSR5_TS_STOPPED); + s->csr[5] |= CSR5_TPS; + } + break; + + case CSR(7): + s->csr[7] = data; + tulip_update_int(s); + break; + + case CSR(8): + s->csr[8] = data; + break; + + case CSR(9): + if (s->device_info->local != 3) { + tulip_csr9_write(s, s->csr[9], data); + /* don't clear MII read data */ + s->csr[9] &= CSR9_MDI; + s->csr[9] |= (data & ~CSR9_MDI); + tulip_mii(s); + s->old_csr9 = s->csr[9]; + } else { + s->rom_read_addr = 0; + } + break; + + case CSR(10): + s->csr[10] = data; + break; + + case CSR(11): + s->csr[11] = data; + break; + + case CSR(12): + /* SIA Status register, some bits are cleared by writing 1 */ + s->csr[12] &= ~(data & (CSR12_MRA | CSR12_TRA | CSR12_ARA)); + break; + + case CSR(13): + s->csr[13] = data; + if (s->device_info->local == 3 && (data & 0x4)) { + s->csr[13] = 0x8f01; + s->csr[14] = 0xfffd; + s->csr[15] = 0; + } + break; + + case CSR(14): + s->csr[14] = data; + break; + + case CSR(15): + s->csr[15] = data; + break; + + default: + pclog("%s: write to CSR at unknown address " + "0x%u\n", + __func__, addr); + break; + } +} + +static void +tulip_writeb_io(uint16_t addr, uint8_t data, void *opaque) +{ + return tulip_write(addr, data, opaque); +} + +static void +tulip_writew_io(uint16_t addr, uint16_t data, void *opaque) +{ + return tulip_write(addr, data, opaque); +} + +static void +tulip_writel_io(uint16_t addr, uint32_t data, void *opaque) +{ + return tulip_write(addr, data, opaque); +} + +static void +tulip_mem_writeb(uint32_t addr, uint8_t data, void *opaque) +{ + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); +} + +static void +tulip_mem_writew(uint32_t addr, uint16_t data, void *opaque) +{ + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); +} + +static void +tulip_mem_writel(uint32_t addr, uint32_t data, void *opaque) +{ + if ((addr & 0xfff) < 0x100) + tulip_write(addr, data, opaque); +} + +static uint8_t +tulip_mem_readb(uint32_t addr, void *opaque) +{ + uint8_t ret = 0xff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; +} + +static uint16_t +tulip_mem_readw(uint32_t addr, void *opaque) +{ + uint16_t ret = 0xffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; +} + +static uint32_t +tulip_mem_readl(uint32_t addr, void *opaque) +{ + uint32_t ret = 0xffffffff; + + if ((addr & 0xfff) < 0x100) + ret = tulip_read(addr, opaque); + + return ret; +} + +static uint8_t +tulip_readb_io(uint16_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +static uint16_t +tulip_readw_io(uint16_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +static uint32_t +tulip_readl_io(uint16_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +static void +tulip_idblock_crc(uint16_t *srom) +{ + unsigned char bitval; + unsigned char crc; + const int len = 9; + crc = -1; + + for (int word = 0; word < len; word++) { + for (int8_t bit = 15; bit >= 0; bit--) { + if ((word == (len - 1)) && (bit == 7)) { + /* + * Insert the correct CRC result into input data stream + * in place. + */ + srom[len - 1] = (srom[len - 1] & 0xff00) | (unsigned short) crc; + break; + } + bitval = ((srom[word] >> bit) & 1) ^ ((crc >> 7) & 1); + crc = crc << 1; + if (bitval == 1) { + crc ^= 6; + crc |= 0x01; + } + } + } +} + +static uint16_t +tulip_srom_crc(uint8_t *eeprom) +{ + unsigned long crc = 0xffffffff; + unsigned long flippedcrc = 0; + unsigned char currentbyte; + unsigned int msb; + unsigned int bit; + + for (size_t i = 0; i < 126; i++) { + currentbyte = eeprom[i]; + for (bit = 0; bit < 8; bit++) { + msb = (crc >> 31) & 1; + crc <<= 1; + if (msb ^ (currentbyte & 1)) { + crc ^= 0x04c11db6; + crc |= 0x00000001; + } + currentbyte >>= 1; + } + } + + for (uint8_t i = 0; i < 32; i++) { + flippedcrc <<= 1; + bit = crc & 1; + crc >>= 1; + flippedcrc += bit; + } + return (flippedcrc ^ 0xffffffff) & 0xffff; +} + +static uint8_t +tulip_pci_read(UNUSED(int func), int addr, void *priv) +{ + const TULIPState *s = (TULIPState *) priv; + uint8_t ret = 0; + + switch (addr) { + case 0x00: + ret = 0x11; + break; + case 0x01: + ret = 0x10; + break; + case 0x02: + if (s->device_info->local == 3) + ret = 0x02; + else if (s->device_info->local) + ret = 0x09; + else + ret = 0x19; + break; + case 0x03: + ret = 0x00; + break; + case 0x04: + ret = s->pci_conf[0x04]; + break; + case 0x05: + ret = s->pci_conf[0x05]; + break; + case 0x06: + ret = 0x80; + break; + case 0x07: + ret = 0x02; + break; + case 0x08: + ret = 0x20; + break; + case 0x09: + ret = 0x00; + break; + case 0x0A: + ret = 0x00; + break; + case 0x0B: + ret = 0x02; + break; + case 0x10: + ret = (tulip_pci_bar[0].addr_regs[0] & 0x80) | 0x01; + break; + case 0x11: + ret = tulip_pci_bar[0].addr_regs[1]; + break; + case 0x12: + ret = tulip_pci_bar[0].addr_regs[2]; + break; + case 0x13: + ret = tulip_pci_bar[0].addr_regs[3]; + break; +#ifdef USE_128_BYTE_BAR + case 0x14: + ret = (tulip_pci_bar[1].addr_regs[0] & 0x80); + break; +#endif + case 0x15: +#ifdef USE_128_BYTE_BAR + ret = tulip_pci_bar[1].addr_regs[1]; +#else + ret = tulip_pci_bar[1].addr_regs[1] & 0xf0; +#endif + break; + case 0x16: + ret = tulip_pci_bar[1].addr_regs[2]; + break; + case 0x17: + ret = tulip_pci_bar[1].addr_regs[3]; + break; + case 0x2C: + ret = s->subsys_ven_id & 0xFF; + break; + case 0x2D: + ret = s->subsys_ven_id >> 8; + break; + case 0x2E: + ret = s->subsys_id & 0xFF; + break; + case 0x2F: + ret = s->subsys_id >> 8; + break; + case 0x30: + ret = (tulip_pci_bar[2].addr_regs[0] & 0x01); + break; + case 0x31: + ret = tulip_pci_bar[2].addr_regs[1]; + break; + case 0x32: + ret = tulip_pci_bar[2].addr_regs[2]; + break; + case 0x33: + ret = tulip_pci_bar[2].addr_regs[3]; + break; + case 0x3C: + ret = s->pci_conf[0x3C]; + break; + case 0x3D: + ret = PCI_INTA; + break; + case 0x3E: + case 0x3F: + case 0x41: + ret = s->pci_conf[addr & 0xff]; + break; + } + + //pclog("PCI read=%02x, ret=%02x.\n", addr, ret); + return ret; +} + +static void +tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +{ + TULIPState *s = (TULIPState *) priv; + + //pclog("PCI write=%02x, ret=%02x.\n", addr, val); + switch (addr) { + case 0x04: + s->pci_conf[0x04] = val & 0x07; + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + io_removehandler(s->PCIBase, 128, + tulip_readb_io, tulip_readw_io, tulip_readl_io, + tulip_writeb_io, tulip_writew_io, tulip_writel_io, + priv); + if ((s->PCIBase != 0) && (val & PCI_COMMAND_IO)) + io_sethandler(s->PCIBase, 128, + tulip_readb_io, tulip_readw_io, tulip_readl_io, + tulip_writeb_io, tulip_writew_io, tulip_writel_io, + priv); + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + mem_mapping_disable(&s->memory); + if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) + mem_mapping_enable(&s->memory); + break; + case 0x05: + s->pci_conf[0x05] = val & 1; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + io_removehandler(s->PCIBase, 128, + tulip_readb_io, tulip_readw_io, tulip_readl_io, + tulip_writeb_io, tulip_writew_io, tulip_writel_io, + priv); + tulip_pci_bar[0].addr_regs[addr & 3] = val; + tulip_pci_bar[0].addr &= 0xffffff80; + s->PCIBase = tulip_pci_bar[0].addr; + if (s->pci_conf[0x4] & PCI_COMMAND_IO) { + //pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); + if (s->PCIBase != 0) + io_sethandler(s->PCIBase, 128, + tulip_readb_io, tulip_readw_io, tulip_readl_io, + tulip_writeb_io, tulip_writew_io, tulip_writel_io, + priv); + } + break; +#ifndef USE_128_BYTE_BAR + case 0x14: +#endif + case 0x15: + case 0x16: + case 0x17: + mem_mapping_disable(&s->memory); + tulip_pci_bar[1].addr_regs[addr & 3] = val; +#ifdef USE_128_BYTE_BAR + tulip_pci_bar[1].addr &= 0xffffff80; +#else + tulip_pci_bar[1].addr &= 0xfffff000; +#endif + s->MMIOBase = tulip_pci_bar[1].addr; + if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { + //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); + if (s->MMIOBase != 0) +#ifdef USE_128_BYTE_BAR + mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); +#else + mem_mapping_set_addr(&s->memory, s->MMIOBase, 4096); +#endif + } + break; + case 0x30: /* PCI_ROMBAR */ + case 0x31: /* PCI_ROMBAR */ + case 0x32: /* PCI_ROMBAR */ + case 0x33: /* PCI_ROMBAR */ + if (!s->has_bios) + return; + + mem_mapping_disable(&s->bios_rom.mapping); + tulip_pci_bar[2].addr_regs[addr & 3] = val; + tulip_pci_bar[2].addr &= 0xffff0001; + s->bios_addr = tulip_pci_bar[2].addr & 0xffff0000; + if (tulip_pci_bar[2].addr_regs[0] & 0x01) { + if (s->bios_addr != 0) + mem_mapping_set_addr(&s->bios_rom.mapping, s->bios_addr, 0x10000); + } + return; + case 0x3C: + s->pci_conf[0x3c] = val; + return; + case 0x3E: + case 0x3F: + case 0x41: + s->pci_conf[addr & 0xff] = val; + return; + } +} + +static void * +nic_init(const device_t *info) +{ + nmc93cxx_eeprom_params_t params; + TULIPState *s = calloc(1, sizeof(TULIPState)); + char filename[1024] = { 0 }; + uint32_t mac; + uint8_t *eeprom_data; + + if (!s) + return NULL; + + if (info->local && info->local != 3) { + s->bios_addr = 0xD0000; + s->has_bios = device_get_config_int("bios"); + } else { + s->bios_addr = 0; + s->has_bios = 0; + } + +#ifdef USE_128_BYTE_BAR + mem_mapping_add(&s->memory, 0x0fffff00, 128, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#else + mem_mapping_add(&s->memory, 0x0ffff000, 4096, tulip_mem_readb, tulip_mem_readw, tulip_mem_readl, tulip_mem_writeb, tulip_mem_writew, tulip_mem_writel, NULL, MEM_MAPPING_EXTERNAL, s); +#endif + mem_mapping_disable(&s->memory); + + s->device_info = info; + + if (info->local != 3) { + if (info->local == 2) { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x0a; + + /*Subsystem ID*/ + s->eeprom_data[2] = 0x14; + s->eeprom_data[3] = 0x21; + } else { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = info->local ? 0x25 : 0x11; + s->eeprom_data[1] = 0x10; + + /*Subsystem ID*/ + s->eeprom_data[2] = info->local ? 0x10 : 0x0a; + s->eeprom_data[3] = info->local ? 0x03 : 0x50; + } + + /*Cardbus CIS Pointer low*/ + s->eeprom_data[4] = 0x00; + s->eeprom_data[5] = 0x00; + + /*Cardbus CIS Pointer high*/ + s->eeprom_data[6] = 0x00; + s->eeprom_data[7] = 0x00; + + /*ID Reserved1*/ + for (int i = 0; i < 7; i++) + s->eeprom_data[8 + i] = 0x00; + + /*MiscHwOptions*/ + s->eeprom_data[15] = 0x00; + + /*ID_BLOCK_CRC*/ + tulip_idblock_crc((uint16_t *) s->eeprom_data); + + /*Func0_HwOptions*/ + s->eeprom_data[17] = 0x00; + + /*SROM Format Version 1, compatible with older guests*/ + s->eeprom_data[18] = 0x01; + + /*Controller Count*/ + s->eeprom_data[19] = 0x01; + + /*DEC OID*/ + s->eeprom_data[20] = 0x00; + s->eeprom_data[21] = 0x00; + s->eeprom_data[22] = 0xf8; + + if (info->local == 2) { + /* Microsoft VPC DEC Tulip. */ + s->eeprom_data[20] = 0x00; + s->eeprom_data[21] = 0x03; + s->eeprom_data[22] = 0x0f; + } + + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[23] = random_generate(); + s->eeprom_data[24] = random_generate(); + s->eeprom_data[25] = random_generate(); + mac = (((int) s->eeprom_data[23]) << 16); + mac |= (((int) s->eeprom_data[24]) << 8); + mac |= ((int) s->eeprom_data[25]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[23] = (mac >> 16) & 0xff; + s->eeprom_data[24] = (mac >> 8) & 0xff; + s->eeprom_data[25] = (mac & 0xff); + } + + /*Controller_0 Device_Number*/ + s->eeprom_data[26] = 0x00; + + /*Controller_0 Info Leaf_Offset*/ + s->eeprom_data[27] = 0x1e; + s->eeprom_data[28] = 0x00; + + /*Selected Connection Type, Powerup AutoSense and Dynamic AutoSense if the board supports it*/ + s->eeprom_data[30] = 0x00; + s->eeprom_data[31] = 0x08; + + if (info->local) { + /*General Purpose Control*/ + s->eeprom_data[32] = 0xff; + + /*Block Count*/ + s->eeprom_data[33] = 0x01; + + /*Extended Format (first part)*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[34] = 0x81; + + /*Block Type (first part)*/ + s->eeprom_data[35] = 0x01; + + /*Extended Format (second part) - Block Type 0 for 21140*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[36] = 0x85; + + /*Block Type (second part)*/ + s->eeprom_data[37] = 0x00; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[38] = 0x01; + + /*General Purpose Data*/ + s->eeprom_data[39] = 0x00; + + /*Command*/ + s->eeprom_data[40] = 0x00; + s->eeprom_data[41] = 0x00; + } else { + /*Block Count*/ + s->eeprom_data[32] = 0x01; + + /*Extended Format - Block Type 2 for 21142/21143*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[33] = 0x86; + + /*Block Type*/ + s->eeprom_data[34] = 0x02; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[35] = 0x01; + + /*General Purpose Control*/ + s->eeprom_data[36] = 0xff; + s->eeprom_data[37] = 0xff; + + /*General Purpose Data*/ + s->eeprom_data[38] = 0x00; + s->eeprom_data[39] = 0x00; + } + + s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; + s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; + } else { + uint32_t checksum = 0; + /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ + memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + /*DEC OID*/ + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x00; + s->eeprom_data[2] = 0xF8; + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[3] = random_generate(); + s->eeprom_data[4] = random_generate(); + s->eeprom_data[5] = random_generate(); + mac = (((int) s->eeprom_data[3]) << 16); + mac |= (((int) s->eeprom_data[4]) << 8); + mac |= ((int) s->eeprom_data[5]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[3] = (mac >> 16) & 0xff; + s->eeprom_data[4] = (mac >> 8) & 0xff; + s->eeprom_data[5] = (mac & 0xff); + } + + /* Generate checksum. */ + checksum = (s->eeprom_data[0] * 256) | s->eeprom_data[1]; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 2nd pair. */ + checksum += (s->eeprom_data[2] * 256) | s->eeprom_data[3]; + if (checksum > 65535) + checksum = checksum % 65535; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 3rd pair. */ + checksum += (s->eeprom_data[4] * 256) | s->eeprom_data[5]; + if (checksum > 65535) + checksum = checksum % 65535; + + if (checksum >= 65535) + checksum = 0; + + s->eeprom_data[6] = (checksum >> 8) & 0xFF; + s->eeprom_data[7] = checksum & 0xFF; + } + + if (info->local != 3) { + params.nwords = 64; + params.default_content = (uint16_t *) s->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + free(s); + return NULL; + } + } + + tulip_pci_bar[0].addr_regs[0] = 1; + tulip_pci_bar[1].addr_regs[0] = 0; + s->pci_conf[0x04] = 7; + + /* Enable our BIOS space in PCI, if needed. */ + if (s->bios_addr > 0) { + rom_init(&s->bios_rom, ROM_PATH_DEC21140, s->bios_addr, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + tulip_pci_bar[2].addr = 0xffff0000; + } else + tulip_pci_bar[2].addr = 0; + + mem_mapping_disable(&s->bios_rom.mapping); + eeprom_data = (info->local == 3) ? s->eeprom_data : (uint8_t *) &nmc93cxx_eeprom_data(s->eeprom)[0]; + + //pclog("EEPROM Data Format=%02x, Count=%02x, MAC=%02x:%02x:%02x:%02x:%02x:%02x.\n", eeprom_data[0x12], eeprom_data[0x13], eeprom_data[0x14], eeprom_data[0x15], eeprom_data[0x16], eeprom_data[0x17], eeprom_data[0x18], eeprom_data[0x19]); + memcpy(s->mii_regs, tulip_mdi_default, sizeof(tulip_mdi_default)); + s->nic = network_attach(s, &eeprom_data[(info->local == 3) ? 0 : 20], tulip_receive, NULL); + pci_add_card(PCI_ADD_NORMAL, tulip_pci_read, tulip_pci_write, s, &s->pci_slot); + tulip_reset(s); + return s; +} + +static void +nic_close(void *priv) +{ + free(priv); +} + +// clang-format off +static const device_config_t dec_tulip_21143_config[] = { + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t dec_tulip_21140_config[] = { + { + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t dec_tulip_device = { + .name = "DE500A Fast Ethernet (DECchip 21143 \"Tulip\")", + .internal_name = "dec_21143_tulip", + .flags = DEVICE_PCI, + .local = 0, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21143_config +}; + +const device_t dec_tulip_21140_device = { + .name = "DEC 21140 Fast Ethernet (DECchip 21140 \"Tulip FasterNet\")", + .internal_name = "dec_21140_tulip", + .flags = DEVICE_PCI, + .local = 1, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21140_config +}; + +const device_t dec_tulip_21140_vpc_device = { + .name = "Microsoft Virtual PC Network (DECchip 21140 \"Tulip FasterNet\")", + .internal_name = "dec_21140_tulip_vpc", + .flags = DEVICE_PCI, + .local = 2, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21140_config +}; + +const device_t dec_tulip_21040_device = { + .name = "DEC DE-435 EtherWorks Turbo (DECchip 21040 \"Tulip\")", + .internal_name = "dec_21040_tulip", + .flags = DEVICE_PCI, + .local = 3, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21143_config +}; diff --git a/src/network/net_vde.c b/src/network/net_vde.c index 5bcf1ffff0..afeeaac9c7 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -62,15 +62,15 @@ static volatile void *libvde_handle = NULL; //+ // VDE connection structure //- -typedef struct { - void *vdeconn; // VDEPLUG Connection - netcard_t *card; // NIC linked to - thread_t *poll_tid; // Polling thread - net_evt_t tx_event; // Packets to transmit event - net_evt_t stop_event; // Stop thread event - netpkt_t pkt; // Packet read/sent - netpkt_t pktv[VDE_PKT_BATCH]; // Packet queue - uint8_t mac_addr[6]; // MAC Address +typedef struct net_vde_t { + void *vdeconn; // VDEPLUG Connection + netcard_t *card; // NIC linked to + thread_t *poll_tid; // Polling thread + net_evt_t tx_event; // Packets to transmit event + net_evt_t stop_event; // Stop thread event + netpkt_t pkt; // Packet read/sent + netpkt_t pktv[VDE_PKT_BATCH]; // Packet queue + uint8_t mac_addr[6]; // MAC Address } net_vde_t; //+ @@ -221,7 +221,7 @@ void net_vde_close(void *priv) { free(vde->pktv[i].data); } free(vde->pkt.data); - f_vde_close((void *) vde->vdeconn); + f_vde_close(vde->vdeconn); net_event_close(&vde->tx_event); net_event_close(&vde->stop_event); free(vde); diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 385f4332a6..04b922aaf3 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -64,6 +64,8 @@ #include <86box/net_dp8390.h> #include <86box/net_wd8003.h> #include <86box/bswap.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include "cpu.h" @@ -98,12 +100,14 @@ #define WE_ID_EXTRA_RAM 0x40 #define WE_ID_BUS_MCA 0x80 -typedef struct { +typedef struct wd_t { dp8390_t *dp8390; mem_mapping_t ram_mapping; - uint32_t ram_addr, ram_size; + uint32_t ram_addr; + uint32_t ram_size; uint8_t maclocal[6]; /* configured MAC (local) address */ - uint8_t bit16, pad; + uint8_t bit16; + uint8_t pad; int board; const char *name; uint32_t base_address; @@ -113,11 +117,12 @@ typedef struct { uint8_t pos_regs[8]; /* Memory for WD cards*/ - uint8_t msr, /* Memory Select Register (MSR) */ - icr, /* Interface Configuration Register (ICR) */ - irr, /* Interrupt Request Register (IRR) */ - laar, /* LA Address Register (read by Windows 98!) */ - if_chip, board_chip; + uint8_t msr; /* Memory Select Register (MSR) */ + uint8_t icr; /* Interface Configuration Register (ICR) */ + uint8_t irr; /* Interrupt Request Register (IRR) */ + uint8_t laar; /* LA Address Register (read by Windows 98!) */ + uint8_t if_chip; + uint8_t board_chip; } wd_t; #ifdef ENABLE_WD_LOG @@ -143,7 +148,7 @@ static const int we_int_table[4] = { 2, 3, 4, 7 }; static void wd_interrupt(void *priv, int set) { - wd_t *dev = (wd_t *) priv; + const wd_t *dev = (wd_t *) priv; if (!(dev->irr & WE_IRR_ENABLE_IRQ)) return; @@ -176,7 +181,7 @@ wd_soft_reset(void *priv) static uint8_t wd_ram_read(uint32_t addr, void *priv) { - wd_t *dev = (wd_t *) priv; + const wd_t *dev = (wd_t *) priv; wdlog("WD80x3: RAM Read: addr=%06x, val=%02x\n", addr & (dev->ram_size - 1), dev->dp8390->mem[addr & (dev->ram_size - 1)]); return dev->dp8390->mem[addr & (dev->ram_size - 1)]; @@ -280,6 +285,9 @@ wd_smc_read(wd_t *dev, uint32_t off) retval = 0xff - (checksum & 0xff); break; + + default: + break; } wdlog("%s: ASIC read addr=0x%02x, value=0x%04x\n", @@ -513,7 +521,7 @@ wd_io_remove(wd_t *dev, uint16_t addr) static uint8_t wd_mca_read(int port, void *priv) { - wd_t *dev = (wd_t *) priv; + const wd_t *dev = (wd_t *) priv; return (dev->pos_regs[port & 7]); } @@ -602,6 +610,9 @@ wd_8013epa_mca_write(int port, uint8_t val, void *priv) case 0x0c: dev->irq = 14; break; + + default: + break; } if (dev->pos_regs[3] & 0x10) @@ -629,7 +640,7 @@ wd_8013epa_mca_write(int port, uint8_t val, void *priv) } static uint8_t -wd_mca_feedb(void *priv) +wd_mca_feedb(UNUSED(void *priv)) { return 1; } @@ -724,6 +735,8 @@ wd_init(const device_t *info) /* Ethernet, MCA, 5x3 interface chip, RAM 16k */ case WD8003EA: dev->board_chip = WE_ID_SOFT_CONFIG; + fallthrough; + /* Ethernet, MCA, no interface chip, RAM 16k */ case WD8003ETA: dev->board_chip |= WE_TYPE_WD8013EBT | WE_ID_BUS_MCA; @@ -740,6 +753,9 @@ wd_init(const device_t *info) dev->pos_regs[1] = 0x61; dev->bit16 = 3; break; + + default: + break; } dev->irr |= WE_IRR_ENABLE_IRQ; diff --git a/src/network/network.c b/src/network/network.c index eec85fcb00..9eb537e3a4 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -67,11 +67,8 @@ #include <86box/ui.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/net_3c501.h> -#include <86box/net_3c503.h> #include <86box/net_ne2000.h> #include <86box/net_pcnet.h> -#include <86box/net_plip.h> #include <86box/net_wd8003.h> #ifdef _WIN32 @@ -94,12 +91,30 @@ static const device_t net_none_device = { .config = NULL }; +static const device_t net_internal_device = { + .name = "Internal", + .internal_name = "internal", + .flags = 0, + .local = NET_TYPE_NONE, + .init = NULL, + .close = NULL, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + static const device_t *net_cards[] = { &net_none_device, + &net_internal_device, &threec501_device, &threec503_device, &pcnet_am79c960_device, &pcnet_am79c961_device, + &de220p_device, + &ne1000_compat_device, + &ne2000_compat_device, &ne1000_device, &ne2000_device, &pcnet_am79c960_eb_device, @@ -114,7 +129,12 @@ static const device_t *net_cards[] = { &wd8013epa_device, &pcnet_am79c973_device, &pcnet_am79c970a_device, + &dec_tulip_device, &rtl8029as_device, + &rtl8139c_plus_device, + &dec_tulip_21140_device, + &dec_tulip_21140_vpc_device, + &dec_tulip_21040_device, &pcnet_am79c960_vlb_device, NULL }; @@ -564,7 +584,8 @@ network_reset(void) } net_card_current = i; - device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); + if (net_cards_conf[i].device_num > NET_INTERNAL) + device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); } } @@ -669,7 +690,8 @@ network_dev_available(int id) { int available = (net_cards_conf[id].device_num > 0); - if (net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)) + if ((net_cards_conf[id].net_type == NET_TYPE_PCAP) && + (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)) available = 0; // TODO: Handle VDE device @@ -717,7 +739,7 @@ network_card_has_config(int card) } /* UI */ -char * +const char * network_card_get_internal_name(int card) { return device_get_internal_name(net_cards[card]); @@ -730,7 +752,7 @@ network_card_get_from_internal_name(char *s) int c = 0; while (net_cards[c] != NULL) { - if (!strcmp((char *) net_cards[c]->internal_name, s)) + if (!strcmp(net_cards[c]->internal_name, s)) return c; c++; } diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 19abb74c3b..1d3e392218 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -176,7 +176,7 @@ start_cap(char *dev) char temp[PCAP_ERRBUF_SIZE]; struct pcap_pkthdr *hdr; const unsigned char *pkt; - struct tm *ltime; + const struct tm *ltime; time_t now; pcap_t *pcap; int rc; diff --git a/src/network/slirp/CMakeLists.txt b/src/network/slirp/CMakeLists.txt deleted file mode 100644 index 60993ad84c..0000000000 --- a/src/network/slirp/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# 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. -# -# CMake build script. -# -# Authors: David Hrdlička, -# -# Copyright 2020-2021 David Hrdlička. -# - -add_library(slirp STATIC arp_table.c bootp.c cksum.c dhcpv6.c dnssearch.c if.c - ip_icmp.c ip_input.c ip_output.c - ip6_icmp.c ip6_input.c ip6_output.c - mbuf.c misc.c sbuf.c slirp.c socket.c - tcp_input.c tcp_output.c tcp_subr.c tcp_timer.c - udp.c udp6.c - util.c version.c) - -if(WIN32) - target_link_libraries(slirp wsock32 iphlpapi) -endif() - -if(APPLE) - target_link_libraries(slirp resolv) -endif() - -# tinyglib conflicts with the real GLib used by Qt, let's just be safe -if(QT AND UNIX AND NOT APPLE) - set(SLIRP_TINYGLIB OFF) -endif() - -option(SLIRP_TINYGLIB "Use a minimal GLib stub (`tinyglib`) with SLiRP" ON) - -if(SLIRP_TINYGLIB) - target_sources(slirp PRIVATE tinyglib.c) -else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) - target_link_libraries(slirp PkgConfig::GLIB) - - target_compile_definitions(slirp PRIVATE TINYGLIB_USE_GLIB) -endif() diff --git a/src/network/slirp/arp_table.c b/src/network/slirp/arp_table.c deleted file mode 100644 index d0c9111d6b..0000000000 --- a/src/network/slirp/arp_table.c +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * ARP table - * - * Copyright (c) 2011 AdaCore - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "slirp.h" - -#include - -void arp_table_add(Slirp *slirp, uint32_t ip_addr, - const uint8_t ethaddr[ETH_ALEN]) -{ - const uint32_t broadcast_addr = - ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; - ArpTable *arptbl = &slirp->arp_table; - int i; -/* - char ethaddr_str[ETH_ADDRSTRLEN]; - char addr[INET_ADDRSTRLEN]; - - DEBUG_CALL("arp_table_add"); - DEBUG_ARG("ip = %s", inet_ntop(AF_INET, &(struct in_addr){ .s_addr = ip_addr }, - addr, sizeof(addr))); - DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str, - sizeof(ethaddr_str))); -*/ - - if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) { - /* Do not register broadcast addresses */ - return; - } - - /* Search for an entry */ - for (i = 0; i < ARP_TABLE_SIZE; i++) { - if (arptbl->table[i].ar_sip == ip_addr) { - /* Update the entry */ - memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN); - return; - } - } - - /* No entry found, create a new one */ - arptbl->table[arptbl->next_victim].ar_sip = ip_addr; - memcpy(arptbl->table[arptbl->next_victim].ar_sha, ethaddr, ETH_ALEN); - arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE; -} - -bool arp_table_search(Slirp *slirp, uint32_t ip_addr, - uint8_t out_ethaddr[ETH_ALEN]) -{ - const uint32_t broadcast_addr = - ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; - ArpTable *arptbl = &slirp->arp_table; - int i; -/* - char ethaddr_str[ETH_ADDRSTRLEN]; - char addr[INET_ADDRSTRLEN]; - - DEBUG_CALL("arp_table_search"); - DEBUG_ARG("ip = %s", inet_ntop(AF_INET, &(struct in_addr){ .s_addr = ip_addr }, - addr, sizeof(addr))); -*/ - - /* If broadcast address */ - if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) { - /* return Ethernet broadcast address */ - memset(out_ethaddr, 0xff, ETH_ALEN); - return 1; - } - - for (i = 0; i < ARP_TABLE_SIZE; i++) { - if (arptbl->table[i].ar_sip == ip_addr) { - memcpy(out_ethaddr, arptbl->table[i].ar_sha, ETH_ALEN); -/* - DEBUG_ARG("found hw addr = %s", - slirp_ether_ntoa(out_ethaddr, ethaddr_str, - sizeof(ethaddr_str))); -*/ - return 1; - } - } - - return 0; -} diff --git a/src/network/slirp/bootp.c b/src/network/slirp/bootp.c deleted file mode 100644 index a0eb17a9dd..0000000000 --- a/src/network/slirp/bootp.c +++ /dev/null @@ -1,398 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * QEMU BOOTP/DHCP server - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "slirp.h" - -#if defined(_WIN32) -/* Windows ntohl() returns an u_long value. - * Add a type cast to match the format strings. */ -#define ntohl(n) ((uint32_t)ntohl(n)) -#endif - -/* XXX: only DHCP is supported */ - -#define LEASE_TIME (24 * 3600) - -#define UEFI_HTTP_VENDOR_CLASS_ID "HTTPClient" - -static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; - -#define DPRINTF(fmt, ...) DEBUG_CALL(fmt, ##__VA_ARGS__) - -static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr, - const uint8_t *macaddr) -{ - BOOTPClient *bc; - int i; - - for (i = 0; i < NB_BOOTP_CLIENTS; i++) { - bc = &slirp->bootp_clients[i]; - if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) - goto found; - } - return NULL; -found: - bc = &slirp->bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i); - return bc; -} - -static BOOTPClient *request_addr(Slirp *slirp, const struct in_addr *paddr, - const uint8_t *macaddr) -{ - uint32_t req_addr = ntohl(paddr->s_addr); - uint32_t dhcp_addr = ntohl(slirp->vdhcp_startaddr.s_addr); - BOOTPClient *bc; - - if (req_addr >= dhcp_addr && req_addr < (dhcp_addr + NB_BOOTP_CLIENTS)) { - bc = &slirp->bootp_clients[req_addr - dhcp_addr]; - if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) { - bc->allocated = 1; - return bc; - } - } - return NULL; -} - -static BOOTPClient *find_addr(Slirp *slirp, struct in_addr *paddr, - const uint8_t *macaddr) -{ - BOOTPClient *bc; - int i; - - for (i = 0; i < NB_BOOTP_CLIENTS; i++) { - if (!memcmp(macaddr, slirp->bootp_clients[i].macaddr, 6)) - goto found; - } - return NULL; -found: - bc = &slirp->bootp_clients[i]; - bc->allocated = 1; - paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i); - return bc; -} - -static void dhcp_decode(const struct bootp_t *bp, - const uint8_t *bp_end, - int *pmsg_type, - struct in_addr *preq_addr) -{ - const uint8_t *p; - int len, tag; - - *pmsg_type = 0; - preq_addr->s_addr = htonl(0L); - - p = bp->bp_vend; - if (memcmp(p, rfc1533_cookie, 4) != 0) - return; - p += 4; - while (p < bp_end) { - tag = p[0]; - if (tag == RFC1533_PAD) { - p++; - } else if (tag == RFC1533_END) { - break; - } else { - p++; - if (p >= bp_end) - break; - len = *p++; - if (p + len > bp_end) { - break; - } - DPRINTF("dhcp: tag=%d len=%d\n", tag, len); - - switch (tag) { - case RFC2132_MSG_TYPE: - if (len >= 1) - *pmsg_type = p[0]; - break; - case RFC2132_REQ_ADDR: - if (len >= 4) { - memcpy(&(preq_addr->s_addr), p, 4); - } - break; - default: - break; - } - p += len; - } - } - if (*pmsg_type == DHCPREQUEST && preq_addr->s_addr == htonl(0L) && - bp->bp_ciaddr.s_addr) { - memcpy(&(preq_addr->s_addr), &bp->bp_ciaddr, 4); - } -} - -static void bootp_reply(Slirp *slirp, - const struct bootp_t *bp, - const uint8_t *bp_end) -{ - BOOTPClient *bc = NULL; - struct mbuf *m; - struct bootp_t *rbp; - struct sockaddr_in saddr, daddr; - struct in_addr preq_addr; - int dhcp_msg_type, val; - uint8_t *q; - uint8_t *end; - uint8_t client_ethaddr[ETH_ALEN]; - - /* extract exact DHCP msg type */ - dhcp_decode(bp, bp_end, &dhcp_msg_type, &preq_addr); - DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type); - if (preq_addr.s_addr != htonl(0L)) - DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr)); - else { - DPRINTF("\n"); - } - - if (dhcp_msg_type == 0) - dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ - - if (dhcp_msg_type != DHCPDISCOVER && dhcp_msg_type != DHCPREQUEST) - return; - - /* Get client's hardware address from bootp request */ - memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN); - - m = m_get(slirp); - if (!m) { - return; - } - m->m_data += IF_MAXLINKHDR; - m_inc(m, sizeof(struct bootp_t) + DHCP_OPT_LEN); - rbp = (struct bootp_t *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - memset(rbp, 0, sizeof(struct bootp_t) + DHCP_OPT_LEN); - - if (dhcp_msg_type == DHCPDISCOVER) { - if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, client_ethaddr); - if (bc) { - daddr.sin_addr = preq_addr; - } - } - if (!bc) { - new_addr: - bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr); - if (!bc) { - DPRINTF("no address left\n"); - return; - } - } - memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); - } else if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, client_ethaddr); - if (bc) { - daddr.sin_addr = preq_addr; - memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); - } else { - /* DHCPNAKs should be sent to broadcast */ - daddr.sin_addr.s_addr = 0xffffffff; - } - } else { - bc = find_addr(slirp, &daddr.sin_addr, bp->bp_hwaddr); - if (!bc) { - /* if never assigned, behaves as if it was already - assigned (windows fix because it remembers its address) */ - goto new_addr; - } - } - - /* Update ARP table for this IP address */ - arp_table_add(slirp, daddr.sin_addr.s_addr, client_ethaddr); - - saddr.sin_addr = slirp->vhost_addr; - saddr.sin_port = htons(BOOTP_SERVER); - - daddr.sin_port = htons(BOOTP_CLIENT); - - rbp->bp_op = BOOTP_REPLY; - rbp->bp_xid = bp->bp_xid; - rbp->bp_htype = 1; - rbp->bp_hlen = 6; - memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, ETH_ALEN); - - rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ - rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ - - q = rbp->bp_vend; - end = rbp->bp_vend + DHCP_OPT_LEN; - memcpy(q, rfc1533_cookie, 4); - q += 4; - - if (bc) { - DPRINTF("%s addr=%08" PRIx32 "\n", - (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed", - ntohl(daddr.sin_addr.s_addr)); - - if (dhcp_msg_type == DHCPDISCOVER) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPOFFER; - } else /* DHCPREQUEST */ { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPACK; - } - - if (slirp->bootp_filename) { - g_assert(strlen(slirp->bootp_filename) < sizeof(rbp->bp_file)); - strcpy(rbp->bp_file, slirp->bootp_filename); - } - - *q++ = RFC2132_SRV_ID; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_NETMASK; - *q++ = 4; - memcpy(q, &slirp->vnetwork_mask, 4); - q += 4; - - if (!slirp->restricted) { - *q++ = RFC1533_GATEWAY; - *q++ = 4; - memcpy(q, &saddr.sin_addr, 4); - q += 4; - - *q++ = RFC1533_DNS; - *q++ = 4; - memcpy(q, &slirp->vnameserver_addr, 4); - q += 4; - } - - *q++ = RFC2132_LEASE_TIME; - *q++ = 4; - val = htonl(LEASE_TIME); - memcpy(q, &val, 4); - q += 4; - - if (*slirp->client_hostname) { - val = strlen(slirp->client_hostname); - if (q + val + 2 >= end) { - g_warning("DHCP packet size exceeded, " - "omitting host name option."); - } else { - *q++ = RFC1533_HOSTNAME; - *q++ = val; - memcpy(q, slirp->client_hostname, val); - q += val; - } - } - - if (slirp->vdomainname) { - val = strlen(slirp->vdomainname); - if (q + val + 2 >= end) { - g_warning("DHCP packet size exceeded, " - "omitting domain name option."); - } else { - *q++ = RFC1533_DOMAINNAME; - *q++ = val; - memcpy(q, slirp->vdomainname, val); - q += val; - } - } - - if (slirp->tftp_server_name) { - val = strlen(slirp->tftp_server_name); - if (q + val + 2 >= end) { - g_warning("DHCP packet size exceeded, " - "omitting tftp-server-name option."); - } else { - *q++ = RFC2132_TFTP_SERVER_NAME; - *q++ = val; - memcpy(q, slirp->tftp_server_name, val); - q += val; - } - } - - if (slirp->vdnssearch) { - val = slirp->vdnssearch_len; - if (q + val >= end) { - g_warning("DHCP packet size exceeded, " - "omitting domain-search option."); - } else { - memcpy(q, slirp->vdnssearch, val); - q += val; - } - } - - /* this allows to support UEFI HTTP boot: according to the UEFI - specification, DHCP server must send vendor class identifier option - set to "HTTPClient" string, when responding to DHCP requests as part - of the UEFI HTTP boot - - we assume that, if the bootfile parameter was configured as an http - URL, the user intends to perform UEFI HTTP boot, so send this option - automatically */ - if (slirp->bootp_filename && g_str_has_prefix(slirp->bootp_filename, "http://")) { - val = strlen(UEFI_HTTP_VENDOR_CLASS_ID); - if (q + val + 2 >= end) { - g_warning("DHCP packet size exceeded, " - "omitting vendor class id option."); - } else { - *q++ = RFC2132_VENDOR_CLASS_ID; - *q++ = val; - memcpy(q, UEFI_HTTP_VENDOR_CLASS_ID, val); - q += val; - } - } - } else { - static const char nak_msg[] = "requested address not available"; - - DPRINTF("nak'ed addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr)); - - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPNAK; - - *q++ = RFC2132_MESSAGE; - *q++ = sizeof(nak_msg) - 1; - memcpy(q, nak_msg, sizeof(nak_msg) - 1); - q += sizeof(nak_msg) - 1; - } - assert(q < end); - *q++ = RFC1533_END; - - daddr.sin_addr.s_addr = 0xffffffffu; - - assert(q <= end); - - m->m_len = sizeof(struct bootp_t) + (end - rbp->bp_vend) - sizeof(struct ip) - sizeof(struct udphdr); - udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); -} - -void bootp_input(struct mbuf *m) -{ - struct bootp_t *bp = mtod_check(m, sizeof(struct bootp_t)); - - if (!m->slirp->disable_dhcp && bp && bp->bp_op == BOOTP_REQUEST) { - bootp_reply(m->slirp, bp, m_end(m)); - } -} diff --git a/src/network/slirp/bootp.h b/src/network/slirp/bootp.h deleted file mode 100644 index cf7797facb..0000000000 --- a/src/network/slirp/bootp.h +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* bootp/dhcp defines */ - -#ifndef SLIRP_BOOTP_H -#define SLIRP_BOOTP_H - -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 - -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 - -#define RFC1533_COOKIE 99, 130, 83, 99 -#define RFC1533_PAD 0 -#define RFC1533_NETMASK 1 -#define RFC1533_TIMEOFFSET 2 -#define RFC1533_GATEWAY 3 -#define RFC1533_TIMESERVER 4 -#define RFC1533_IEN116NS 5 -#define RFC1533_DNS 6 -#define RFC1533_LOGSERVER 7 -#define RFC1533_COOKIESERVER 8 -#define RFC1533_LPRSERVER 9 -#define RFC1533_IMPRESSSERVER 10 -#define RFC1533_RESOURCESERVER 11 -#define RFC1533_HOSTNAME 12 -#define RFC1533_BOOTFILESIZE 13 -#define RFC1533_MERITDUMPFILE 14 -#define RFC1533_DOMAINNAME 15 -#define RFC1533_SWAPSERVER 16 -#define RFC1533_ROOTPATH 17 -#define RFC1533_EXTENSIONPATH 18 -#define RFC1533_IPFORWARDING 19 -#define RFC1533_IPSOURCEROUTING 20 -#define RFC1533_IPPOLICYFILTER 21 -#define RFC1533_IPMAXREASSEMBLY 22 -#define RFC1533_IPTTL 23 -#define RFC1533_IPMTU 24 -#define RFC1533_IPMTUPLATEAU 25 -#define RFC1533_INTMTU 26 -#define RFC1533_INTLOCALSUBNETS 27 -#define RFC1533_INTBROADCAST 28 -#define RFC1533_INTICMPDISCOVER 29 -#define RFC1533_INTICMPRESPOND 30 -#define RFC1533_INTROUTEDISCOVER 31 -#define RFC1533_INTROUTESOLICIT 32 -#define RFC1533_INTSTATICROUTES 33 -#define RFC1533_LLTRAILERENCAP 34 -#define RFC1533_LLARPCACHETMO 35 -#define RFC1533_LLETHERNETENCAP 36 -#define RFC1533_TCPTTL 37 -#define RFC1533_TCPKEEPALIVETMO 38 -#define RFC1533_TCPKEEPALIVEGB 39 -#define RFC1533_NISDOMAIN 40 -#define RFC1533_NISSERVER 41 -#define RFC1533_NTPSERVER 42 -#define RFC1533_VENDOR 43 -#define RFC1533_NBNS 44 -#define RFC1533_NBDD 45 -#define RFC1533_NBNT 46 -#define RFC1533_NBSCOPE 47 -#define RFC1533_XFS 48 -#define RFC1533_XDM 49 - -#define RFC2132_REQ_ADDR 50 -#define RFC2132_LEASE_TIME 51 -#define RFC2132_MSG_TYPE 53 -#define RFC2132_SRV_ID 54 -#define RFC2132_PARAM_LIST 55 -#define RFC2132_MESSAGE 56 -#define RFC2132_MAX_SIZE 57 -#define RFC2132_RENEWAL_TIME 58 -#define RFC2132_REBIND_TIME 59 -#define RFC2132_VENDOR_CLASS_ID 60 -#define RFC2132_TFTP_SERVER_NAME 66 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPACK 5 -#define DHCPNAK 6 - -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 - -#define RFC1533_VENDOR_MAGIC 128 -#define RFC1533_VENDOR_ADDPARM 129 -#define RFC1533_VENDOR_ETHDEV 130 -#define RFC1533_VENDOR_HOWTO 132 -#define RFC1533_VENDOR_MNUOPTS 160 -#define RFC1533_VENDOR_SELECTION 176 -#define RFC1533_VENDOR_MOTD 184 -#define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 - -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#define DHCP_OPT_LEN 312 - -struct bootp_t { - struct ip ip; - struct udphdr udp; - uint8_t bp_op; - uint8_t bp_htype; - uint8_t bp_hlen; - uint8_t bp_hops; - uint32_t bp_xid; - uint16_t bp_secs; - uint16_t unused; - struct in_addr bp_ciaddr; - struct in_addr bp_yiaddr; - struct in_addr bp_siaddr; - struct in_addr bp_giaddr; - uint8_t bp_hwaddr[16]; - uint8_t bp_sname[64]; - char bp_file[128]; - uint8_t bp_vend[]; -}; - -typedef struct { - uint16_t allocated; - uint8_t macaddr[6]; -} BOOTPClient; - -#define NB_BOOTP_CLIENTS 16 - -void bootp_input(struct mbuf *m); - -#endif diff --git a/src/network/slirp/cksum.c b/src/network/slirp/cksum.c deleted file mode 100644 index b1cb97b7e1..0000000000 --- a/src/network/slirp/cksum.c +++ /dev/null @@ -1,179 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1988, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 - * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp - */ - -#include "slirp.h" - -/* - * Checksum routine for Internet Protocol family headers (Portable Version). - * - * This routine is very heavily used in the network - * code and should be modified for each CPU to be as fast as possible. - * - * XXX Since we will never span more than 1 mbuf, we can optimise this - */ - -#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) -#define REDUCE \ - { \ - l_util.l = sum; \ - sum = l_util.s[0] + l_util.s[1]; \ - ADDCARRY(sum); \ - } - -int cksum(struct mbuf *m, int len) -{ - register uint16_t *w; - register int sum = 0; - register int mlen = 0; - int byte_swapped = 0; - - union { - uint8_t c[2]; - uint16_t s; - } s_util; - union { - uint16_t s[2]; - uint32_t l; - } l_util; - - if (m->m_len == 0) - goto cont; - w = mtod(m, uint16_t *); - - mlen = m->m_len; - - if (len < mlen) - mlen = len; - len -= mlen; - /* - * Force to even boundary. - */ - if ((1 & (uintptr_t)w) && (mlen > 0)) { - REDUCE; - sum <<= 8; - s_util.c[0] = *(uint8_t *)w; - w = (uint16_t *)((int8_t *)w + 1); - mlen--; - byte_swapped = 1; - } - /* - * Unroll the loop to make overhead from - * branches &c small. - */ - while ((mlen -= 32) >= 0) { - sum += w[0]; - sum += w[1]; - sum += w[2]; - sum += w[3]; - sum += w[4]; - sum += w[5]; - sum += w[6]; - sum += w[7]; - sum += w[8]; - sum += w[9]; - sum += w[10]; - sum += w[11]; - sum += w[12]; - sum += w[13]; - sum += w[14]; - sum += w[15]; - w += 16; - } - mlen += 32; - while ((mlen -= 8) >= 0) { - sum += w[0]; - sum += w[1]; - sum += w[2]; - sum += w[3]; - w += 4; - } - mlen += 8; - if (mlen == 0 && byte_swapped == 0) - goto cont; - REDUCE; - while ((mlen -= 2) >= 0) { - sum += *w++; - } - - if (byte_swapped) { - REDUCE; - sum <<= 8; - if (mlen == -1) { - s_util.c[1] = *(uint8_t *)w; - sum += s_util.s; - mlen = 0; - } else - - mlen = -1; - } else if (mlen == -1) - s_util.c[0] = *(uint8_t *)w; - -cont: - if (len) { - DEBUG_ERROR("cksum: out of data"); - DEBUG_ERROR(" len = %d", len); - } - if (mlen == -1) { - /* The last mbuf has odd # of bytes. Follow the - standard (the odd byte may be shifted left by 8 bits - or not as determined by endian-ness of the machine) */ - s_util.c[1] = 0; - sum += s_util.s; - } - REDUCE; - return (~sum & 0xffff); -} - -int ip6_cksum(struct mbuf *m) -{ - /* TODO: Optimize this by being able to pass the ip6_pseudohdr to cksum - * separately from the mbuf */ - struct ip6 save_ip, *ip = mtod(m, struct ip6 *); - struct ip6_pseudohdr *ih = mtod(m, struct ip6_pseudohdr *); - int sum; - - save_ip = *ip; - - ih->ih_src = save_ip.ip_src; - ih->ih_dst = save_ip.ip_dst; - ih->ih_pl = htonl((uint32_t)ntohs(save_ip.ip_pl)); - ih->ih_zero_hi = 0; - ih->ih_zero_lo = 0; - ih->ih_nh = save_ip.ip_nh; - - sum = cksum(m, ((int)sizeof(struct ip6_pseudohdr)) + ntohl(ih->ih_pl)); - - *ip = save_ip; - - return sum; -} diff --git a/src/network/slirp/debug.h b/src/network/slirp/debug.h deleted file mode 100644 index 0f9f3eff3f..0000000000 --- a/src/network/slirp/debug.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef DEBUG_H_ -#define DEBUG_H_ - -#define DBG_CALL (1 << 0) -#define DBG_MISC (1 << 1) -#define DBG_ERROR (1 << 2) -#define DBG_TFTP (1 << 3) -#define DBG_VERBOSE_CALL (1 << 4) - -extern int slirp_debug; - -#define DEBUG_CALL(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \ - g_debug(fmt "...", ##__VA_ARGS__); \ - } \ - } while (0) - -#define DEBUG_VERBOSE_CALL(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_VERBOSE_CALL)) { \ - g_debug(fmt "...", ##__VA_ARGS__); \ - } \ - } while (0) - -#define DEBUG_ARG(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \ - g_debug(" " fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#define DEBUG_MISC(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_MISC)) { \ - g_debug(fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#define DEBUG_ERROR(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_ERROR)) { \ - g_debug(fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#define DEBUG_TFTP(fmt, ...) \ - do { \ - if (G_UNLIKELY(slirp_debug & DBG_TFTP)) { \ - g_debug(fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#endif /* DEBUG_H_ */ diff --git a/src/network/slirp/dhcpv6.c b/src/network/slirp/dhcpv6.c deleted file mode 100644 index 77b451b910..0000000000 --- a/src/network/slirp/dhcpv6.c +++ /dev/null @@ -1,224 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * SLIRP stateless DHCPv6 - * - * We only support stateless DHCPv6, e.g. for network booting. - * See RFC 3315, RFC 3736, RFC 3646 and RFC 5970 for details. - * - * Copyright 2016 Thomas Huth, Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "slirp.h" -#include "dhcpv6.h" - -/* DHCPv6 message types */ -#define MSGTYPE_REPLY 7 -#define MSGTYPE_INFO_REQUEST 11 - -/* DHCPv6 option types */ -#define OPTION_CLIENTID 1 -#define OPTION_IAADDR 5 -#define OPTION_ORO 6 -#define OPTION_DNS_SERVERS 23 -#define OPTION_BOOTFILE_URL 59 - -struct requested_infos { - uint8_t *client_id; - int client_id_len; - bool want_dns; - bool want_boot_url; -}; - -/** - * Analyze the info request message sent by the client to see what data it - * provided and what it wants to have. The information is gathered in the - * "requested_infos" struct. Note that client_id (if provided) points into - * the odata region, thus the caller must keep odata valid as long as it - * needs to access the requested_infos struct. - */ -static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t *odata, int olen, - struct requested_infos *ri) -{ - int i, req_opt; - - while (olen > 4) { - /* Parse one option */ - int option = odata[0] << 8 | odata[1]; - int len = odata[2] << 8 | odata[3]; - - if (len + 4 > olen) { - slirp->cb->guest_error("Guest sent bad DHCPv6 packet!", - slirp->opaque); - return -E2BIG; - } - - switch (option) { - case OPTION_IAADDR: - /* According to RFC3315, we must discard requests with IA option */ - return -EINVAL; - case OPTION_CLIENTID: - if (len > 256) { - /* Avoid very long IDs which could cause problems later */ - return -E2BIG; - } - ri->client_id = odata + 4; - ri->client_id_len = len; - break; - case OPTION_ORO: /* Option request option */ - if (len & 1) { - return -EINVAL; - } - /* Check which options the client wants to have */ - for (i = 0; i < len; i += 2) { - req_opt = odata[4 + i] << 8 | odata[4 + i + 1]; - switch (req_opt) { - case OPTION_DNS_SERVERS: - ri->want_dns = true; - break; - case OPTION_BOOTFILE_URL: - ri->want_boot_url = true; - break; - default: - DEBUG_MISC("dhcpv6: Unsupported option request %d", - req_opt); - } - } - break; - default: - DEBUG_MISC("dhcpv6 info req: Unsupported option %d, len=%d", option, - len); - } - - odata += len + 4; - olen -= len + 4; - } - - return 0; -} - - -/** - * Handle information request messages - */ -static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas, - uint32_t xid, uint8_t *odata, int olen) -{ - struct requested_infos ri = { NULL }; - struct sockaddr_in6 sa6, da6; - struct mbuf *m; - uint8_t *resp; - - if (dhcpv6_parse_info_request(slirp, odata, olen, &ri) < 0) { - return; - } - - m = m_get(slirp); - if (!m) { - return; - } - memset(m->m_data, 0, m->m_size); - m->m_data += IF_MAXLINKHDR; - resp = (uint8_t *)m->m_data + sizeof(struct ip6) + sizeof(struct udphdr); - - /* Fill in response */ - *resp++ = MSGTYPE_REPLY; - *resp++ = (uint8_t)(xid >> 16); - *resp++ = (uint8_t)(xid >> 8); - *resp++ = (uint8_t)xid; - - if (ri.client_id) { - *resp++ = OPTION_CLIENTID >> 8; /* option-code high byte */ - *resp++ = OPTION_CLIENTID; /* option-code low byte */ - *resp++ = ri.client_id_len >> 8; /* option-len high byte */ - *resp++ = ri.client_id_len; /* option-len low byte */ - memcpy(resp, ri.client_id, ri.client_id_len); - resp += ri.client_id_len; - } - if (ri.want_dns) { - *resp++ = OPTION_DNS_SERVERS >> 8; /* option-code high byte */ - *resp++ = OPTION_DNS_SERVERS; /* option-code low byte */ - *resp++ = 0; /* option-len high byte */ - *resp++ = 16; /* option-len low byte */ - memcpy(resp, &slirp->vnameserver_addr6, 16); - resp += 16; - } - if (ri.want_boot_url) { - uint8_t *sa = slirp->vhost_addr6.s6_addr; - int slen, smaxlen; - - *resp++ = OPTION_BOOTFILE_URL >> 8; /* option-code high byte */ - *resp++ = OPTION_BOOTFILE_URL; /* option-code low byte */ - smaxlen = (uint8_t *)m->m_data + slirp->if_mtu - (resp + 2); - slen = slirp_fmt((char *)resp + 2, smaxlen, - "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" - "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s", - sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7], - sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14], - sa[15], slirp->bootp_filename); - *resp++ = slen >> 8; /* option-len high byte */ - *resp++ = slen; /* option-len low byte */ - resp += slen; - } - - sa6.sin6_addr = slirp->vhost_addr6; - sa6.sin6_port = DHCPV6_SERVER_PORT; - da6.sin6_addr = srcsas->sin6_addr; - da6.sin6_port = srcsas->sin6_port; - m->m_data += sizeof(struct ip6) + sizeof(struct udphdr); - m->m_len = resp - (uint8_t *)m->m_data; - udp6_output(NULL, m, &sa6, &da6); -} - -/** - * Handle DHCPv6 messages sent by the client - */ -void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m) -{ - uint8_t *data = (uint8_t *)m->m_data + sizeof(struct udphdr); - int data_len = m->m_len - sizeof(struct udphdr); - uint32_t xid; - - if (data_len < 4) { - return; - } - - xid = ntohl(*(uint32_t *)data) & 0xffffff; - - switch (data[0]) { - case MSGTYPE_INFO_REQUEST: - dhcpv6_info_request(m->slirp, srcsas, xid, &data[4], data_len - 4); - break; - default: - DEBUG_MISC("dhcpv6_input: Unsupported message type 0x%x", data[0]); - } -} diff --git a/src/network/slirp/dhcpv6.h b/src/network/slirp/dhcpv6.h deleted file mode 100644 index d12c49b36c..0000000000 --- a/src/network/slirp/dhcpv6.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Definitions and prototypes for SLIRP stateless DHCPv6 - * - * Copyright 2016 Thomas Huth, Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef SLIRP_DHCPV6_H -#define SLIRP_DHCPV6_H - -#define DHCPV6_SERVER_PORT 547 - -#define ALLDHCP_MULTICAST \ - { \ - .s6_addr = { \ - 0xff, \ - 0x02, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x01, \ - 0x00, \ - 0x02 \ - } \ - } - -#define in6_dhcp_multicast(a) in6_equal(a, &(struct in6_addr)ALLDHCP_MULTICAST) - -void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m); - -#endif diff --git a/src/network/slirp/dnssearch.c b/src/network/slirp/dnssearch.c deleted file mode 100644 index 55497e860e..0000000000 --- a/src/network/slirp/dnssearch.c +++ /dev/null @@ -1,306 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Domain search option for DHCP (RFC 3397) - * - * Copyright (c) 2012 Klaus Stengel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "slirp.h" - -static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119; -static const uint8_t MAX_OPT_LEN = 255; -static const uint8_t OPT_HEADER_LEN = 2; -static const uint8_t REFERENCE_LEN = 2; - -struct compact_domain; - -typedef struct compact_domain { - struct compact_domain *self; - struct compact_domain *refdom; - uint8_t *labels; - size_t len; - size_t common_octets; -} CompactDomain; - -static size_t domain_suffix_diffoff(const CompactDomain *a, - const CompactDomain *b) -{ - size_t la = a->len, lb = b->len; - uint8_t *da = a->labels + la, *db = b->labels + lb; - size_t i, lm = (la < lb) ? la : lb; - - for (i = 0; i < lm; i++) { - da--; - db--; - if (*da != *db) { - break; - } - } - return i; -} - -static int domain_suffix_ord(const void *cva, const void *cvb) -{ - const CompactDomain *a = cva, *b = cvb; - size_t la = a->len, lb = b->len; - size_t doff = domain_suffix_diffoff(a, b); - uint8_t ca = a->labels[la - doff]; - uint8_t cb = b->labels[lb - doff]; - - if (ca < cb) { - return -1; - } - if (ca > cb) { - return 1; - } - if (la < lb) { - return -1; - } - if (la > lb) { - return 1; - } - return 0; -} - -static size_t domain_common_label(CompactDomain *a, CompactDomain *b) -{ - size_t res, doff = domain_suffix_diffoff(a, b); - uint8_t *first_eq_pos = a->labels + (a->len - doff); - uint8_t *label = a->labels; - - while (*label && label < first_eq_pos) { - label += *label + 1; - } - res = a->len - (label - a->labels); - /* only report if it can help to reduce the packet size */ - return (res > REFERENCE_LEN) ? res : 0; -} - -static void domain_fixup_order(CompactDomain *cd, size_t n) -{ - size_t i; - - for (i = 0; i < n; i++) { - CompactDomain *cur = cd + i, *next = cd[i].self; - - while (!cur->common_octets) { - CompactDomain *tmp = next->self; /* backup target value */ - - next->self = cur; - cur->common_octets++; - - cur = next; - next = tmp; - } - } -} - -static void domain_mklabels(CompactDomain *cd, const char *input) -{ - uint8_t *len_marker = cd->labels; - uint8_t *output = len_marker; /* pre-incremented */ - const char *in = input; - char cur_chr; - size_t len = 0; - - if (cd->len == 0) { - goto fail; - } - cd->len++; - - do { - cur_chr = *in++; - if (cur_chr == '.' || cur_chr == '\0') { - len = output - len_marker; - if ((len == 0 && cur_chr == '.') || len >= 64) { - goto fail; - } - *len_marker = len; - - output++; - len_marker = output; - } else { - output++; - *output = cur_chr; - } - } while (cur_chr != '\0'); - - /* ensure proper zero-termination */ - if (len != 0) { - *len_marker = 0; - cd->len++; - } - return; - -fail: - g_warning("failed to parse domain name '%s'\n", input); - cd->len = 0; -} - -static void domain_mkxrefs(CompactDomain *doms, CompactDomain *last, - size_t depth) -{ - CompactDomain *i = doms, *target = doms; - - do { - if (i->labels < target->labels) { - target = i; - } - } while (i++ != last); - - for (i = doms; i != last; i++) { - CompactDomain *group_last; - size_t next_depth; - - if (i->common_octets == depth) { - continue; - } - - next_depth = -1; - for (group_last = i; group_last != last; group_last++) { - size_t co = group_last->common_octets; - if (co <= depth) { - break; - } - if (co < next_depth) { - next_depth = co; - } - } - domain_mkxrefs(i, group_last, next_depth); - - i = group_last; - if (i == last) { - break; - } - } - - if (depth == 0) { - return; - } - - i = doms; - do { - if (i != target && i->refdom == NULL) { - i->refdom = target; - i->common_octets = depth; - } - } while (i++ != last); -} - -static size_t domain_compactify(CompactDomain *domains, size_t n) -{ - uint8_t *start = domains->self->labels, *outptr = start; - size_t i; - - for (i = 0; i < n; i++) { - CompactDomain *cd = domains[i].self; - CompactDomain *rd = cd->refdom; - - if (rd != NULL) { - size_t moff = (rd->labels - start) + (rd->len - cd->common_octets); - if (moff < 0x3FFFu) { - cd->len -= cd->common_octets - 2; - cd->labels[cd->len - 1] = moff & 0xFFu; - cd->labels[cd->len - 2] = 0xC0u | (moff >> 8); - } - } - - if (cd->labels != outptr) { - memmove(outptr, cd->labels, cd->len); - cd->labels = outptr; - } - outptr += cd->len; - } - return outptr - start; -} - -int translate_dnssearch(Slirp *s, const char **names) -{ - size_t blocks, bsrc_start, bsrc_end, bdst_start; - size_t i, num_domains, memreq = 0; - uint8_t *result = NULL, *outptr; - CompactDomain *domains = NULL; - - num_domains = g_strv_length((GStrv)(void *)names); - if (num_domains == 0) { - return -2; - } - - domains = g_malloc(num_domains * sizeof(*domains)); - - for (i = 0; i < num_domains; i++) { - size_t nlen = strlen(names[i]); - memreq += nlen + 2; /* 1 zero octet + 1 label length octet */ - domains[i].self = domains + i; - domains[i].len = nlen; - domains[i].common_octets = 0; - domains[i].refdom = NULL; - } - - /* reserve extra 2 header bytes for each 255 bytes of output */ - memreq += DIV_ROUND_UP(memreq, MAX_OPT_LEN) * OPT_HEADER_LEN; - result = g_malloc(memreq * sizeof(*result)); - - outptr = result; - for (i = 0; i < num_domains; i++) { - domains[i].labels = outptr; - domain_mklabels(domains + i, names[i]); - outptr += domains[i].len; - } - - if (outptr == result) { - g_free(domains); - g_free(result); - return -1; - } - - qsort(domains, num_domains, sizeof(*domains), domain_suffix_ord); - domain_fixup_order(domains, num_domains); - - for (i = 1; i < num_domains; i++) { - size_t cl = domain_common_label(domains + i - 1, domains + i); - domains[i - 1].common_octets = cl; - } - - domain_mkxrefs(domains, domains + num_domains - 1, 0); - memreq = domain_compactify(domains, num_domains); - - blocks = DIV_ROUND_UP(memreq, MAX_OPT_LEN); - bsrc_end = memreq; - bsrc_start = (blocks - 1) * MAX_OPT_LEN; - bdst_start = bsrc_start + blocks * OPT_HEADER_LEN; - memreq += blocks * OPT_HEADER_LEN; - - while (blocks--) { - size_t len = bsrc_end - bsrc_start; - memmove(result + bdst_start, result + bsrc_start, len); - result[bdst_start - 2] = RFC3397_OPT_DOMAIN_SEARCH; - result[bdst_start - 1] = len; - bsrc_end = bsrc_start; - bsrc_start -= MAX_OPT_LEN; - bdst_start -= MAX_OPT_LEN + OPT_HEADER_LEN; - } - - g_free(domains); - s->vdnssearch = result; - s->vdnssearch_len = memreq; - return 0; -} diff --git a/src/network/slirp/if.c b/src/network/slirp/if.c deleted file mode 100644 index 741473dc4b..0000000000 --- a/src/network/slirp/if.c +++ /dev/null @@ -1,216 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" - -static void ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead) -{ - ifm->ifs_next = ifmhead->ifs_next; - ifmhead->ifs_next = ifm; - ifm->ifs_prev = ifmhead; - ifm->ifs_next->ifs_prev = ifm; -} - -static void ifs_remque(struct mbuf *ifm) -{ - ifm->ifs_prev->ifs_next = ifm->ifs_next; - ifm->ifs_next->ifs_prev = ifm->ifs_prev; -} - -void if_init(Slirp *slirp) -{ - slirp->if_fastq.qh_link = slirp->if_fastq.qh_rlink = &slirp->if_fastq; - slirp->if_batchq.qh_link = slirp->if_batchq.qh_rlink = &slirp->if_batchq; -} - -/* - * if_output: Queue packet into an output queue. - * There are 2 output queue's, if_fastq and if_batchq. - * Each output queue is a doubly linked list of double linked lists - * of mbufs, each list belonging to one "session" (socket). This - * way, we can output packets fairly by sending one packet from each - * session, instead of all the packets from one session, then all packets - * from the next session, etc. Packets on the if_fastq get absolute - * priority, but if one session hogs the link, it gets "downgraded" - * to the batchq until it runs out of packets, then it'll return - * to the fastq (eg. if the user does an ls -alR in a telnet session, - * it'll temporarily get downgraded to the batchq) - */ -void if_output(struct socket *so, struct mbuf *ifm) -{ - Slirp *slirp = ifm->slirp; - M_DUP_DEBUG(slirp, ifm, 0, 0); - - struct mbuf *ifq; - int on_fastq = 1; - - DEBUG_CALL("if_output"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("ifm = %p", ifm); - - /* - * First remove the mbuf from m_usedlist, - * since we're gonna use m_next and m_prev ourselves - * XXX Shouldn't need this, gotta change dtom() etc. - */ - if (ifm->m_flags & M_USEDLIST) { - slirp_remque(ifm); - ifm->m_flags &= ~M_USEDLIST; - } - - /* - * See if there's already a batchq list for this session. - * This can include an interactive session, which should go on fastq, - * but gets too greedy... hence it'll be downgraded from fastq to batchq. - * We mustn't put this packet back on the fastq (or we'll send it out of - * order) - * XXX add cache here? - */ - if (so) { - for (ifq = (struct mbuf *)slirp->if_batchq.qh_rlink; - (struct slirp_quehead *)ifq != &slirp->if_batchq; - ifq = ifq->ifq_prev) { - if (so == ifq->ifq_so) { - /* A match! */ - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } - } - - /* No match, check which queue to put it on */ - if (so && (so->so_iptos & IPTOS_LOWDELAY)) { - ifq = (struct mbuf *)slirp->if_fastq.qh_rlink; - on_fastq = 1; - /* - * Check if this packet is a part of the last - * packet's session - */ - if (ifq->ifq_so == so) { - ifm->ifq_so = so; - ifs_insque(ifm, ifq->ifs_prev); - goto diddit; - } - } else { - ifq = (struct mbuf *)slirp->if_batchq.qh_rlink; - } - - /* Create a new doubly linked list for this session */ - ifm->ifq_so = so; - ifs_init(ifm); - slirp_insque(ifm, ifq); - -diddit: - if (so) { - /* Update *_queued */ - so->so_queued++; - so->so_nqueued++; - /* - * Check if the interactive session should be downgraded to - * the batchq. A session is downgraded if it has queued 6 - * packets without pausing, and at least 3 of those packets - * have been sent over the link - * (XXX These are arbitrary numbers, probably not optimal..) - */ - if (on_fastq && - ((so->so_nqueued >= 6) && (so->so_nqueued - so->so_queued) >= 3)) { - /* Remove from current queue... */ - slirp_remque(ifm->ifs_next); - - /* ...And insert in the new. That'll teach ya! */ - slirp_insque(ifm->ifs_next, &slirp->if_batchq); - } - } - - /* - * This prevents us from malloc()ing too many mbufs - */ - if_start(ifm->slirp); -} - -/* - * Send one packet from each session. - * If there are packets on the fastq, they are sent FIFO, before - * everything else. Then we choose the first packet from each - * batchq session (socket) and send it. - * For example, if there are 3 ftp sessions fighting for bandwidth, - * one packet will be sent from the first session, then one packet - * from the second session, then one packet from the third. - */ -void if_start(Slirp *slirp) -{ - uint64_t now = slirp->cb->clock_get_ns(slirp->opaque); - bool from_batchq = false; - struct mbuf *ifm, *ifm_next, *ifqt; - - DEBUG_VERBOSE_CALL("if_start"); - - if (slirp->if_start_busy) { - return; - } - slirp->if_start_busy = true; - - struct mbuf *batch_head = NULL; - if (slirp->if_batchq.qh_link != &slirp->if_batchq) { - batch_head = (struct mbuf *)slirp->if_batchq.qh_link; - } - - if (slirp->if_fastq.qh_link != &slirp->if_fastq) { - ifm_next = (struct mbuf *)slirp->if_fastq.qh_link; - } else if (batch_head) { - /* Nothing on fastq, pick up from batchq */ - ifm_next = batch_head; - from_batchq = true; - } else { - ifm_next = NULL; - } - - while (ifm_next) { - ifm = ifm_next; - - ifm_next = ifm->ifq_next; - if ((struct slirp_quehead *)ifm_next == &slirp->if_fastq) { - /* No more packets in fastq, switch to batchq */ - ifm_next = batch_head; - from_batchq = true; - } - if ((struct slirp_quehead *)ifm_next == &slirp->if_batchq) { - /* end of batchq */ - ifm_next = NULL; - } - - /* Try to send packet unless it already expired */ - if (ifm->expiration_date >= now && !if_encap(slirp, ifm)) { - /* Packet is delayed due to pending ARP or NDP resolution */ - continue; - } - - /* Remove it from the queue */ - ifqt = ifm->ifq_prev; - slirp_remque(ifm); - - /* If there are more packets for this session, re-queue them */ - if (ifm->ifs_next != ifm) { - struct mbuf *next = ifm->ifs_next; - - slirp_insque(next, ifqt); - ifs_remque(ifm); - if (!from_batchq) { - ifm_next = next; - } - } - - /* Update so_queued */ - if (ifm->ifq_so && --ifm->ifq_so->so_queued == 0) { - /* If there's no more queued, reset nqueued */ - ifm->ifq_so->so_nqueued = 0; - } - - m_free(ifm); - } - - slirp->if_start_busy = false; -} diff --git a/src/network/slirp/if.h b/src/network/slirp/if.h deleted file mode 100644 index 7cf9d2750e..0000000000 --- a/src/network/slirp/if.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef IF_H -#define IF_H - -#define IF_COMPRESS 0x01 /* We want compression */ -#define IF_NOCOMPRESS 0x02 /* Do not do compression */ -#define IF_AUTOCOMP 0x04 /* Autodetect (default) */ -#define IF_NOCIDCOMP 0x08 /* CID compression */ - -#define IF_MTU_DEFAULT 1500 -#define IF_MTU_MIN 68 -#define IF_MTU_MAX 65521 -#define IF_MRU_DEFAULT 1500 -#define IF_MRU_MIN 68 -#define IF_MRU_MAX 65521 -#define IF_COMP IF_AUTOCOMP /* Flags for compression */ - -/* 2 for alignment, 14 for ethernet */ -#define IF_MAXLINKHDR (2 + ETH_HLEN) - -#endif diff --git a/src/network/slirp/ip.h b/src/network/slirp/ip.h deleted file mode 100644 index c4203f6358..0000000000 --- a/src/network/slirp/ip.h +++ /dev/null @@ -1,272 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip.h 8.1 (Berkeley) 6/10/93 - * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp - */ - -#ifndef IP_H -#define IP_H - -#include - -#if G_BYTE_ORDER == G_BIG_ENDIAN -#undef NTOHL -#undef NTOHS -#undef HTONL -#undef HTONS -#define NTOHL(d) -#define NTOHS(d) -#define HTONL(d) -#define HTONS(d) -#else -#ifndef NTOHL -#define NTOHL(d) ((d) = ntohl((d))) -#endif -#ifndef NTOHS -#define NTOHS(d) ((d) = ntohs((uint16_t)(d))) -#endif -#ifndef HTONL -#define HTONL(d) ((d) = htonl((d))) -#endif -#ifndef HTONS -#define HTONS(d) ((d) = htons((uint16_t)(d))) -#endif -#endif - -typedef uint32_t n_long; /* long as received from the net */ - -/* - * Definitions for internet protocol version 4. - * Per RFC 791, September 1981. - */ -#define IPVERSION 4 - -/* - * Structure of an internet header, naked of options. - */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ip { -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint8_t ip_v : 4, /* version */ - ip_hl : 4; /* header length */ -#else - uint8_t ip_hl : 4, /* header length */ - ip_v : 4; /* version */ -#endif - uint8_t ip_tos; /* type of service */ - uint16_t ip_len; /* total length */ - uint16_t ip_id; /* identification */ - uint16_t ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* don't fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - uint8_t ip_ttl; /* time to live */ - uint8_t ip_p; /* protocol */ - uint16_t ip_sum; /* checksum */ - struct in_addr ip_src, ip_dst; /* source and dest address */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#define IP_MAXPACKET 65535 /* maximum packet size */ - -/* - * Definitions for IP type of service (ip_tos) - */ -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 - -/* - * Definitions for options. - */ -#define IPOPT_COPIED(o) ((o)&0x80) -#define IPOPT_CLASS(o) ((o)&0x60) -#define IPOPT_NUMBER(o) ((o)&0x1f) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_DEBMEAS 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_EOL 0 /* end of option list */ -#define IPOPT_NOP 1 /* no operation */ - -#define IPOPT_RR 7 /* record packet route */ -#define IPOPT_TS 68 /* timestamp */ -#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ -#define IPOPT_LSRR 131 /* loose source route */ -#define IPOPT_SATID 136 /* satnet id */ -#define IPOPT_SSRR 137 /* strict source route */ - -/* - * Offsets to fields in options other than EOL and NOP. - */ -#define IPOPT_OPTVAL 0 /* option ID */ -#define IPOPT_OLEN 1 /* option length */ -#define IPOPT_OFFSET 2 /* offset within option */ -#define IPOPT_MINOFF 4 /* min value of above */ - -/* - * Time stamp option structure. - */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ip_timestamp { - uint8_t ipt_code; /* IPOPT_TS */ - uint8_t ipt_len; /* size of structure (variable) */ - uint8_t ipt_ptr; /* index of current entry */ -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint8_t ipt_oflw : 4, /* overflow counter */ - ipt_flg : 4; /* flags, see below */ -#else - uint8_t ipt_flg : 4, /* flags, see below */ - ipt_oflw : 4; /* overflow counter */ -#endif - union ipt_timestamp { - n_long ipt_time[1]; - struct ipt_ta { - struct in_addr ipt_addr; - n_long ipt_time; - } ipt_ta[1]; - } ipt_timestamp; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* flag bits for ipt_flg */ -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -/* bits for security (not byte swapped) */ -#define IPOPT_SECUR_UNCLASS 0x0000 -#define IPOPT_SECUR_CONFID 0xf135 -#define IPOPT_SECUR_EFTO 0x789a -#define IPOPT_SECUR_MMMM 0xbc4d -#define IPOPT_SECUR_RESTR 0xaf13 -#define IPOPT_SECUR_SECRET 0xd788 -#define IPOPT_SECUR_TOPSECRET 0x6bc5 - -/* - * Internet implementation parameters. - */ -#define MAXTTL 255 /* maximum time to live (seconds) */ -#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ -#define IPFRAGTTL 60 /* time to live for frags, slowhz */ -#define IPTTLDEC 1 /* subtracted when forwarding */ - -#define IP_MSS 576 /* default maximum segment size */ - -#if GLIB_SIZEOF_VOID_P == 4 -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct mbuf_ptr { - struct mbuf *mptr; - uint32_t dummy; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif -#else -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct mbuf_ptr { - struct mbuf *mptr; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif -#endif -struct qlink { - void *next, *prev; -}; - -/* - * Overlay for ip header used by other protocols (tcp, udp). - */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ipovly { - struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ - uint8_t ih_x1; /* (unused) */ - uint8_t ih_pr; /* protocol */ - uint16_t ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* - * Ip reassembly queue structure. Each fragment - * being reassembled is attached to one of these structures. - * They are timed out after ipq_ttl drops to 0, and may also - * be reclaimed if memory becomes tight. - * size 28 bytes - */ -struct ipq { - struct qlink frag_link; /* to ip headers of fragments */ - struct qlink ip_link; /* to other reass headers */ - uint8_t ipq_ttl; /* time for reass q to live */ - uint8_t ipq_p; /* protocol of this fragment */ - uint16_t ipq_id; /* sequence id for reassembly */ - struct in_addr ipq_src, ipq_dst; -}; - -/* - * Ip header, when holding a fragment. - * - * Note: ipf_link must be at same offset as frag_link above - */ -struct ipasfrag { - struct qlink ipf_link; - struct ip ipf_ip; -}; - -G_STATIC_ASSERT(offsetof(struct ipq, frag_link) == - offsetof(struct ipasfrag, ipf_link)); - -#define ipf_off ipf_ip.ip_off -#define ipf_tos ipf_ip.ip_tos -#define ipf_len ipf_ip.ip_len -#define ipf_next ipf_link.next -#define ipf_prev ipf_link.prev - -#endif diff --git a/src/network/slirp/ip6.h b/src/network/slirp/ip6.h deleted file mode 100644 index 73a00b1140..0000000000 --- a/src/network/slirp/ip6.h +++ /dev/null @@ -1,214 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#ifndef SLIRP_IP6_H -#define SLIRP_IP6_H - -#include -#include - -#define ALLNODES_MULTICAST \ - { \ - .s6_addr = { \ - 0xff, \ - 0x02, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x01 \ - } \ - } - -#define SOLICITED_NODE_PREFIX \ - { \ - .s6_addr = { \ - 0xff, \ - 0x02, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x01, \ - 0xff, \ - 0x00, \ - 0x00, \ - 0x00 \ - } \ - } - -#define LINKLOCAL_ADDR \ - { \ - .s6_addr = { \ - 0xfe, \ - 0x80, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x02 \ - } \ - } - -#define ZERO_ADDR \ - { \ - .s6_addr = { \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00, \ - 0x00 \ - } \ - } - -static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b) -{ - return memcmp(a, b, sizeof(*a)) == 0; -} - -static inline bool in6_equal_net(const struct in6_addr *a, - const struct in6_addr *b, int prefix_len) -{ - if (memcmp(a, b, prefix_len / 8) != 0) { - return 0; - } - - if (prefix_len % 8 == 0) { - return 1; - } - - return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8)) == - b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8)); -} - -static inline bool in6_equal_mach(const struct in6_addr *a, - const struct in6_addr *b, int prefix_len) -{ - if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]), - &(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]), - 16 - DIV_ROUND_UP(prefix_len, 8)) != 0) { - return 0; - } - - if (prefix_len % 8 == 0) { - return 1; - } - - return (a->s6_addr[prefix_len / 8] & - ((1U << (8 - (prefix_len % 8))) - 1)) == - (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1)); -} - - -#define in6_equal_router(a) \ - ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \ - in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len)) || \ - (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \ - in6_equal_mach(a, &slirp->vhost_addr6, 64))) - -#define in6_equal_dns(a) \ - ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \ - in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len)) || \ - (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \ - in6_equal_mach(a, &slirp->vnameserver_addr6, 64))) - -#define in6_equal_host(a) (in6_equal_router(a) || in6_equal_dns(a)) - -#define in6_solicitednode_multicast(a) \ - (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104)) - -#define in6_zero(a) (in6_equal(a, &(struct in6_addr)ZERO_ADDR)) - -/* Compute emulated host MAC address from its ipv6 address */ -static inline void in6_compute_ethaddr(struct in6_addr ip, - uint8_t eth[ETH_ALEN]) -{ - eth[0] = 0x52; - eth[1] = 0x56; - memcpy(ð[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2); -} - -/* - * Definitions for internet protocol version 6. - * Per RFC 2460, December 1998. - */ -#define IP6VERSION 6 -#define IP6_HOP_LIMIT 255 - -/* - * Structure of an internet header, naked of options. - */ -struct ip6 { -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint32_t ip_v : 4, /* version */ - ip_tc_hi : 4, /* traffic class */ - ip_tc_lo : 4, ip_fl_hi : 4, /* flow label */ - ip_fl_lo : 16; -#else - uint32_t ip_tc_hi : 4, ip_v : 4, ip_fl_hi : 4, ip_tc_lo : 4, ip_fl_lo : 16; -#endif - uint16_t ip_pl; /* payload length */ - uint8_t ip_nh; /* next header */ - uint8_t ip_hl; /* hop limit */ - struct in6_addr ip_src, ip_dst; /* source and dest address */ -}; - -/* - * IPv6 pseudo-header used by upper-layer protocols - */ -struct ip6_pseudohdr { - struct in6_addr ih_src; /* source internet address */ - struct in6_addr ih_dst; /* destination internet address */ - uint32_t ih_pl; /* upper-layer packet length */ - uint16_t ih_zero_hi; /* zero */ - uint8_t ih_zero_lo; /* zero */ - uint8_t ih_nh; /* next header */ -}; - -/* - * We don't want to mark these ip6 structs as packed as they are naturally - * correctly aligned; instead assert that there is no stray padding. - * If we marked the struct as packed then we would be unable to take - * the address of any of the fields in it. - */ -G_STATIC_ASSERT(sizeof(struct ip6) == 40); -G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40); - -#endif diff --git a/src/network/slirp/ip6_icmp.c b/src/network/slirp/ip6_icmp.c deleted file mode 100644 index 0d7ee69caa..0000000000 --- a/src/network/slirp/ip6_icmp.c +++ /dev/null @@ -1,442 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#include "slirp.h" -#include "ip6_icmp.h" - -#define NDP_Interval \ - g_rand_int_range(slirp->grand, NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval) - -void icmp6_post_init(Slirp *slirp) -{ - if (!slirp->in6_enabled) { - return; - } - - slirp->ra_timer = - slirp_timer_new(slirp, SLIRP_TIMER_RA, NULL); - slirp->cb->timer_mod(slirp->ra_timer, - slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + - NDP_Interval, - slirp->opaque); -} - -void icmp6_cleanup(Slirp *slirp) -{ - if (!slirp->in6_enabled) { - return; - } - - slirp->cb->timer_free(slirp->ra_timer, slirp->opaque); -} - -static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip, - struct icmp6 *icmp) -{ - struct mbuf *t = m_get(slirp); - t->m_len = sizeof(struct ip6) + ntohs(ip->ip_pl); - memcpy(t->m_data, m->m_data, t->m_len); - - /* IPv6 Packet */ - struct ip6 *rip = mtod(t, struct ip6 *); - rip->ip_dst = ip->ip_src; - rip->ip_src = ip->ip_dst; - - /* ICMPv6 packet */ - t->m_data += sizeof(struct ip6); - struct icmp6 *ricmp = mtod(t, struct icmp6 *); - ricmp->icmp6_type = ICMP6_ECHO_REPLY; - ricmp->icmp6_cksum = 0; - - /* Checksum */ - t->m_data -= sizeof(struct ip6); - ricmp->icmp6_cksum = ip6_cksum(t); - - ip6_output(NULL, t, 0); -} - -void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src) -{ - Slirp *slirp = m->slirp; - struct mbuf *t; - struct ip6 *ip = mtod(m, struct ip6 *); - char addrstr[INET6_ADDRSTRLEN]; - - DEBUG_CALL("icmp6_send_error"); - DEBUG_ARG("type = %d, code = %d", type, code); - - if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) || in6_zero(&ip->ip_src)) { - /* TODO icmp error? */ - return; - } - - t = m_get(slirp); - - /* IPv6 packet */ - struct ip6 *rip = mtod(t, struct ip6 *); - rip->ip_src = *src; - rip->ip_dst = ip->ip_src; - inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN); - DEBUG_ARG("target = %s", addrstr); - - rip->ip_nh = IPPROTO_ICMPV6; - const int error_data_len = MIN( - m->m_len, slirp->if_mtu - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN)); - rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len); - t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl); - - /* ICMPv6 packet */ - t->m_data += sizeof(struct ip6); - struct icmp6 *ricmp = mtod(t, struct icmp6 *); - ricmp->icmp6_type = type; - ricmp->icmp6_code = code; - ricmp->icmp6_cksum = 0; - - switch (type) { - case ICMP6_UNREACH: - case ICMP6_TIMXCEED: - ricmp->icmp6_err.unused = 0; - break; - case ICMP6_TOOBIG: - ricmp->icmp6_err.mtu = htonl(slirp->if_mtu); - break; - case ICMP6_PARAMPROB: - /* TODO: Handle this case */ - break; - default: - g_assert_not_reached(); - } - t->m_data += ICMP6_ERROR_MINLEN; - memcpy(t->m_data, m->m_data, error_data_len); - - /* Checksum */ - t->m_data -= ICMP6_ERROR_MINLEN; - t->m_data -= sizeof(struct ip6); - ricmp->icmp6_cksum = ip6_cksum(t); - - ip6_output(NULL, t, 0); -} - -void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code) -{ - struct in6_addr src = LINKLOCAL_ADDR; - icmp6_forward_error(m, type, code, &src); -} - -/* - * Send NDP Router Advertisement - */ -static void ndp_send_ra(Slirp *slirp) -{ - DEBUG_CALL("ndp_send_ra"); - - /* Build IPv6 packet */ - struct mbuf *t = m_get(slirp); - struct ip6 *rip = mtod(t, struct ip6 *); - size_t pl_size = 0; - struct in6_addr addr; - uint32_t scope_id; - - rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR; - rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST; - rip->ip_nh = IPPROTO_ICMPV6; - - /* Build ICMPv6 packet */ - t->m_data += sizeof(struct ip6); - struct icmp6 *ricmp = mtod(t, struct icmp6 *); - ricmp->icmp6_type = ICMP6_NDP_RA; - ricmp->icmp6_code = 0; - ricmp->icmp6_cksum = 0; - - /* NDP */ - ricmp->icmp6_nra.chl = NDP_AdvCurHopLimit; - ricmp->icmp6_nra.M = NDP_AdvManagedFlag; - ricmp->icmp6_nra.O = NDP_AdvOtherConfigFlag; - ricmp->icmp6_nra.reserved = 0; - ricmp->icmp6_nra.lifetime = htons(NDP_AdvDefaultLifetime); - ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime); - ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime); - t->m_data += ICMP6_NDP_RA_MINLEN; - pl_size += ICMP6_NDP_RA_MINLEN; - - /* Source link-layer address (NDP option) */ - struct ndpopt *opt = mtod(t, struct ndpopt *); - opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE; - opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8; - in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer); - t->m_data += NDPOPT_LINKLAYER_LEN; - pl_size += NDPOPT_LINKLAYER_LEN; - - /* Prefix information (NDP option) */ - struct ndpopt *opt2 = mtod(t, struct ndpopt *); - opt2->ndpopt_type = NDPOPT_PREFIX_INFO; - opt2->ndpopt_len = NDPOPT_PREFIXINFO_LEN / 8; - opt2->ndpopt_prefixinfo.prefix_length = slirp->vprefix_len; - opt2->ndpopt_prefixinfo.L = 1; - opt2->ndpopt_prefixinfo.A = 1; - opt2->ndpopt_prefixinfo.reserved1 = 0; - opt2->ndpopt_prefixinfo.valid_lt = htonl(NDP_AdvValidLifetime); - opt2->ndpopt_prefixinfo.pref_lt = htonl(NDP_AdvPrefLifetime); - opt2->ndpopt_prefixinfo.reserved2 = 0; - opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6; - t->m_data += NDPOPT_PREFIXINFO_LEN; - pl_size += NDPOPT_PREFIXINFO_LEN; - - /* Prefix information (NDP option) */ - if (get_dns6_addr(&addr, &scope_id) >= 0) { - /* Host system does have an IPv6 DNS server, announce our proxy. */ - struct ndpopt *opt3 = mtod(t, struct ndpopt *); - opt3->ndpopt_type = NDPOPT_RDNSS; - opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8; - opt3->ndpopt_rdnss.reserved = 0; - opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval); - opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6; - t->m_data += NDPOPT_RDNSS_LEN; - pl_size += NDPOPT_RDNSS_LEN; - } - - rip->ip_pl = htons(pl_size); - t->m_data -= sizeof(struct ip6) + pl_size; - t->m_len = sizeof(struct ip6) + pl_size; - - /* ICMPv6 Checksum */ - ricmp->icmp6_cksum = ip6_cksum(t); - - ip6_output(NULL, t, 0); -} - -void ra_timer_handler(Slirp *slirp, void *unused) -{ - slirp->cb->timer_mod(slirp->ra_timer, - slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS + - NDP_Interval, - slirp->opaque); - ndp_send_ra(slirp); -} - -/* - * Send NDP Neighbor Solitication - */ -void ndp_send_ns(Slirp *slirp, struct in6_addr addr) -{ - char addrstr[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &addr, addrstr, INET6_ADDRSTRLEN); - - DEBUG_CALL("ndp_send_ns"); - DEBUG_ARG("target = %s", addrstr); - - /* Build IPv6 packet */ - struct mbuf *t = m_get(slirp); - struct ip6 *rip = mtod(t, struct ip6 *); - rip->ip_src = slirp->vhost_addr6; - rip->ip_dst = (struct in6_addr)SOLICITED_NODE_PREFIX; - memcpy(&rip->ip_dst.s6_addr[13], &addr.s6_addr[13], 3); - rip->ip_nh = IPPROTO_ICMPV6; - rip->ip_pl = htons(ICMP6_NDP_NS_MINLEN + NDPOPT_LINKLAYER_LEN); - t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl); - - /* Build ICMPv6 packet */ - t->m_data += sizeof(struct ip6); - struct icmp6 *ricmp = mtod(t, struct icmp6 *); - ricmp->icmp6_type = ICMP6_NDP_NS; - ricmp->icmp6_code = 0; - ricmp->icmp6_cksum = 0; - - /* NDP */ - ricmp->icmp6_nns.reserved = 0; - ricmp->icmp6_nns.target = addr; - - /* Build NDP option */ - t->m_data += ICMP6_NDP_NS_MINLEN; - struct ndpopt *opt = mtod(t, struct ndpopt *); - opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE; - opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8; - in6_compute_ethaddr(slirp->vhost_addr6, opt->ndpopt_linklayer); - - /* ICMPv6 Checksum */ - t->m_data -= ICMP6_NDP_NA_MINLEN; - t->m_data -= sizeof(struct ip6); - ricmp->icmp6_cksum = ip6_cksum(t); - - ip6_output(NULL, t, 1); -} - -/* - * Send NDP Neighbor Advertisement - */ -static void ndp_send_na(Slirp *slirp, struct ip6 *ip, struct icmp6 *icmp) -{ - /* Build IPv6 packet */ - struct mbuf *t = m_get(slirp); - struct ip6 *rip = mtod(t, struct ip6 *); - rip->ip_src = icmp->icmp6_nns.target; - if (in6_zero(&ip->ip_src)) { - rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST; - } else { - rip->ip_dst = ip->ip_src; - } - rip->ip_nh = IPPROTO_ICMPV6; - rip->ip_pl = htons(ICMP6_NDP_NA_MINLEN + NDPOPT_LINKLAYER_LEN); - t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl); - - /* Build ICMPv6 packet */ - t->m_data += sizeof(struct ip6); - struct icmp6 *ricmp = mtod(t, struct icmp6 *); - ricmp->icmp6_type = ICMP6_NDP_NA; - ricmp->icmp6_code = 0; - ricmp->icmp6_cksum = 0; - - /* NDP */ - ricmp->icmp6_nna.R = NDP_IsRouter; - ricmp->icmp6_nna.S = !IN6_IS_ADDR_MULTICAST(&rip->ip_dst); - ricmp->icmp6_nna.O = 1; - ricmp->icmp6_nna.reserved_hi = 0; - ricmp->icmp6_nna.reserved_lo = 0; - ricmp->icmp6_nna.target = icmp->icmp6_nns.target; - - /* Build NDP option */ - t->m_data += ICMP6_NDP_NA_MINLEN; - struct ndpopt *opt = mtod(t, struct ndpopt *); - opt->ndpopt_type = NDPOPT_LINKLAYER_TARGET; - opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8; - in6_compute_ethaddr(ricmp->icmp6_nna.target, opt->ndpopt_linklayer); - - /* ICMPv6 Checksum */ - t->m_data -= ICMP6_NDP_NA_MINLEN; - t->m_data -= sizeof(struct ip6); - ricmp->icmp6_cksum = ip6_cksum(t); - - ip6_output(NULL, t, 0); -} - -/* - * Process a NDP message - */ -static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip, - struct icmp6 *icmp) -{ - g_assert(M_ROOMBEFORE(m) >= ETH_HLEN); - - m->m_len += ETH_HLEN; - m->m_data -= ETH_HLEN; - struct ethhdr *eth = mtod(m, struct ethhdr *); - m->m_len -= ETH_HLEN; - m->m_data += ETH_HLEN; - - switch (icmp->icmp6_type) { - case ICMP6_NDP_RS: - DEBUG_CALL(" type = Router Solicitation"); - if (ip->ip_hl == 255 && icmp->icmp6_code == 0 && - ntohs(ip->ip_pl) >= ICMP6_NDP_RS_MINLEN) { - /* Gratuitous NDP */ - ndp_table_add(slirp, ip->ip_src, eth->h_source); - - ndp_send_ra(slirp); - } - break; - - case ICMP6_NDP_RA: - DEBUG_CALL(" type = Router Advertisement"); - slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't", - slirp->opaque); - break; - - case ICMP6_NDP_NS: - DEBUG_CALL(" type = Neighbor Solicitation"); - if (ip->ip_hl == 255 && icmp->icmp6_code == 0 && - !IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nns.target) && - ntohs(ip->ip_pl) >= ICMP6_NDP_NS_MINLEN && - (!in6_zero(&ip->ip_src) || - in6_solicitednode_multicast(&ip->ip_dst))) { - if (in6_equal_host(&icmp->icmp6_nns.target)) { - /* Gratuitous NDP */ - ndp_table_add(slirp, ip->ip_src, eth->h_source); - ndp_send_na(slirp, ip, icmp); - } - } - break; - - case ICMP6_NDP_NA: - DEBUG_CALL(" type = Neighbor Advertisement"); - if (ip->ip_hl == 255 && icmp->icmp6_code == 0 && - ntohs(ip->ip_pl) >= ICMP6_NDP_NA_MINLEN && - !IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nna.target) && - (!IN6_IS_ADDR_MULTICAST(&ip->ip_dst) || icmp->icmp6_nna.S == 0)) { - ndp_table_add(slirp, ip->ip_src, eth->h_source); - } - break; - - case ICMP6_NDP_REDIRECT: - DEBUG_CALL(" type = Redirect"); - slirp->cb->guest_error( - "Warning: guest sent NDP REDIRECT, but shouldn't", slirp->opaque); - break; - } -} - -/* - * Process a received ICMPv6 message. - */ -void icmp6_input(struct mbuf *m) -{ - Slirp *slirp = m->slirp; - /* NDP reads the ethernet header for gratuitous NDP */ - M_DUP_DEBUG(slirp, m, 1, ETH_HLEN); - - struct icmp6 *icmp; - struct ip6 *ip = mtod(m, struct ip6 *); - int hlen = sizeof(struct ip6); - - DEBUG_CALL("icmp6_input"); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("m_len = %d", m->m_len); - - if (ntohs(ip->ip_pl) < ICMP6_MINLEN) { - goto end; - } - - if (ip6_cksum(m)) { - goto end; - } - - m->m_len -= hlen; - m->m_data += hlen; - icmp = mtod(m, struct icmp6 *); - m->m_len += hlen; - m->m_data -= hlen; - - DEBUG_ARG("icmp6_type = %d", icmp->icmp6_type); - switch (icmp->icmp6_type) { - case ICMP6_ECHO_REQUEST: - if (in6_equal_host(&ip->ip_dst)) { - icmp6_send_echoreply(m, slirp, ip, icmp); - } else { - /* TODO */ - g_critical("external icmpv6 not supported yet"); - } - break; - - case ICMP6_NDP_RS: - case ICMP6_NDP_RA: - case ICMP6_NDP_NS: - case ICMP6_NDP_NA: - case ICMP6_NDP_REDIRECT: - ndp_input(m, slirp, ip, icmp); - break; - - case ICMP6_UNREACH: - case ICMP6_TOOBIG: - case ICMP6_TIMXCEED: - case ICMP6_PARAMPROB: - /* XXX? report error? close socket? */ - default: - break; - } - -end: - m_free(m); -} diff --git a/src/network/slirp/ip6_icmp.h b/src/network/slirp/ip6_icmp.h deleted file mode 100644 index 02761b7263..0000000000 --- a/src/network/slirp/ip6_icmp.h +++ /dev/null @@ -1,238 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#ifndef SLIRP_IP6_ICMP_H -#define SLIRP_IP6_ICMP_H - -/* - * Interface Control Message Protocol version 6 Definitions. - * Per RFC 4443, March 2006. - * - * Network Discover Protocol Definitions. - * Per RFC 4861, September 2007. - */ - -struct icmp6_echo { /* Echo Messages */ - uint16_t id; - uint16_t seq_num; -}; - -union icmp6_error_body { - uint32_t unused; - uint32_t pointer; - uint32_t mtu; -}; - -/* - * NDP Messages - */ -struct ndp_rs { /* Router Solicitation Message */ - uint32_t reserved; -}; - -struct ndp_ra { /* Router Advertisement Message */ - uint8_t chl; /* Cur Hop Limit */ -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint8_t M : 1, O : 1, reserved : 6; -#else - uint8_t reserved : 6, O : 1, M : 1; -#endif - uint16_t lifetime; /* Router Lifetime */ - uint32_t reach_time; /* Reachable Time */ - uint32_t retrans_time; /* Retrans Timer */ -}; - -G_STATIC_ASSERT(sizeof(struct ndp_ra) == 12); - -struct ndp_ns { /* Neighbor Solicitation Message */ - uint32_t reserved; - struct in6_addr target; /* Target Address */ -}; - -G_STATIC_ASSERT(sizeof(struct ndp_ns) == 20); - -struct ndp_na { /* Neighbor Advertisement Message */ -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint32_t R : 1, /* Router Flag */ - S : 1, /* Solicited Flag */ - O : 1, /* Override Flag */ - reserved_hi : 5, reserved_lo : 24; -#else - uint32_t reserved_hi : 5, O : 1, S : 1, R : 1, reserved_lo : 24; -#endif - struct in6_addr target; /* Target Address */ -}; - -G_STATIC_ASSERT(sizeof(struct ndp_na) == 20); - -struct ndp_redirect { - uint32_t reserved; - struct in6_addr target; /* Target Address */ - struct in6_addr dest; /* Destination Address */ -}; - -G_STATIC_ASSERT(sizeof(struct ndp_redirect) == 36); - -/* - * Structure of an icmpv6 header. - */ -struct icmp6 { - uint8_t icmp6_type; /* type of message, see below */ - uint8_t icmp6_code; /* type sub code */ - uint16_t icmp6_cksum; /* ones complement cksum of struct */ - union { - union icmp6_error_body error_body; - struct icmp6_echo echo; - struct ndp_rs ndp_rs; - struct ndp_ra ndp_ra; - struct ndp_ns ndp_ns; - struct ndp_na ndp_na; - struct ndp_redirect ndp_redirect; - } icmp6_body; -#define icmp6_err icmp6_body.error_body -#define icmp6_echo icmp6_body.echo -#define icmp6_nrs icmp6_body.ndp_rs -#define icmp6_nra icmp6_body.ndp_ra -#define icmp6_nns icmp6_body.ndp_ns -#define icmp6_nna icmp6_body.ndp_na -#define icmp6_redirect icmp6_body.ndp_redirect -}; - -G_STATIC_ASSERT(sizeof(struct icmp6) == 40); - -#define ICMP6_MINLEN 4 -#define ICMP6_ERROR_MINLEN 8 -#define ICMP6_ECHO_MINLEN 8 -#define ICMP6_NDP_RS_MINLEN 8 -#define ICMP6_NDP_RA_MINLEN 16 -#define ICMP6_NDP_NS_MINLEN 24 -#define ICMP6_NDP_NA_MINLEN 24 -#define ICMP6_NDP_REDIRECT_MINLEN 40 - -/* - * NDP Options - */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ndpopt { - uint8_t ndpopt_type; /* Option type */ - uint8_t ndpopt_len; /* /!\ In units of 8 octets */ - union { - unsigned char linklayer_addr[6]; /* Source/Target Link-layer */ -#define ndpopt_linklayer ndpopt_body.linklayer_addr -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif - struct prefixinfo { /* Prefix Information */ - uint8_t prefix_length; -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint8_t L : 1, A : 1, reserved1 : 6; -#else - uint8_t reserved1 : 6, A : 1, L : 1; -#endif - uint32_t valid_lt; /* Valid Lifetime */ - uint32_t pref_lt; /* Preferred Lifetime */ - uint32_t reserved2; - struct in6_addr prefix; - } SLIRP_PACKED prefixinfo; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif -#define ndpopt_prefixinfo ndpopt_body.prefixinfo -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif - struct rdnss { - uint16_t reserved; - uint32_t lifetime; - struct in6_addr addr; - } SLIRP_PACKED rdnss; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif -#define ndpopt_rdnss ndpopt_body.rdnss - } ndpopt_body; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* NDP options type */ -#define NDPOPT_LINKLAYER_SOURCE 1 /* Source Link-Layer Address */ -#define NDPOPT_LINKLAYER_TARGET 2 /* Target Link-Layer Address */ -#define NDPOPT_PREFIX_INFO 3 /* Prefix Information */ -#define NDPOPT_RDNSS 25 /* Recursive DNS Server Address */ - -/* NDP options size, in octets. */ -#define NDPOPT_LINKLAYER_LEN 8 -#define NDPOPT_PREFIXINFO_LEN 32 -#define NDPOPT_RDNSS_LEN 24 - -/* - * Definition of type and code field values. - * Per https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml - * Last Updated 2012-11-12 - */ - -/* Errors */ -#define ICMP6_UNREACH 1 /* Destination Unreachable */ -#define ICMP6_UNREACH_NO_ROUTE 0 /* no route to dest */ -#define ICMP6_UNREACH_DEST_PROHIB 1 /* com with dest prohibited */ -#define ICMP6_UNREACH_SCOPE 2 /* beyond scope of src addr */ -#define ICMP6_UNREACH_ADDRESS 3 /* address unreachable */ -#define ICMP6_UNREACH_PORT 4 /* port unreachable */ -#define ICMP6_UNREACH_SRC_FAIL 5 /* src addr failed */ -#define ICMP6_UNREACH_REJECT_ROUTE 6 /* reject route to dest */ -#define ICMP6_UNREACH_SRC_HDR_ERROR 7 /* error in src routing header */ -#define ICMP6_TOOBIG 2 /* Packet Too Big */ -#define ICMP6_TIMXCEED 3 /* Time Exceeded */ -#define ICMP6_TIMXCEED_INTRANS 0 /* hop limit exceeded in transit */ -#define ICMP6_TIMXCEED_REASS 1 /* ttl=0 in reass */ -#define ICMP6_PARAMPROB 4 /* Parameter Problem */ -#define ICMP6_PARAMPROB_HDR_FIELD 0 /* err header field */ -#define ICMP6_PARAMPROB_NXTHDR_TYPE 1 /* unrecognized Next Header type */ -#define ICMP6_PARAMPROB_IPV6_OPT 2 /* unrecognized IPv6 option */ - -/* Informational Messages */ -#define ICMP6_ECHO_REQUEST 128 /* Echo Request */ -#define ICMP6_ECHO_REPLY 129 /* Echo Reply */ -#define ICMP6_NDP_RS 133 /* Router Solicitation (NDP) */ -#define ICMP6_NDP_RA 134 /* Router Advertisement (NDP) */ -#define ICMP6_NDP_NS 135 /* Neighbor Solicitation (NDP) */ -#define ICMP6_NDP_NA 136 /* Neighbor Advertisement (NDP) */ -#define ICMP6_NDP_REDIRECT 137 /* Redirect Message (NDP) */ - -/* - * Router Configuration Variables (rfc4861#section-6) - */ -#define NDP_IsRouter 1 -#define NDP_AdvSendAdvertisements 1 -#define NDP_MaxRtrAdvInterval 600000 -#define NDP_MinRtrAdvInterval \ - ((NDP_MaxRtrAdvInterval >= 9) ? NDP_MaxRtrAdvInterval / 3 : \ - NDP_MaxRtrAdvInterval) -#define NDP_AdvManagedFlag 0 -#define NDP_AdvOtherConfigFlag 0 -#define NDP_AdvLinkMTU 0 -#define NDP_AdvReachableTime 0 -#define NDP_AdvRetransTime 0 -#define NDP_AdvCurHopLimit 64 -#define NDP_AdvDefaultLifetime ((3 * NDP_MaxRtrAdvInterval) / 1000) -#define NDP_AdvValidLifetime 86400 -#define NDP_AdvOnLinkFlag 1 -#define NDP_AdvPrefLifetime 14400 -#define NDP_AdvAutonomousFlag 1 - -void icmp6_post_init(Slirp *slirp); -void icmp6_cleanup(Slirp *slirp); -void icmp6_input(struct mbuf *); -void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src); -void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code); -void ndp_send_ns(Slirp *slirp, struct in6_addr addr); -void ra_timer_handler(Slirp *slirp, void *unused); - -#endif diff --git a/src/network/slirp/ip6_input.c b/src/network/slirp/ip6_input.c deleted file mode 100644 index 4aca08285d..0000000000 --- a/src/network/slirp/ip6_input.c +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#include "slirp.h" -#include "ip6_icmp.h" - -/* - * IP initialization: fill in IP protocol switch table. - * All protocols not implemented in kernel go to raw IP protocol handler. - */ -void ip6_post_init(Slirp *slirp) -{ - icmp6_post_init(slirp); -} - -void ip6_cleanup(Slirp *slirp) -{ - icmp6_cleanup(slirp); -} - -void ip6_input(struct mbuf *m) -{ - Slirp *slirp = m->slirp; - /* NDP reads the ethernet header for gratuitous NDP */ - M_DUP_DEBUG(slirp, m, 1, TCPIPHDR_DELTA + 2 + ETH_HLEN); - - struct ip6 *ip6; - - if (!slirp->in6_enabled) { - goto bad; - } - - DEBUG_CALL("ip6_input"); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("m_len = %d", m->m_len); - - if (m->m_len < sizeof(struct ip6)) { - goto bad; - } - - ip6 = mtod(m, struct ip6 *); - - if (ip6->ip_v != IP6VERSION) { - goto bad; - } - - if (ntohs(ip6->ip_pl) + sizeof(struct ip6) > slirp->if_mtu) { - icmp6_send_error(m, ICMP6_TOOBIG, 0); - goto bad; - } - - // Check if the message size is big enough to hold what's - // set in the payload length header. If not this is an invalid - // packet - if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) { - goto bad; - } - - /* check ip_ttl for a correct ICMP reply */ - if (ip6->ip_hl == 0) { - icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS); - goto bad; - } - - /* - * Switch out to protocol's input routine. - */ - switch (ip6->ip_nh) { - case IPPROTO_TCP: - NTOHS(ip6->ip_pl); - tcp_input(m, sizeof(struct ip6), (struct socket *)NULL, AF_INET6); - break; - case IPPROTO_UDP: - udp6_input(m); - break; - case IPPROTO_ICMPV6: - icmp6_input(m); - break; - default: - m_free(m); - } - return; -bad: - m_free(m); -} diff --git a/src/network/slirp/ip6_output.c b/src/network/slirp/ip6_output.c deleted file mode 100644 index 834f1c0a32..0000000000 --- a/src/network/slirp/ip6_output.c +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#include "slirp.h" - -/* Number of packets queued before we start sending - * (to prevent allocing too many mbufs) */ -#define IF6_THRESH 10 - -/* - * IPv6 output. The packet in mbuf chain m contains a IP header - */ -int ip6_output(struct socket *so, struct mbuf *m, int fast) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, 0); - - struct ip6 *ip = mtod(m, struct ip6 *); - - DEBUG_CALL("ip6_output"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - - /* Fill IPv6 header */ - ip->ip_v = IP6VERSION; - ip->ip_hl = IP6_HOP_LIMIT; - ip->ip_tc_hi = 0; - ip->ip_tc_lo = 0; - ip->ip_fl_hi = 0; - ip->ip_fl_lo = 0; - - if (fast) { - /* We cannot fast-send non-multicast, we'd need a NDP NS */ - assert(IN6_IS_ADDR_MULTICAST(&ip->ip_dst)); - if_encap(m->slirp, m); - m_free(m); - } else { - if_output(so, m); - } - - return 0; -} diff --git a/src/network/slirp/ip_icmp.c b/src/network/slirp/ip_icmp.c deleted file mode 100644 index 6ae523c690..0000000000 --- a/src/network/slirp/ip_icmp.c +++ /dev/null @@ -1,541 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 - * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp - */ - -#include "slirp.h" -#include "ip_icmp.h" - -#ifndef WITH_ICMP_ERROR_MSG -#define WITH_ICMP_ERROR_MSG 0 -#endif - -/* The message sent when emulating PING */ -/* Be nice and tell them it's just a pseudo-ping packet */ -static const char icmp_ping_msg[] = - "This is a pseudo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST " - "packets.\n"; - -/* list of actions for icmp_send_error() on RX of an icmp message */ -static const int icmp_flush[19] = { - /* ECHO REPLY (0) */ 0, - 1, - 1, - /* DEST UNREACH (3) */ 1, - /* SOURCE QUENCH (4)*/ 1, - /* REDIRECT (5) */ 1, - 1, - 1, - /* ECHO (8) */ 0, - /* ROUTERADVERT (9) */ 1, - /* ROUTERSOLICIT (10) */ 1, - /* TIME EXCEEDED (11) */ 1, - /* PARAMETER PROBLEM (12) */ 1, - /* TIMESTAMP (13) */ 0, - /* TIMESTAMP REPLY (14) */ 0, - /* INFO (15) */ 0, - /* INFO REPLY (16) */ 0, - /* ADDR MASK (17) */ 0, - /* ADDR MASK REPLY (18) */ 0 -}; - -void icmp_init(Slirp *slirp) -{ - slirp->icmp.so_next = slirp->icmp.so_prev = &slirp->icmp; - slirp->icmp_last_so = &slirp->icmp; -} - -void icmp_cleanup(Slirp *slirp) -{ - struct socket *so, *so_next; - - for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) { - so_next = so->so_next; - icmp_detach(so); - } -} - -static int icmp_send(struct socket *so, struct mbuf *m, int hlen) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, 0); - - struct ip *ip = mtod(m, struct ip *); - struct sockaddr_in addr; - - /* - * The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent - * between host OSes. On Linux, only the ICMP header and payload is - * included. On macOS/Darwin, the socket acts like a raw socket and - * includes the IP header as well. On other BSDs, SOCK_DGRAM+IPPROTO_ICMP - * sockets aren't supported at all, so we treat them like raw sockets. It - * isn't possible to detect this difference at runtime, so we must use an - * #ifdef to determine if we need to remove the IP header. - */ -#ifdef CONFIG_BSD - so->so_type = IPPROTO_IP; -#else - so->so_type = IPPROTO_ICMP; -#endif - - so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); - if (so->s == -1) { - if (errno == EAFNOSUPPORT - || errno == EPROTONOSUPPORT - || errno == EACCES) { - /* Kernel doesn't support or allow ping sockets. */ - so->so_type = IPPROTO_IP; - so->s = slirp_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - } - } - if (so->s == -1) { - return -1; - } - so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); - - if (slirp_bind_outbound(so, AF_INET) != 0) { - // bind failed - close socket - closesocket(so->s); - so->s = -1; - return -1; - } - - so->so_m = m; - so->so_faddr = ip->ip_dst; - so->so_laddr = ip->ip_src; - so->so_iptos = ip->ip_tos; - so->so_state = SS_ISFCONNECTED; - so->so_expire = curtime + SO_EXPIRE; - - addr.sin_family = AF_INET; - addr.sin_addr = so->so_faddr; - - slirp_insque(so, &so->slirp->icmp); - - if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0, - (struct sockaddr *)&addr, sizeof(addr)) == -1) { - DEBUG_MISC("icmp_input icmp sendto tx errno = %d-%s", errno, - strerror(errno)); - icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); - icmp_detach(so); - } - - return 0; -} - -void icmp_detach(struct socket *so) -{ - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - sofree(so); -} - -/* - * Process a received ICMP message. - */ -void icmp_input(struct mbuf *m, int hlen) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, 0); - - register struct icmp *icp; - register struct ip *ip = mtod(m, struct ip *); - int icmplen = ip->ip_len; - - DEBUG_CALL("icmp_input"); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("m_len = %d", m->m_len); - - /* - * Locate icmp structure in mbuf, and check - * that its not corrupted and of at least minimum length. - */ - if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ - freeit: - m_free(m); - goto end_error; - } - - m->m_len -= hlen; - m->m_data += hlen; - icp = mtod(m, struct icmp *); - if (cksum(m, icmplen)) { - goto freeit; - } - m->m_len += hlen; - m->m_data -= hlen; - - DEBUG_ARG("icmp_type = %d", icp->icmp_type); - switch (icp->icmp_type) { - case ICMP_ECHO: - ip->ip_len += hlen; /* since ip_input subtracts this */ - if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr || - ip->ip_dst.s_addr == slirp->vnameserver_addr.s_addr) { - icmp_reflect(m); - } else if (slirp->restricted) { - goto freeit; - } else { - struct socket *so; - struct sockaddr_storage addr; - int ttl; - - so = socreate(slirp, IPPROTO_ICMP); - if (icmp_send(so, m, hlen) == 0) { - /* We could send this as ICMP, good! */ - return; - } - - /* We could not send this as ICMP, try to send it on UDP echo - * service (7), wishfully hoping that it is open there. */ - - if (udp_attach(so, AF_INET) == -1) { - DEBUG_MISC("icmp_input udp_attach errno = %d-%s", errno, - strerror(errno)); - sofree(so); - m_free(m); - goto end_error; - } - so->so_m = m; - so->so_ffamily = AF_INET; - so->so_faddr = ip->ip_dst; - so->so_fport = htons(7); - so->so_lfamily = AF_INET; - so->so_laddr = ip->ip_src; - so->so_lport = htons(9); - so->so_iptos = ip->ip_tos; - so->so_state = SS_ISFCONNECTED; - - /* Send the packet */ - addr = so->fhost.ss; - if (sotranslate_out(so, &addr) < 0) { - icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, - strerror(errno)); - udp_detach(so); - return; - } - - /* - * Check for TTL - */ - ttl = ip->ip_ttl-1; - if (ttl <= 0) { - DEBUG_MISC("udp ttl exceeded"); - icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, - NULL); - udp_detach(so); - break; - } - setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); - - if (sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0, - (struct sockaddr *)&addr, sockaddr_size(&addr)) == -1) { - DEBUG_MISC("icmp_input udp sendto tx errno = %d-%s", errno, - strerror(errno)); - icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, - strerror(errno)); - udp_detach(so); - } - } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ - break; - case ICMP_UNREACH: - /* XXX? report error? close socket? */ - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - case ICMP_SOURCEQUENCH: - case ICMP_TSTAMP: - case ICMP_MASKREQ: - case ICMP_REDIRECT: - m_free(m); - break; - - default: - m_free(m); - } /* switch */ - -end_error: - /* m is m_free()'d xor put in a socket xor or given to ip_send */ - return; -} - - -/* - * Send an ICMP message in response to a situation - * - * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. - *MAY send more (we do). MUST NOT change this header information. MUST NOT reply - *to a multicast/broadcast IP address. MUST NOT reply to a multicast/broadcast - *MAC address. MUST reply to only the first fragment. - */ -/* - * Send ICMP_UNREACH back to the source regarding msrc. - * mbuf *msrc is used as a template, but is NOT m_free()'d. - * It is reported as the bad ip packet. The header should - * be fully correct and in host byte order. - * ICMP fragmentation is illegal. All machines must accept 576 bytes in one - * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548 - */ - -#define ICMP_MAXDATALEN (IP_MSS - 28) -void icmp_forward_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize, - const char *message, struct in_addr *src) -{ - unsigned hlen, shlen, s_ip_len; - register struct ip *ip; - register struct icmp *icp; - register struct mbuf *m; - - DEBUG_CALL("icmp_send_error"); - DEBUG_ARG("msrc = %p", msrc); - DEBUG_ARG("msrc_len = %d", msrc->m_len); - - if (type != ICMP_UNREACH && type != ICMP_TIMXCEED) - goto end_error; - - /* check msrc */ - if (!msrc) - goto end_error; - ip = mtod(msrc, struct ip *); - if (slirp_debug & DBG_MISC) { - char addr_src[INET_ADDRSTRLEN]; - char addr_dst[INET_ADDRSTRLEN]; - - inet_ntop(AF_INET, &ip->ip_src, addr_src, sizeof(addr_src)); - inet_ntop(AF_INET, &ip->ip_dst, addr_dst, sizeof(addr_dst)); - DEBUG_MISC(" %.16s to %.16s", addr_src, addr_dst); - } - if (ip->ip_off & IP_OFFMASK) - goto end_error; /* Only reply to fragment 0 */ - - /* Do not reply to source-only IPs */ - if ((ip->ip_src.s_addr & htonl(~(0xf << 28))) == 0) { - goto end_error; - } - - shlen = ip->ip_hl << 2; - s_ip_len = ip->ip_len; - if (ip->ip_p == IPPROTO_ICMP) { - icp = (struct icmp *)((char *)ip + shlen); - /* - * Assume any unknown ICMP type is an error. This isn't - * specified by the RFC, but think about it.. - */ - if (icp->icmp_type > 18 || icmp_flush[icp->icmp_type]) - goto end_error; - } - - /* make a copy */ - m = m_get(msrc->slirp); - if (!m) { - goto end_error; - } - - { - int new_m_size; - new_m_size = - sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN; - if (new_m_size > m->m_size) - m_inc(m, new_m_size); - } - memcpy(m->m_data, msrc->m_data, msrc->m_len); - m->m_len = msrc->m_len; /* copy msrc to m */ - - /* make the header of the reply packet */ - ip = mtod(m, struct ip *); - hlen = sizeof(struct ip); /* no options in reply */ - - /* fill in icmp */ - m->m_data += hlen; - m->m_len -= hlen; - - icp = mtod(m, struct icmp *); - - if (minsize) - s_ip_len = shlen + ICMP_MINLEN; /* return header+8b only */ - else if (s_ip_len > ICMP_MAXDATALEN) /* maximum size */ - s_ip_len = ICMP_MAXDATALEN; - - m->m_len = ICMP_MINLEN + s_ip_len; /* 8 bytes ICMP header */ - - /* min. size = 8+sizeof(struct ip)+8 */ - - icp->icmp_type = type; - icp->icmp_code = code; - icp->icmp_id = 0; - icp->icmp_seq = 0; - - memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */ - HTONS(icp->icmp_ip.ip_len); - HTONS(icp->icmp_ip.ip_id); - HTONS(icp->icmp_ip.ip_off); - - if (message && WITH_ICMP_ERROR_MSG) { /* append message to ICMP packet */ - int message_len; - char *cpnt; - message_len = strlen(message); - if (message_len > ICMP_MAXDATALEN) - message_len = ICMP_MAXDATALEN; - cpnt = (char *)m->m_data + m->m_len; - memcpy(cpnt, message, message_len); - m->m_len += message_len; - } - - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, m->m_len); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - ip->ip_hl = hlen >> 2; - ip->ip_len = m->m_len; - - ip->ip_tos = ((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ - - ip->ip_ttl = MAXTTL; - ip->ip_p = IPPROTO_ICMP; - ip->ip_dst = ip->ip_src; /* ip addresses */ - ip->ip_src = *src; - - ip_output((struct socket *)NULL, m); - -end_error: - return; -} -#undef ICMP_MAXDATALEN - -void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize, - const char *message) -{ - icmp_forward_error(msrc, type, code, minsize, message, &msrc->slirp->vhost_addr); -} - -/* - * Reflect the ip packet back to the source - */ -void icmp_reflect(struct mbuf *m) -{ - register struct ip *ip = mtod(m, struct ip *); - int hlen = ip->ip_hl << 2; - int optlen = hlen - sizeof(struct ip); - register struct icmp *icp; - - /* - * Send an icmp packet back to the ip level, - * after supplying a checksum. - */ - m->m_data += hlen; - m->m_len -= hlen; - icp = mtod(m, struct icmp *); - - icp->icmp_type = ICMP_ECHOREPLY; - icp->icmp_cksum = 0; - icp->icmp_cksum = cksum(m, ip->ip_len - hlen); - - m->m_data -= hlen; - m->m_len += hlen; - - /* fill in ip */ - if (optlen > 0) { - /* - * Strip out original options by copying rest of first - * mbuf's data back, and adjust the IP length. - */ - memmove((char *)(ip + 1), (char *)ip + hlen, - (unsigned)(m->m_len - hlen)); - hlen -= optlen; - ip->ip_hl = hlen >> 2; - ip->ip_len -= optlen; - m->m_len -= optlen; - } - - ip->ip_ttl = MAXTTL; - { /* swap */ - struct in_addr icmp_dst; - icmp_dst = ip->ip_dst; - ip->ip_dst = ip->ip_src; - ip->ip_src = icmp_dst; - } - - ip_output((struct socket *)NULL, m); -} - -void icmp_receive(struct socket *so) -{ - struct mbuf *m = so->so_m; - struct ip *ip = mtod(m, struct ip *); - int hlen = ip->ip_hl << 2; - uint8_t error_code; - struct icmp *icp; - int id, len; - - m->m_data += hlen; - m->m_len -= hlen; - icp = mtod(m, struct icmp *); - - id = icp->icmp_id; - len = recv(so->s, icp, M_ROOM(m), 0); - - if (so->so_type == IPPROTO_IP) { - if (len >= sizeof(struct ip)) { - struct ip *inner_ip = mtod(m, struct ip *); - int inner_hlen = inner_ip->ip_hl << 2; - if (inner_hlen > len) { - len = -1; - errno = -EINVAL; - } else { - len -= inner_hlen; - memmove(icp, (unsigned char *)icp + inner_hlen, len); - } - } else { - len = -1; - errno = -EINVAL; - } - } - - icp->icmp_id = id; - - m->m_data -= hlen; - m->m_len += hlen; - - if (len == -1 || len == 0) { - if (errno == ENETUNREACH) { - error_code = ICMP_UNREACH_NET; - } else { - error_code = ICMP_UNREACH_HOST; - } - DEBUG_MISC(" udp icmp rx errno = %d-%s", errno, strerror(errno)); - icmp_send_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno)); - } else { - icmp_reflect(so->so_m); - so->so_m = NULL; /* Don't m_free() it again! */ - } - icmp_detach(so); -} diff --git a/src/network/slirp/ip_icmp.h b/src/network/slirp/ip_icmp.h deleted file mode 100644 index 569a083061..0000000000 --- a/src/network/slirp/ip_icmp.h +++ /dev/null @@ -1,168 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 - * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp - */ - -#ifndef NETINET_IP_ICMP_H -#define NETINET_IP_ICMP_H - -/* - * Interface Control Message Protocol Definitions. - * Per RFC 792, September 1981. - */ - -typedef uint32_t n_time; - -/* - * Structure of an icmp header. - */ -struct icmp { - uint8_t icmp_type; /* type of message, see below */ - uint8_t icmp_code; /* type sub code */ - uint16_t icmp_cksum; /* ones complement cksum of struct */ - union { - uint8_t ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - uint16_t icd_id; - uint16_t icd_seq; - } ih_idseq; - int ih_void; - - /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ - struct ih_pmtu { - uint16_t ipm_void; - uint16_t ipm_nextmtu; - } ih_pmtu; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu - union { - struct id_ts { - n_time its_otime; - n_time its_rtime; - n_time its_ttime; - } id_ts; - struct id_ip { - struct ip idi_ip; - /* options and then 64 bits of data */ - } id_ip; - uint32_t id_mask; - char id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -}; - -/* - * Lower bounds on packet lengths for various types. - * For the error advice packets must first ensure that the - * packet is large enough to contain the returned ip header. - * Only then can we do the check to see if 64 bits of packet - * data have been returned, since we need to check the returned - * ip header length. - */ -#define ICMP_MINLEN 8 /* abs minimum */ -#define ICMP_TSLEN (8 + 3 * sizeof(n_time)) /* timestamp */ -#define ICMP_MASKLEN 12 /* address mask */ -#define ICMP_ADVLENMIN (8 + sizeof(struct ip) + 8) /* min */ -#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) -/* N.B.: must separately check that ip_hl >= 5 */ - -/* - * Definition of type and code field values. - */ -#define ICMP_ECHOREPLY 0 /* echo reply */ -#define ICMP_UNREACH 3 /* dest unreachable, codes: */ -#define ICMP_UNREACH_NET 0 /* bad net */ -#define ICMP_UNREACH_HOST 1 /* bad host */ -#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ -#define ICMP_UNREACH_PORT 3 /* bad port */ -#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ -#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ -#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ -#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ -#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ -#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ -#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ -#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ -#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ -#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ -#define ICMP_REDIRECT 5 /* shorter route, codes: */ -#define ICMP_REDIRECT_NET 0 /* for network */ -#define ICMP_REDIRECT_HOST 1 /* for host */ -#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ -#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ -#define ICMP_ECHO 8 /* echo service */ -#define ICMP_ROUTERADVERT 9 /* router advertisement */ -#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ -#define ICMP_TIMXCEED 11 /* time exceeded, code: */ -#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ -#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ -#define ICMP_PARAMPROB 12 /* ip header bad */ -#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ -#define ICMP_TSTAMP 13 /* timestamp request */ -#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ -#define ICMP_IREQ 15 /* information request */ -#define ICMP_IREQREPLY 16 /* information reply */ -#define ICMP_MASKREQ 17 /* address mask request */ -#define ICMP_MASKREPLY 18 /* address mask reply */ - -#define ICMP_MAXTYPE 18 - -#define ICMP_INFOTYPE(type) \ - ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ - (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ - (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ - (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ - (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) - -void icmp_init(Slirp *slirp); -void icmp_cleanup(Slirp *slirp); -void icmp_input(struct mbuf *, int); -void icmp_forward_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize, - const char *message, struct in_addr *src); -void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize, - const char *message); -void icmp_reflect(struct mbuf *); -void icmp_receive(struct socket *so); -void icmp_detach(struct socket *so); - -#endif diff --git a/src/network/slirp/ip_input.c b/src/network/slirp/ip_input.c deleted file mode 100644 index b0a64da19a..0000000000 --- a/src/network/slirp/ip_input.c +++ /dev/null @@ -1,464 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 - * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" -#include "ip_icmp.h" -#include - -static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp); -static void ip_freef(Slirp *slirp, struct ipq *fp); -static void ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev); -static void ip_deq(register struct ipasfrag *p); - -/* - * IP initialization: fill in IP protocol switch table. - * All protocols not implemented in kernel go to raw IP protocol handler. - */ -void ip_init(Slirp *slirp) -{ - slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link; - udp_init(slirp); - tcp_init(slirp); - icmp_init(slirp); -} - -void ip_cleanup(Slirp *slirp) -{ - udp_cleanup(slirp); - tcp_cleanup(slirp); - icmp_cleanup(slirp); -} - -/* - * Ip input routine. Checksum and byte swap header. If fragmented - * try to reassemble. Process options. Pass to next level. - */ -void ip_input(struct mbuf *m) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, TCPIPHDR_DELTA); - - register struct ip *ip; - int hlen; - - if (!slirp->in_enabled) { - goto bad; - } - - DEBUG_CALL("ip_input"); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("m_len = %d", m->m_len); - - if (m->m_len < sizeof(struct ip)) { - goto bad; - } - - ip = mtod(m, struct ip *); - - if (ip->ip_v != IPVERSION) { - goto bad; - } - - hlen = ip->ip_hl << 2; - if (hlen < sizeof(struct ip) || hlen > m->m_len) { /* min header length */ - goto bad; /* or packet too short */ - } - - /* keep ip header intact for ICMP reply - * ip->ip_sum = cksum(m, hlen); - * if (ip->ip_sum) { - */ - if (cksum(m, hlen)) { - goto bad; - } - - /* - * Convert fields to host representation. - */ - NTOHS(ip->ip_len); - if (ip->ip_len < hlen) { - goto bad; - } - NTOHS(ip->ip_id); - NTOHS(ip->ip_off); - - /* - * Check that the amount of data in the buffers - * is as at least much as the IP header would have us expect. - * Trim mbufs if longer than we expect. - * Drop packet if shorter than we expect. - */ - if (m->m_len < ip->ip_len) { - goto bad; - } - - /* Should drop packet if mbuf too long? hmmm... */ - if (m->m_len > ip->ip_len) - m_adj(m, ip->ip_len - m->m_len); - - /* check ip_ttl for a correct ICMP reply */ - if (ip->ip_ttl == 0) { - icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, "ttl"); - goto bad; - } - - /* - * If offset or IP_MF are set, must reassemble. - * Otherwise, nothing need be done. - * (We could look in the reassembly queue to see - * if the packet was previously fragmented, - * but it's not worth the time; just let them time out.) - * - * XXX This should fail, don't fragment yet - */ - if (ip->ip_off & ~IP_DF) { - register struct ipq *fp; - struct qlink *l; - /* - * Look for queue of fragments - * of this datagram. - */ - for (l = slirp->ipq.ip_link.next; l != &slirp->ipq.ip_link; - l = l->next) { - fp = container_of(l, struct ipq, ip_link); - if (ip->ip_id == fp->ipq_id && - ip->ip_src.s_addr == fp->ipq_src.s_addr && - ip->ip_dst.s_addr == fp->ipq_dst.s_addr && - ip->ip_p == fp->ipq_p) - goto found; - } - fp = NULL; - found: - - /* - * Adjust ip_len to not reflect header, - * set ip_mff if more fragments are expected, - * convert offset of this to bytes. - */ - ip->ip_len -= hlen; - if (ip->ip_off & IP_MF) - ip->ip_tos |= 1; - else - ip->ip_tos &= ~1; - - ip->ip_off <<= 3; - - /* - * If datagram marked as having more fragments - * or if this is not the first fragment, - * attempt reassembly; if it succeeds, proceed. - */ - if (ip->ip_tos & 1 || ip->ip_off) { - ip = ip_reass(slirp, ip, fp); - if (ip == NULL) - return; - m = dtom(slirp, ip); - } else if (fp) - ip_freef(slirp, fp); - - } else - ip->ip_len -= hlen; - - /* - * Switch out to protocol's input routine. - */ - switch (ip->ip_p) { - case IPPROTO_TCP: - tcp_input(m, hlen, (struct socket *)NULL, AF_INET); - break; - case IPPROTO_UDP: - udp_input(m, hlen); - break; - case IPPROTO_ICMP: - icmp_input(m, hlen); - break; - default: - m_free(m); - } - return; -bad: - m_free(m); -} - -#define iptofrag(P) ((struct ipasfrag *)(((char *)(P)) - sizeof(struct qlink))) -#define fragtoip(P) ((struct ip *)(((char *)(P)) + sizeof(struct qlink))) -/* - * Take incoming datagram fragment and try to - * reassemble it into whole datagram. If a chain for - * reassembly of this datagram already exists, then it - * is given as fp; otherwise have to make a chain. - */ -static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) -{ - register struct mbuf *m = dtom(slirp, ip); - register struct ipasfrag *q; - int hlen = ip->ip_hl << 2; - int i, next; - - DEBUG_CALL("ip_reass"); - DEBUG_ARG("ip = %p", ip); - DEBUG_ARG("fp = %p", fp); - DEBUG_ARG("m = %p", m); - - /* - * Presence of header sizes in mbufs - * would confuse code below. - * Fragment m_data is concatenated. - */ - m->m_data += hlen; - m->m_len -= hlen; - - /* - * If first fragment to arrive, create a reassembly queue. - */ - if (fp == NULL) { - struct mbuf *t = m_get(slirp); - - if (t == NULL) { - goto dropfrag; - } - fp = mtod(t, struct ipq *); - slirp_insque(&fp->ip_link, &slirp->ipq.ip_link); - fp->ipq_ttl = IPFRAGTTL; - fp->ipq_p = ip->ip_p; - fp->ipq_id = ip->ip_id; - fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; - fp->ipq_src = ip->ip_src; - fp->ipq_dst = ip->ip_dst; - q = (struct ipasfrag *)fp; - goto insert; - } - - /* - * Find a segment which begins after this one does. - */ - for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; - q = q->ipf_next) - if (q->ipf_off > ip->ip_off) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if (q->ipf_prev != &fp->frag_link) { - struct ipasfrag *pq = q->ipf_prev; - i = pq->ipf_off + pq->ipf_len - ip->ip_off; - if (i > 0) { - if (i >= ip->ip_len) - goto dropfrag; - m_adj(dtom(slirp, ip), i); - ip->ip_off += i; - ip->ip_len -= i; - } - } - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (q != (struct ipasfrag *)&fp->frag_link && - ip->ip_off + ip->ip_len > q->ipf_off) { - struct ipasfrag *prev; - i = (ip->ip_off + ip->ip_len) - q->ipf_off; - if (i < q->ipf_len) { - q->ipf_len -= i; - q->ipf_off += i; - m_adj(dtom(slirp, q), i); - break; - } - prev = q; - q = q->ipf_next; - ip_deq(prev); - m_free(dtom(slirp, prev)); - } - -insert: - /* - * Stick new segment in its place; - * check for complete reassembly. - */ - ip_enq(iptofrag(ip), q->ipf_prev); - next = 0; - for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; - q = q->ipf_next) { - if (q->ipf_off != next) - return NULL; - next += q->ipf_len; - } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) - return NULL; - - /* - * Reassembly is complete; concatenate fragments. - */ - q = fp->frag_link.next; - m = dtom(slirp, q); - int delta = (char *)q - (m->m_flags & M_EXT ? m->m_ext : m->m_dat); - - q = (struct ipasfrag *)q->ipf_next; - while (q != (struct ipasfrag *)&fp->frag_link) { - struct mbuf *t = dtom(slirp, q); - q = (struct ipasfrag *)q->ipf_next; - m_cat(m, t); - } - - /* - * Create header for new ip packet by - * modifying header of first packet; - * dequeue and discard fragment reassembly header. - * Make header visible. - */ - q = fp->frag_link.next; - - /* - * If the fragments concatenated to an mbuf that's bigger than the total - * size of the fragment and the mbuf was not already using an m_ext buffer, - * then an m_ext buffer was allocated. But fp->ipq_next points to the old - * buffer (in the mbuf), so we must point ip into the new buffer. - */ - if (m->m_flags & M_EXT) { - q = (struct ipasfrag *)(m->m_ext + delta); - } - - ip = fragtoip(q); - ip->ip_len = next; - ip->ip_tos &= ~1; - ip->ip_src = fp->ipq_src; - ip->ip_dst = fp->ipq_dst; - slirp_remque(&fp->ip_link); - m_free(dtom(slirp, fp)); - m->m_len += (ip->ip_hl << 2); - m->m_data -= (ip->ip_hl << 2); - - return ip; - -dropfrag: - m_free(m); - return NULL; -} - -/* - * Free a fragment reassembly header and all - * associated datagrams. - */ -static void ip_freef(Slirp *slirp, struct ipq *fp) -{ - register struct ipasfrag *q, *p; - - for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; - q = p) { - p = q->ipf_next; - ip_deq(q); - m_free(dtom(slirp, q)); - } - slirp_remque(&fp->ip_link); - m_free(dtom(slirp, fp)); -} - -/* - * Put an ip fragment on a reassembly chain. - * Like slirp_insque, but pointers in middle of structure. - */ -static void ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev) -{ - DEBUG_CALL("ip_enq"); - DEBUG_ARG("prev = %p", prev); - p->ipf_prev = prev; - p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; - prev->ipf_next = p; -} - -/* - * To ip_enq as slirp_remque is to slirp_insque. - */ -static void ip_deq(register struct ipasfrag *p) -{ - ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; - ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; -} - -/* - * IP timer processing; - * if a timer expires on a reassembly - * queue, discard it. - */ -void ip_slowtimo(Slirp *slirp) -{ - struct qlink *l; - - DEBUG_CALL("ip_slowtimo"); - - l = slirp->ipq.ip_link.next; - - if (l == NULL) - return; - - while (l != &slirp->ipq.ip_link) { - struct ipq *fp = container_of(l, struct ipq, ip_link); - l = l->next; - if (--fp->ipq_ttl == 0) { - ip_freef(slirp, fp); - } - } -} - -/* - * Strip out IP options, at higher - * level protocol in the kernel. - * Second argument is buffer to which options - * will be moved, and return value is their length. - * (XXX) should be deleted; last arg currently ignored. - */ -void ip_stripoptions(register struct mbuf *m, struct mbuf *mopt) -{ - register int i; - struct ip *ip = mtod(m, struct ip *); - register char *opts; - int olen; - - olen = (ip->ip_hl << 2) - sizeof(struct ip); - opts = (char *)(ip + 1); - i = m->m_len - (sizeof(struct ip) + olen); - memmove(opts, opts + olen, (unsigned)i); - m->m_len -= olen; - - ip->ip_hl = sizeof(struct ip) >> 2; -} diff --git a/src/network/slirp/ip_output.c b/src/network/slirp/ip_output.c deleted file mode 100644 index 4f62605915..0000000000 --- a/src/network/slirp/ip_output.c +++ /dev/null @@ -1,171 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp - */ - -/* - * Changes and additions relating to SLiRP are - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" - -/* Number of packets queued before we start sending - * (to prevent allocing too many mbufs) */ -#define IF_THRESH 10 - -/* - * IP output. The packet in mbuf chain m contains a skeletal IP - * header (with len, off, ttl, proto, tos, src, dst). - * The mbuf chain containing the packet will be freed. - * The mbuf opt, if present, will not be freed. - */ -int ip_output(struct socket *so, struct mbuf *m0) -{ - Slirp *slirp = m0->slirp; - M_DUP_DEBUG(slirp, m0, 0, 0); - - register struct ip *ip; - register struct mbuf *m = m0; - register int hlen = sizeof(struct ip); - int len, off, error = 0; - - DEBUG_CALL("ip_output"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m0 = %p", m0); - - ip = mtod(m, struct ip *); - /* - * Fill in IP header. - */ - ip->ip_v = IPVERSION; - ip->ip_off &= IP_DF; - ip->ip_id = htons(slirp->ip_id++); - ip->ip_hl = hlen >> 2; - - /* - * If small enough for interface, can just send directly. - */ - if ((uint16_t)ip->ip_len <= slirp->if_mtu) { - ip->ip_len = htons((uint16_t)ip->ip_len); - ip->ip_off = htons((uint16_t)ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); - - if_output(so, m); - goto done; - } - - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - if (ip->ip_off & IP_DF) { - error = -1; - goto bad; - } - - len = (slirp->if_mtu - hlen) & ~7; /* ip databytes per packet */ - if (len < 8) { - error = -1; - goto bad; - } - - { - int mhlen, firstlen = len; - struct mbuf **mnext = &m->m_nextpkt; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof(struct ip); - for (off = hlen + len; off < (uint16_t)ip->ip_len; off += len) { - register struct ip *mhip; - m = m_get(slirp); - if (m == NULL) { - error = -1; - goto sendorfree; - } - m->m_data += IF_MAXLINKHDR; - mhip = mtod(m, struct ip *); - *mhip = *ip; - - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); - if (ip->ip_off & IP_MF) - mhip->ip_off |= IP_MF; - if (off + len >= (uint16_t)ip->ip_len) - len = (uint16_t)ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((uint16_t)(len + mhlen)); - - if (m_copy(m, m0, off, len) < 0) { - error = -1; - goto sendorfree; - } - - mhip->ip_off = htons((uint16_t)mhip->ip_off); - mhip->ip_sum = 0; - mhip->ip_sum = cksum(m, mhlen); - *mnext = m; - mnext = &m->m_nextpkt; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m = m0; - m_adj(m, hlen + firstlen - (uint16_t)ip->ip_len); - ip->ip_len = htons((uint16_t)m->m_len); - ip->ip_off = htons((uint16_t)(ip->ip_off | IP_MF)); - ip->ip_sum = 0; - ip->ip_sum = cksum(m, hlen); - sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_nextpkt; - m->m_nextpkt = NULL; - if (error == 0) - if_output(so, m); - else - m_free(m); - } - } - -done: - return (error); - -bad: - m_free(m0); - goto done; -} diff --git a/src/network/slirp/libslirp-version.h b/src/network/slirp/libslirp-version.h deleted file mode 100644 index b689069573..0000000000 --- a/src/network/slirp/libslirp-version.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -#ifndef LIBSLIRP_VERSION_H_ -#define LIBSLIRP_VERSION_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define SLIRP_MAJOR_VERSION 4 -#define SLIRP_MINOR_VERSION 7 -#define SLIRP_MICRO_VERSION 0 -#define SLIRP_VERSION_STRING "4.7.0-86Box" - -#define SLIRP_CHECK_VERSION(major,minor,micro) \ - (SLIRP_MAJOR_VERSION > (major) || \ - (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION > (minor)) || \ - (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION == (minor) && \ - SLIRP_MICRO_VERSION >= (micro))) - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LIBSLIRP_VERSION_H_ */ diff --git a/src/network/slirp/libslirp.h b/src/network/slirp/libslirp.h deleted file mode 100644 index 7a6c9a4da4..0000000000 --- a/src/network/slirp/libslirp.h +++ /dev/null @@ -1,273 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -#ifndef LIBSLIRP_H -#define LIBSLIRP_H - -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#include -#endif - -#include "libslirp-version.h" - -/* Windows does not define ssize_t, so we need to define it here. */ -#ifndef _SSIZE_T_DEFINED -# define _SSIZE_T_DEFINED -# undef ssize_t -# ifdef _WIN64 -# define ssize_t int64_t -# else -# define ssize_t int32_t -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Opaque structure containing the slirp state */ -typedef struct Slirp Slirp; - -/* Flags passed to SlirpAddPollCb and to be returned by SlirpGetREventsCb. */ -enum { - SLIRP_POLL_IN = 1 << 0, - SLIRP_POLL_OUT = 1 << 1, - SLIRP_POLL_PRI = 1 << 2, - SLIRP_POLL_ERR = 1 << 3, - SLIRP_POLL_HUP = 1 << 4, -}; - -typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque); -typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque); -typedef void (*SlirpTimerCb)(void *opaque); -typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque); -typedef int (*SlirpGetREventsCb)(int idx, void *opaque); - -typedef enum SlirpTimerId { - SLIRP_TIMER_RA, - SLIRP_TIMER_NUM, -} SlirpTimerId; - -/* - * Callbacks from slirp, to be set by the application. - * - * The opaque parameter is set to the opaque pointer given in the slirp_new / - * slirp_init call. - */ -typedef struct SlirpCb { - /* - * Send an ethernet frame to the guest network. The opaque parameter is the - * one given to slirp_init(). If the guest is not ready to receive a frame, - * the function can just drop the data. TCP will then handle retransmissions - * at a lower pace. - * <0 reports an IO error. - */ - SlirpWriteCb send_packet; - /* Print a message for an error due to guest misbehavior. */ - void (*guest_error)(const char *msg, void *opaque); - /* Return the virtual clock value in nanoseconds */ - int64_t (*clock_get_ns)(void *opaque); - /* Create a new timer with the given callback and opaque data. Not - * needed if timer_new_opaque is provided. */ - void *(*timer_new)(SlirpTimerCb cb, void *cb_opaque, void *opaque); - /* Remove and free a timer */ - void (*timer_free)(void *timer, void *opaque); - /* Modify a timer to expire at @expire_time (ms) */ - void (*timer_mod)(void *timer, int64_t expire_time, void *opaque); - /* Register a fd for future polling */ - void (*register_poll_fd)(int fd, void *opaque); - /* Unregister a fd */ - void (*unregister_poll_fd)(int fd, void *opaque); - /* Kick the io-thread, to signal that new events may be processed because some TCP buffer - * can now receive more data, i.e. slirp_socket_can_recv will return 1. */ - void (*notify)(void *opaque); - - /* - * Fields introduced in SlirpConfig version 4 begin - */ - - /* Initialization has completed and a Slirp* has been created. */ - void (*init_completed)(Slirp *slirp, void *opaque); - /* Create a new timer. When the timer fires, the application passes - * the SlirpTimerId and cb_opaque to slirp_handle_timer. */ - void *(*timer_new_opaque)(SlirpTimerId id, void *cb_opaque, void *opaque); -} SlirpCb; - -#define SLIRP_CONFIG_VERSION_MIN 1 -#define SLIRP_CONFIG_VERSION_MAX 4 - -typedef struct SlirpConfig { - /* Version must be provided */ - uint32_t version; - /* - * Fields introduced in SlirpConfig version 1 begin - */ - int restricted; - bool in_enabled; - struct in_addr vnetwork; - struct in_addr vnetmask; - struct in_addr vhost; - bool in6_enabled; - struct in6_addr vprefix_addr6; - uint8_t vprefix_len; - struct in6_addr vhost6; - const char *vhostname; - const char *tftp_server_name; - const char *tftp_path; - const char *bootfile; - struct in_addr vdhcp_start; - struct in_addr vnameserver; - struct in6_addr vnameserver6; - const char **vdnssearch; - const char *vdomainname; - /* Default: IF_MTU_DEFAULT */ - size_t if_mtu; - /* Default: IF_MRU_DEFAULT */ - size_t if_mru; - /* Prohibit connecting to 127.0.0.1:* */ - bool disable_host_loopback; - /* - * Enable emulation code (*warning*: this code isn't safe, it is not - * recommended to enable it) - */ - bool enable_emu; - /* - * Fields introduced in SlirpConfig version 2 begin - */ - struct sockaddr_in *outbound_addr; - struct sockaddr_in6 *outbound_addr6; - /* - * Fields introduced in SlirpConfig version 3 begin - */ - bool disable_dns; /* slirp will not redirect/serve any DNS packet */ - /* - * Fields introduced in SlirpConfig version 4 begin - */ - bool disable_dhcp; /* slirp will not reply to any DHCP requests */ -} SlirpConfig; - -/* Create a new instance of a slirp stack */ -Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, - void *opaque); -/* slirp_init is deprecated in favor of slirp_new */ -Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, - struct in_addr vnetmask, struct in_addr vhost, - bool in6_enabled, struct in6_addr vprefix_addr6, - uint8_t vprefix_len, struct in6_addr vhost6, - const char *vhostname, const char *tftp_server_name, - const char *tftp_path, const char *bootfile, - struct in_addr vdhcp_start, struct in_addr vnameserver, - struct in6_addr vnameserver6, const char **vdnssearch, - const char *vdomainname, const SlirpCb *callbacks, - void *opaque); -/* Shut down an instance of a slirp stack */ -void slirp_cleanup(Slirp *slirp); - -/* This is called by the application when it is about to sleep through poll(). - * *timeout is set to the amount of virtual time (in ms) that the application intends to - * wait (UINT32_MAX if infinite). slirp_pollfds_fill updates it according to - * e.g. TCP timers, so the application knows it should sleep a smaller amount of - * time. slirp_pollfds_fill calls add_poll for each file descriptor - * that should be monitored along the sleep. The opaque pointer is passed as - * such to add_poll, and add_poll returns an index. */ -void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout, - SlirpAddPollCb add_poll, void *opaque); - -/* This is called by the application after sleeping, to report which file - * descriptors are available. slirp_pollfds_poll calls get_revents on each file - * descriptor, giving it the index that add_poll returned during the - * slirp_pollfds_fill call, to know whether the descriptor is available for - * read/write/etc. (SLIRP_POLL_*) - * select_error should be passed 1 if poll() returned an error. */ -void slirp_pollfds_poll(Slirp *slirp, int select_error, - SlirpGetREventsCb get_revents, void *opaque); - -/* This is called by the application when the guest emits a packet on the - * guest network, to be interpreted by slirp. */ -void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); - -/* This is called by the application when a timer expires, if it provides - * the timer_new_opaque callback. It is not needed if the application only - * uses timer_new. */ -void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque); - -/* These set up / remove port forwarding between a host port in the real world - * and the guest network. */ -int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, - int host_port, struct in_addr guest_addr, int guest_port); -int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, - int host_port); - -#define SLIRP_HOSTFWD_UDP 1 -#define SLIRP_HOSTFWD_V6ONLY 2 -int slirp_add_hostxfwd(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *gaddr, socklen_t gaddrlen, - int flags); -int slirp_remove_hostxfwd(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - int flags); - -/* Set up port forwarding between a port in the guest network and a - * command running on the host */ -int slirp_add_exec(Slirp *slirp, const char *cmdline, - struct in_addr *guest_addr, int guest_port); -/* Set up port forwarding between a port in the guest network and a - * Unix port on the host */ -int slirp_add_unix(Slirp *slirp, const char *unixsock, - struct in_addr *guest_addr, int guest_port); -/* Set up port forwarding between a port in the guest network and a - * callback that will receive the data coming from the port */ -int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, - struct in_addr *guest_addr, int guest_port); - -/* TODO: rather identify a guestfwd through an opaque pointer instead of through - * the guest_addr */ - -/* This is called by the application for a guestfwd, to determine how much data - * can be received by the forwarded port through a call to slirp_socket_recv. */ -size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, - int guest_port); -/* This is called by the application for a guestfwd, to provide the data to be - * sent on the forwarded port */ -void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, - const uint8_t *buf, int size); - -/* Remove entries added by slirp_add_exec, slirp_add_unix or slirp_add_guestfwd */ -int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, - int guest_port); - -/* Return a human-readable state of the slirp stack */ -char *slirp_connection_info(Slirp *slirp); - -/* Return a human-readable state of the NDP/ARP tables */ -char *slirp_neighbor_info(Slirp *slirp); - -/* Save the slirp state through the write_cb. The opaque pointer is passed as - * such to the write_cb. */ -void slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque); - -/* Returns the version of the slirp state, to be saved along the state */ -int slirp_state_version(void); - -/* Load the slirp state through the read_cb. The opaque pointer is passed as - * such to the read_cb. The version should be given as it was obtained from - * slirp_state_version when slirp_state_save was called. */ -int slirp_state_load(Slirp *s, int version_id, SlirpReadCb read_cb, - void *opaque); - -/* Return the version of the slirp implementation */ -const char *slirp_version_string(void); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LIBSLIRP_H */ diff --git a/src/network/slirp/main.h b/src/network/slirp/main.h deleted file mode 100644 index 3b3f883703..0000000000 --- a/src/network/slirp/main.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef SLIRP_MAIN_H -#define SLIRP_MAIN_H - -extern unsigned curtime; -extern struct in_addr loopback_addr; -extern unsigned long loopback_mask; - -int if_encap(Slirp *slirp, struct mbuf *ifm); -ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags); - -#endif diff --git a/src/network/slirp/mbuf.c b/src/network/slirp/mbuf.c deleted file mode 100644 index 153b36c030..0000000000 --- a/src/network/slirp/mbuf.c +++ /dev/null @@ -1,282 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski - */ - -/* - * mbuf's in SLiRP are much simpler than the real mbufs in - * FreeBSD. They are fixed size, determined by the MTU, - * so that one whole packet can fit. Mbuf's cannot be - * chained together. If there's more data than the mbuf - * could hold, an external g_malloced buffer is pointed to - * by m_ext (and the data pointers) and M_EXT is set in - * the flags - */ - -#include "slirp.h" -#include - -#define MBUF_THRESH 30 - -/* - * Find a nice value for msize - */ -#define SLIRP_MSIZE(mtu) \ - (offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + (mtu)) - -void m_init(Slirp *slirp) -{ - slirp->m_freelist.qh_link = slirp->m_freelist.qh_rlink = &slirp->m_freelist; - slirp->m_usedlist.qh_link = slirp->m_usedlist.qh_rlink = &slirp->m_usedlist; -} - -static void m_cleanup_list(struct slirp_quehead *list_head) -{ - struct mbuf *m, *next; - - m = (struct mbuf *)list_head->qh_link; - while ((struct slirp_quehead *)m != list_head) { - next = m->m_next; - if (m->m_flags & M_EXT) { - g_free(m->m_ext); - } - g_free(m); - m = next; - } - list_head->qh_link = list_head; - list_head->qh_rlink = list_head; -} - -void m_cleanup(Slirp *slirp) -{ - m_cleanup_list(&slirp->m_usedlist); - m_cleanup_list(&slirp->m_freelist); - m_cleanup_list(&slirp->if_batchq); - m_cleanup_list(&slirp->if_fastq); -} - -/* - * Get an mbuf from the free list, if there are none - * allocate one - * - * Because fragmentation can occur if we alloc new mbufs and - * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, - * which tells m_free to actually g_free() it - */ -struct mbuf *m_get(Slirp *slirp) -{ - register struct mbuf *m; - int flags = 0; - - DEBUG_CALL("m_get"); - - if (MBUF_DEBUG || slirp->m_freelist.qh_link == &slirp->m_freelist) { - m = g_malloc(SLIRP_MSIZE(slirp->if_mtu)); - slirp->mbuf_alloced++; - if (MBUF_DEBUG || slirp->mbuf_alloced > MBUF_THRESH) - flags = M_DOFREE; - m->slirp = slirp; - } else { - m = (struct mbuf *)slirp->m_freelist.qh_link; - slirp_remque(m); - } - - /* Insert it in the used list */ - slirp_insque(m, &slirp->m_usedlist); - m->m_flags = (flags | M_USEDLIST); - - /* Initialise it */ - m->m_size = SLIRP_MSIZE(slirp->if_mtu) - offsetof(struct mbuf, m_dat); - m->m_data = m->m_dat; - m->m_len = 0; - m->m_nextpkt = NULL; - m->m_prevpkt = NULL; - m->resolution_requested = false; - m->expiration_date = (uint64_t)-1; - DEBUG_ARG("m = %p", m); - return m; -} - -void m_free(struct mbuf *m) -{ - DEBUG_CALL("m_free"); - DEBUG_ARG("m = %p", m); - - if (m) { - /* Remove from m_usedlist */ - if (m->m_flags & M_USEDLIST) - slirp_remque(m); - - /* If it's M_EXT, free() it */ - if (m->m_flags & M_EXT) { - g_free(m->m_ext); - m->m_flags &= ~M_EXT; - } - /* - * Either free() it or put it on the free list - */ - if (m->m_flags & M_DOFREE) { - m->slirp->mbuf_alloced--; - g_free(m); - } else if ((m->m_flags & M_FREELIST) == 0) { - slirp_insque(m, &m->slirp->m_freelist); - m->m_flags = M_FREELIST; /* Clobber other flags */ - } - } /* if(m) */ -} - -/* - * Copy data from one mbuf to the end of - * the other.. if result is too big for one mbuf, allocate - * an M_EXT data segment - */ -void m_cat(struct mbuf *m, struct mbuf *n) -{ - /* - * If there's no room, realloc - */ - if (M_FREEROOM(m) < n->m_len) - m_inc(m, m->m_len + n->m_len); - - memcpy(m->m_data + m->m_len, n->m_data, n->m_len); - m->m_len += n->m_len; - - m_free(n); -} - - -/* make m 'size' bytes large from m_data */ -void m_inc(struct mbuf *m, int size) -{ - int gapsize; - - /* some compilers throw up on gotos. This one we can fake. */ - if (M_ROOM(m) > size) { - return; - } - - if (m->m_flags & M_EXT) { - gapsize = m->m_data - m->m_ext; - m->m_ext = g_realloc(m->m_ext, size + gapsize); - } else { - gapsize = m->m_data - m->m_dat; - m->m_ext = g_malloc(size + gapsize); - memcpy(m->m_ext, m->m_dat, m->m_size); - m->m_flags |= M_EXT; - } - - m->m_data = m->m_ext + gapsize; - m->m_size = size + gapsize; -} - - -void m_adj(struct mbuf *m, int len) -{ - if (m == NULL) - return; - if (len >= 0) { - /* Trim from head */ - m->m_data += len; - m->m_len -= len; - } else { - /* Trim from tail */ - len = -len; - m->m_len -= len; - } -} - - -/* - * Copy len bytes from m, starting off bytes into n - */ -int m_copy(struct mbuf *n, struct mbuf *m, int off, int len) -{ - if (len > M_FREEROOM(n)) - return -1; - - memcpy((n->m_data + n->m_len), (m->m_data + off), len); - n->m_len += len; - return 0; -} - - -/* - * Given a pointer into an mbuf, return the mbuf - * XXX This is a kludge, I should eliminate the need for it - * Fortunately, it's not used often - */ -struct mbuf *dtom(Slirp *slirp, void *dat) -{ - struct mbuf *m; - - DEBUG_CALL("dtom"); - DEBUG_ARG("dat = %p", dat); - - /* bug corrected for M_EXT buffers */ - for (m = (struct mbuf *)slirp->m_usedlist.qh_link; - (struct slirp_quehead *)m != &slirp->m_usedlist; m = m->m_next) { - if (m->m_flags & M_EXT) { - if ((char *)dat >= m->m_ext && (char *)dat < (m->m_ext + m->m_size)) - return m; - } else { - if ((char *)dat >= m->m_dat && (char *)dat < (m->m_dat + m->m_size)) - return m; - } - } - - DEBUG_ERROR("dtom failed"); - - return (struct mbuf *)0; -} - -/* - * Duplicate the mbuf - * - * copy_header specifies whether the bytes before m_data should also be copied. - * header_size specifies how many bytes are to be reserved before m_data. - */ -struct mbuf *m_dup(Slirp *slirp, struct mbuf *m, - bool copy_header, - size_t header_size) -{ - struct mbuf *n; - int mcopy_result; - - /* The previous mbuf was supposed to have it already, we can check it along - * the way */ - assert(M_ROOMBEFORE(m) >= header_size); - - n = m_get(slirp); - m_inc(n, m->m_len + header_size); - - if (copy_header) { - m->m_len += header_size; - m->m_data -= header_size; - mcopy_result = m_copy(n, m, 0, m->m_len + header_size); - n->m_data += header_size; - m->m_len -= header_size; - m->m_data += header_size; - } else { - n->m_data += header_size; - mcopy_result = m_copy(n, m, 0, m->m_len); - } - g_assert(mcopy_result == 0); - - return n; -} - -void *mtod_check(struct mbuf *m, size_t len) -{ - if (m->m_len >= len) { - return m->m_data; - } - - DEBUG_ERROR("mtod failed"); - - return NULL; -} - -void *m_end(struct mbuf *m) -{ - return m->m_data + m->m_len; -} diff --git a/src/network/slirp/mbuf.h b/src/network/slirp/mbuf.h deleted file mode 100644 index aedfc712e4..0000000000 --- a/src/network/slirp/mbuf.h +++ /dev/null @@ -1,192 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 - * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp - */ - -#ifndef MBUF_H -#define MBUF_H - -/* - * Macros for type conversion - * mtod(m,t) - convert mbuf pointer to data pointer of correct type - */ -#define mtod(m, t) ((t)(m)->m_data) - -/* XXX About mbufs for slirp: - * Only one mbuf is ever used in a chain, for each "cell" of data. - * m_nextpkt points to the next packet, if fragmented. - * If the data is too large, the M_EXT is used, and a larger block - * is alloced. Therefore, m_free[m] must check for M_EXT and if set - * free the m_ext. This is inefficient memory-wise, but who cares. - */ - -/* - * mbufs allow to have a gap between the start of the allocated buffer (m_ext if - * M_EXT is set, m_dat otherwise) and the in-use data: - * - * |--gapsize----->|---m_len-------> - * |----------m_size------------------------------> - * |----M_ROOM--------------------> - * |-M_FREEROOM--> - * - * ^ ^ ^ - * m_dat/m_ext m_data end of buffer - */ - -/* - * How much room is in the mbuf, from m_data to the end of the mbuf - */ -#define M_ROOM(m) \ - ((m->m_flags & M_EXT) ? (((m)->m_ext + (m)->m_size) - (m)->m_data) : \ - (((m)->m_dat + (m)->m_size) - (m)->m_data)) - -/* - * How much free room there is - */ -#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len) - -/* - * How much free room there is before m_data - */ -#define M_ROOMBEFORE(m) \ - (((m)->m_flags & M_EXT) ? (m)->m_data - (m)->m_ext \ - : (m)->m_data - (m)->m_dat) - -struct mbuf { - /* XXX should union some of these! */ - /* header at beginning of each mbuf: */ - struct mbuf *m_next; /* Linked list of mbufs */ - struct mbuf *m_prev; - struct mbuf *m_nextpkt; /* Next packet in queue/record */ - struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */ - int m_flags; /* Misc flags */ - - int m_size; /* Size of mbuf, from m_dat or m_ext */ - struct socket *m_so; - - char *m_data; /* Current location of data */ - int m_len; /* Amount of data in this mbuf, from m_data */ - - Slirp *slirp; - bool resolution_requested; - uint64_t expiration_date; - char *m_ext; - /* start of dynamic buffer area, must be last element */ - char m_dat[]; -}; - -#define ifq_prev m_prev -#define ifq_next m_next -#define ifs_prev m_prevpkt -#define ifs_next m_nextpkt -#define ifq_so m_so - -#define M_EXT 0x01 /* m_ext points to more (malloced) data */ -#define M_FREELIST 0x02 /* mbuf is on free list */ -#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */ -#define M_DOFREE \ - 0x08 /* when m_free is called on the mbuf, free() \ - * it rather than putting it on the free list */ - -void m_init(Slirp *); -void m_cleanup(Slirp *slirp); -struct mbuf *m_get(Slirp *); -void m_free(struct mbuf *); -void m_cat(register struct mbuf *, register struct mbuf *); -void m_inc(struct mbuf *, int); -void m_adj(struct mbuf *, int); -int m_copy(struct mbuf *, struct mbuf *, int, int); -struct mbuf *m_dup(Slirp *slirp, struct mbuf *m, bool copy_header, size_t header_size); -struct mbuf *dtom(Slirp *, void *); -void *mtod_check(struct mbuf *, size_t len); -void *m_end(struct mbuf *); - -static inline void ifs_init(struct mbuf *ifm) -{ - ifm->ifs_next = ifm->ifs_prev = ifm; -} - -#ifdef SLIRP_DEBUG -# define MBUF_DEBUG 1 -#else -# ifdef HAVE_VALGRIND -# include -# define MBUF_DEBUG RUNNING_ON_VALGRIND -# else -# define MBUF_DEBUG 0 -# endif -#endif - -/* - * When a function is given an mbuf as well as the responsibility to free it, we - * want valgrind etc. to properly identify the new responsible for the - * free. Achieve this by making a new copy. For instance: - * - * f0(void) { - * struct mbuf *m = m_get(slirp); - * [...] - * switch (something) { - * case 1: - * f1(m); - * break; - * case 2: - * f2(m); - * break; - * [...] - * } - * } - * - * f1(struct mbuf *m) { - * M_DUP_DEBUG(m->slirp, m); - * [...] - * m_free(m); // but author of f1 might be forgetting this - * } - * - * f0 transfers the freeing responsibility to f1, f2, etc. Without the - * M_DUP_DEBUG call in f1, valgrind would tell us that it is f0 where the buffer - * was allocated, but it's difficult to know whether a leak is actually in f0, - * or in f1, or in f2, etc. Duplicating the mbuf in M_DUP_DEBUG each time the - * responsibility is transferred allows to immediately know where the leak - * actually is. - */ -#define M_DUP_DEBUG(slirp, m, copy_header, header_size) do { \ - if (MBUF_DEBUG) { \ - struct mbuf *__n; \ - __n = m_dup((slirp), (m), (copy_header), (header_size)); \ - m_free(m); \ - (m) = __n; \ - } else { \ - (void) (slirp); (void) (copy_header); \ - g_assert(M_ROOMBEFORE(m) >= (header_size)); \ - } \ -} while(0) - -#endif diff --git a/src/network/slirp/misc.c b/src/network/slirp/misc.c deleted file mode 100644 index 220506328f..0000000000 --- a/src/network/slirp/misc.c +++ /dev/null @@ -1,459 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" -#include -#ifdef G_OS_UNIX -#include -#include -#ifdef BSD -#define g_strlcpy strlcpy -#else -extern gsize g_strlcpy(gchar* dest, const gchar* src, gsize dest_size); -#endif -#endif - -#ifdef __APPLE__ -#include -#endif - -extern inline void slirp_insque(void *a, void *b) -{ - register struct slirp_quehead *element = (struct slirp_quehead *)a; - register struct slirp_quehead *head = (struct slirp_quehead *)b; - element->qh_link = head->qh_link; - head->qh_link = (struct slirp_quehead *)element; - element->qh_rlink = (struct slirp_quehead *)head; - ((struct slirp_quehead *)(element->qh_link))->qh_rlink = - (struct slirp_quehead *)element; -} - -extern inline void slirp_remque(void *a) -{ - register struct slirp_quehead *element = (struct slirp_quehead *)a; - ((struct slirp_quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct slirp_quehead *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = NULL; -} - -/* TODO: IPv6 */ -struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, - void *opaque, struct in_addr addr, int port) -{ - struct gfwd_list *f = g_new0(struct gfwd_list, 1); - - f->write_cb = write_cb; - f->opaque = opaque; - f->ex_fport = port; - f->ex_addr = addr; - f->ex_next = *ex_ptr; - *ex_ptr = f; - - return f; -} - -struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline, - struct in_addr addr, int port) -{ - struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port); - - f->ex_exec = g_strdup(cmdline); - - return f; -} - -struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, - struct in_addr addr, int port) -{ - struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port); - - f->ex_unix = g_strdup(unixsock); - - return f; -} - -int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port) -{ - for (; *ex_ptr != NULL; ex_ptr = &((*ex_ptr)->ex_next)) { - struct gfwd_list *f = *ex_ptr; - if (f->ex_addr.s_addr == addr.s_addr && f->ex_fport == port) { - *ex_ptr = f->ex_next; - g_free(f->ex_exec); - g_free(f); - return 0; - } - } - return -1; -} - -static int slirp_socketpair_with_oob(int sv[2]) -{ - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = 0, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; - socklen_t addrlen = sizeof(addr); - int ret, s; - - sv[1] = -1; - s = slirp_socket(AF_INET, SOCK_STREAM, 0); - if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 || - listen(s, 1) < 0 || - getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) { - goto err; - } - - sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0); - if (sv[1] < 0) { - goto err; - } - /* - * This connect won't block because we've already listen()ed on - * the server end (even though we won't accept() the connection - * until later on). - */ - do { - ret = connect(sv[1], (struct sockaddr *)&addr, addrlen); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { - goto err; - } - - do { - sv[0] = accept(s, (struct sockaddr *)&addr, &addrlen); - } while (sv[0] < 0 && errno == EINTR); - if (sv[0] < 0) { - goto err; - } - - closesocket(s); - return 0; - -err: - g_critical("slirp_socketpair(): %s", strerror(errno)); - if (s >= 0) { - closesocket(s); - } - if (sv[1] >= 0) { - closesocket(sv[1]); - } - return -1; -} - -static void fork_exec_child_setup(gpointer data) -{ -#ifndef _WIN32 - setsid(); - - /* Unblock all signals and leave our exec()-ee to block what it wants */ - sigset_t ss; - sigemptyset(&ss); - sigprocmask(SIG_SETMASK, &ss, NULL); - - /* POSIX is obnoxious about SIGCHLD specifically across exec() */ - signal(SIGCHLD, SIG_DFL); -#endif -} - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -#if !GLIB_CHECK_VERSION(2, 58, 0) -typedef struct SlirpGSpawnFds { - GSpawnChildSetupFunc child_setup; - gpointer user_data; - gint stdin_fd; - gint stdout_fd; - gint stderr_fd; -} SlirpGSpawnFds; - -static inline void slirp_gspawn_fds_setup(gpointer user_data) -{ - SlirpGSpawnFds *q = (SlirpGSpawnFds *)user_data; - - dup2(q->stdin_fd, 0); - dup2(q->stdout_fd, 1); - dup2(q->stderr_fd, 2); - q->child_setup(q->user_data); -} -#endif - -static inline gboolean -g_spawn_async_with_fds_slirp(const gchar *working_directory, gchar **argv, - gchar **envp, GSpawnFlags flags, - GSpawnChildSetupFunc child_setup, - gpointer user_data, GPid *child_pid, gint stdin_fd, - gint stdout_fd, gint stderr_fd, GError **error) -{ -#if GLIB_CHECK_VERSION(2, 58, 0) - return g_spawn_async_with_fds(working_directory, argv, envp, flags, - child_setup, user_data, child_pid, stdin_fd, - stdout_fd, stderr_fd, error); -#else - SlirpGSpawnFds setup = { - .child_setup = child_setup, - .user_data = user_data, - .stdin_fd = stdin_fd, - .stdout_fd = stdout_fd, - .stderr_fd = stderr_fd, - }; - - return g_spawn_async(working_directory, argv, envp, flags, - slirp_gspawn_fds_setup, &setup, child_pid, error); -#endif -} - -#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \ - g_spawn_async_with_fds_slirp(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - -int fork_exec(struct socket *so, const char *ex) -{ - GError *err = NULL; - gint argc = 0; - gchar **argv = NULL; - int opt, sp[2]; - - DEBUG_CALL("fork_exec"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("ex = %p", ex); - - if (slirp_socketpair_with_oob(sp) < 0) { - return 0; - } - - if (!g_shell_parse_argv(ex, &argc, &argv, &err)) { - g_critical("fork_exec invalid command: %s\nerror: %s", ex, err->message); - g_error_free(err); - return 0; - } - - g_spawn_async_with_fds(NULL /* cwd */, argv, NULL /* env */, - G_SPAWN_SEARCH_PATH, fork_exec_child_setup, - NULL /* data */, NULL /* child_pid */, sp[1], sp[1], - sp[1], &err); - g_strfreev(argv); - - if (err) { - g_critical("fork_exec: %s", err->message); - g_error_free(err); - closesocket(sp[0]); - closesocket(sp[1]); - return 0; - } - - so->s = sp[0]; - closesocket(sp[1]); - slirp_socket_set_fast_reuse(so->s); - opt = 1; - setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int)); - slirp_set_nonblock(so->s); - so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); - return 1; -} - -int open_unix(struct socket *so, const char *unixpath) -{ -#ifdef G_OS_UNIX - struct sockaddr_un sa; - int s; - - DEBUG_CALL("open_unix"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("unixpath = %s", unixpath); - - memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - if (g_strlcpy(sa.sun_path, unixpath, sizeof(sa.sun_path)) >= sizeof(sa.sun_path)) { - g_critical("Bad unix path: %s", unixpath); - return 0; - } - - s = slirp_socket(PF_UNIX, SOCK_STREAM, 0); - if (s < 0) { - g_critical("open_unix(): %s", strerror(errno)); - return 0; - } - - if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { - g_critical("open_unix(): %s", strerror(errno)); - closesocket(s); - return 0; - } - - so->s = s; - slirp_set_nonblock(so->s); - so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); - - return 1; -#else - g_assert_not_reached(); -#endif -} - -char *slirp_connection_info(Slirp *slirp) -{ - GString *str = g_string_new(NULL); - const char *const tcpstates[] = { - [TCPS_CLOSED] = "CLOSED", [TCPS_LISTEN] = "LISTEN", - [TCPS_SYN_SENT] = "SYN_SENT", [TCPS_SYN_RECEIVED] = "SYN_RCVD", - [TCPS_ESTABLISHED] = "ESTABLISHED", [TCPS_CLOSE_WAIT] = "CLOSE_WAIT", - [TCPS_FIN_WAIT_1] = "FIN_WAIT_1", [TCPS_CLOSING] = "CLOSING", - [TCPS_LAST_ACK] = "LAST_ACK", [TCPS_FIN_WAIT_2] = "FIN_WAIT_2", - [TCPS_TIME_WAIT] = "TIME_WAIT", - }; - struct in_addr dst_addr; - struct sockaddr_in src; - socklen_t src_len; - uint16_t dst_port; - struct socket *so; - const char *state; - char addr[INET_ADDRSTRLEN]; - char buf[20]; - - g_string_append_printf(str, - " Protocol[State] FD Source Address Port " - "Dest. Address Port RecvQ SendQ\n"); - - /* TODO: IPv6 */ - - for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) { - if (so->so_state & SS_HOSTFWD) { - state = "HOST_FORWARD"; - } else if (so->so_tcpcb) { - state = tcpstates[so->so_tcpcb->t_state]; - } else { - state = "NONE"; - } - if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) { - src_len = sizeof(src); - getsockname(so->s, (struct sockaddr *)&src, &src_len); - dst_addr = so->so_laddr; - dst_port = so->so_lport; - } else { - src.sin_addr = so->so_laddr; - src.sin_port = so->so_lport; - dst_addr = so->so_faddr; - dst_port = so->so_fport; - } - slirp_fmt0(buf, sizeof(buf), " TCP[%s]", state); - g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s, - src.sin_addr.s_addr ? - inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*", - ntohs(src.sin_port)); - g_string_append_printf(str, "%15s %5d %5d %5d\n", - inet_ntop(AF_INET, &dst_addr, addr, sizeof(addr)), - ntohs(dst_port), so->so_rcv.sb_cc, - so->so_snd.sb_cc); - } - - for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) { - if (so->so_state & SS_HOSTFWD) { - slirp_fmt0(buf, sizeof(buf), " UDP[HOST_FORWARD]"); - src_len = sizeof(src); - getsockname(so->s, (struct sockaddr *)&src, &src_len); - dst_addr = so->so_laddr; - dst_port = so->so_lport; - } else { - slirp_fmt0(buf, sizeof(buf), " UDP[%d sec]", - (so->so_expire - curtime) / 1000); - src.sin_addr = so->so_laddr; - src.sin_port = so->so_lport; - dst_addr = so->so_faddr; - dst_port = so->so_fport; - } - g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s, - src.sin_addr.s_addr ? - inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*", - ntohs(src.sin_port)); - g_string_append_printf(str, "%15s %5d %5d %5d\n", - inet_ntop(AF_INET, &dst_addr, addr, sizeof(addr)), - ntohs(dst_port), so->so_rcv.sb_cc, - so->so_snd.sb_cc); - } - - for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) { - slirp_fmt0(buf, sizeof(buf), " ICMP[%d sec]", - (so->so_expire - curtime) / 1000); - src.sin_addr = so->so_laddr; - dst_addr = so->so_faddr; - g_string_append_printf(str, "%-19s %3d %15s - ", buf, so->s, - src.sin_addr.s_addr ? - inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*"); - g_string_append_printf(str, "%15s - %5d %5d\n", - inet_ntop(AF_INET, &dst_addr, addr, sizeof(addr)), - so->so_rcv.sb_cc, so->so_snd.sb_cc); - } - - return g_string_free(str, false); -} - -char *slirp_neighbor_info(Slirp *slirp) -{ - GString *str = g_string_new(NULL); - ArpTable *arp_table = &slirp->arp_table; - NdpTable *ndp_table = &slirp->ndp_table; - char ip_addr[INET6_ADDRSTRLEN]; - char eth_addr[ETH_ADDRSTRLEN]; - const char *ip; - - g_string_append_printf(str, " %5s %-17s %s\n", - "Table", "MacAddr", "IP Address"); - - for (int i = 0; i < ARP_TABLE_SIZE; ++i) { - struct in_addr addr; - addr.s_addr = arp_table->table[i].ar_sip; - if (!addr.s_addr) { - continue; - } - ip = inet_ntop(AF_INET, &addr, ip_addr, sizeof(ip_addr)); - g_assert(ip != NULL); - g_string_append_printf(str, " %5s %-17s %s\n", "ARP", - slirp_ether_ntoa(arp_table->table[i].ar_sha, - eth_addr, sizeof(eth_addr)), - ip); - } - - for (int i = 0; i < NDP_TABLE_SIZE; ++i) { - if (in6_zero(&ndp_table->table[i].ip_addr)) { - continue; - } - ip = inet_ntop(AF_INET6, &ndp_table->table[i].ip_addr, ip_addr, - sizeof(ip_addr)); - g_assert(ip != NULL); - g_string_append_printf(str, " %5s %-17s %s\n", "NDP", - slirp_ether_ntoa(ndp_table->table[i].eth_addr, - eth_addr, sizeof(eth_addr)), - ip); - } - - return g_string_free(str, false); -} - -int slirp_bind_outbound(struct socket *so, unsigned short af) -{ - int ret = 0; - struct sockaddr *addr = NULL; - int addr_size = 0; - - if (af == AF_INET && so->slirp->outbound_addr != NULL) { - addr = (struct sockaddr *)so->slirp->outbound_addr; - addr_size = sizeof(struct sockaddr_in); - } else if (af == AF_INET6 && so->slirp->outbound_addr6 != NULL) { - addr = (struct sockaddr *)so->slirp->outbound_addr6; - addr_size = sizeof(struct sockaddr_in6); - } - - if (addr != NULL) { - ret = bind(so->s, addr, addr_size); - } - return ret; -} diff --git a/src/network/slirp/misc.h b/src/network/slirp/misc.h deleted file mode 100644 index 81b370cfb1..0000000000 --- a/src/network/slirp/misc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef MISC_H -#define MISC_H - -#include "libslirp.h" - -struct gfwd_list { - SlirpWriteCb write_cb; - void *opaque; - struct in_addr ex_addr; /* Server address */ - int ex_fport; /* Port to telnet to */ - char *ex_exec; /* Command line of what to exec */ - char *ex_unix; /* unix socket */ - struct gfwd_list *ex_next; -}; - -#define EMU_NONE 0x0 - -/* TCP emulations */ -#define EMU_CTL 0x1 -#define EMU_FTP 0x2 -#define EMU_KSH 0x3 -#define EMU_IRC 0x4 -#define EMU_REALAUDIO 0x5 -#define EMU_RLOGIN 0x6 -#define EMU_IDENT 0x7 - -#define EMU_NOCONNECT 0x10 /* Don't connect */ - -struct tos_t { - uint16_t lport; - uint16_t fport; - uint8_t tos; - uint8_t emu; -}; - -struct emu_t { - uint16_t lport; - uint16_t fport; - uint8_t tos; - uint8_t emu; - struct emu_t *next; -}; - -struct slirp_quehead { - struct slirp_quehead *qh_link; - struct slirp_quehead *qh_rlink; -}; - -void slirp_insque(void *, void *); -void slirp_remque(void *); -int fork_exec(struct socket *so, const char *ex); -int open_unix(struct socket *so, const char *unixsock); - -struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, - void *opaque, struct in_addr addr, int port); - -struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline, - struct in_addr addr, int port); - -struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, - struct in_addr addr, int port); - -int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port); - -int slirp_bind_outbound(struct socket *so, unsigned short af); - -#endif diff --git a/src/network/slirp/ncsi-pkt.h b/src/network/slirp/ncsi-pkt.h deleted file mode 100644 index 7694e68ff3..0000000000 --- a/src/network/slirp/ncsi-pkt.h +++ /dev/null @@ -1,616 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright Gavin Shan, IBM Corporation 2016. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NCSI_PKT_H -#define NCSI_PKT_H - -/* from linux/net/ncsi/ncsi-pkt.h */ -#define __be32 uint32_t -#define __be16 uint16_t - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_pkt_hdr { - unsigned char mc_id; /* Management controller ID */ - unsigned char revision; /* NCSI version - 0x01 */ - unsigned char reserved; /* Reserved */ - unsigned char id; /* Packet sequence number */ - unsigned char type; /* Packet type */ - unsigned char channel; /* Network controller ID */ - __be16 length; /* Payload length */ - __be32 reserved1[2]; /* Reserved */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_pkt_hdr { - struct ncsi_pkt_hdr common; /* Common NCSI packet header */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_pkt_hdr { - struct ncsi_pkt_hdr common; /* Common NCSI packet header */ - __be16 code; /* Response code */ - __be16 reason; /* Response reason */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_aen_pkt_hdr { - struct ncsi_pkt_hdr common; /* Common NCSI packet header */ - unsigned char reserved2[3]; /* Reserved */ - unsigned char type; /* AEN packet type */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* NCSI common command packet */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be32 checksum; /* Checksum */ - unsigned char pad[26]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Select Package */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_sp_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char reserved[3]; /* Reserved */ - unsigned char hw_arbitration; /* HW arbitration */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Disable Channel */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_dc_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char reserved[3]; /* Reserved */ - unsigned char ald; /* Allow link down */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Reset Channel */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_rc_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be32 reserved; /* Reserved */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* AEN Enable */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_ae_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char reserved[3]; /* Reserved */ - unsigned char mc_id; /* MC ID */ - __be32 mode; /* AEN working mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[18]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Set Link */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_sl_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be32 mode; /* Link working mode */ - __be32 oem_mode; /* OEM link mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[18]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Set VLAN Filter */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_svf_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be16 reserved; /* Reserved */ - __be16 vlan; /* VLAN ID */ - __be16 reserved1; /* Reserved */ - unsigned char index; /* VLAN table index */ - unsigned char enable; /* Enable or disable */ - __be32 checksum; /* Checksum */ - unsigned char pad[14]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Enable VLAN */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_ev_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char reserved[3]; /* Reserved */ - unsigned char mode; /* VLAN filter mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Set MAC Address */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_sma_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char mac[6]; /* MAC address */ - unsigned char index; /* MAC table index */ - unsigned char at_e; /* Addr type and operation */ - __be32 checksum; /* Checksum */ - unsigned char pad[18]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Enable Broadcast Filter */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_ebf_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be32 mode; /* Filter mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Enable Global Multicast Filter */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_cmd_egmf_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - __be32 mode; /* Global MC mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Set NCSI Flow Control */ -struct ncsi_cmd_snfc_pkt { - struct ncsi_cmd_pkt_hdr cmd; /* Command header */ - unsigned char reserved[3]; /* Reserved */ - unsigned char mode; /* Flow control mode */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get Link Status */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gls_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 status; /* Link status */ - __be32 other; /* Other indications */ - __be32 oem_status; /* OEM link status */ - __be32 checksum; - unsigned char pad[10]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get Version ID */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gvi_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 ncsi_version; /* NCSI version */ - unsigned char reserved[3]; /* Reserved */ - unsigned char alpha2; /* NCSI version */ - unsigned char fw_name[12]; /* f/w name string */ - __be32 fw_version; /* f/w version */ - __be16 pci_ids[4]; /* PCI IDs */ - __be32 mf_id; /* Manufacture ID */ - __be32 checksum; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get Capabilities */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gc_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 cap; /* Capabilities */ - __be32 bc_cap; /* Broadcast cap */ - __be32 mc_cap; /* Multicast cap */ - __be32 buf_cap; /* Buffering cap */ - __be32 aen_cap; /* AEN cap */ - unsigned char vlan_cnt; /* VLAN filter count */ - unsigned char mixed_cnt; /* Mix filter count */ - unsigned char mc_cnt; /* MC filter count */ - unsigned char uc_cnt; /* UC filter count */ - unsigned char reserved[2]; /* Reserved */ - unsigned char vlan_mode; /* VLAN mode */ - unsigned char channel_cnt; /* Channel count */ - __be32 checksum; /* Checksum */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get Parameters */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gp_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - unsigned char mac_cnt; /* Number of MAC addr */ - unsigned char reserved[2]; /* Reserved */ - unsigned char mac_enable; /* MAC addr enable flags */ - unsigned char vlan_cnt; /* VLAN tag count */ - unsigned char reserved1; /* Reserved */ - __be16 vlan_enable; /* VLAN tag enable flags */ - __be32 link_mode; /* Link setting */ - __be32 bc_mode; /* BC filter mode */ - __be32 valid_modes; /* Valid mode parameters */ - unsigned char vlan_mode; /* VLAN mode */ - unsigned char fc_mode; /* Flow control mode */ - unsigned char reserved2[2]; /* Reserved */ - __be32 aen_mode; /* AEN mode */ - unsigned char mac[6]; /* Supported MAC addr */ - __be16 vlan; /* Supported VLAN tags */ - __be32 checksum; /* Checksum */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get Controller Packet Statistics */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gcps_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 cnt_hi; /* Counter cleared */ - __be32 cnt_lo; /* Counter cleared */ - __be32 rx_bytes; /* Rx bytes */ - __be32 tx_bytes; /* Tx bytes */ - __be32 rx_uc_pkts; /* Rx UC packets */ - __be32 rx_mc_pkts; /* Rx MC packets */ - __be32 rx_bc_pkts; /* Rx BC packets */ - __be32 tx_uc_pkts; /* Tx UC packets */ - __be32 tx_mc_pkts; /* Tx MC packets */ - __be32 tx_bc_pkts; /* Tx BC packets */ - __be32 fcs_err; /* FCS errors */ - __be32 align_err; /* Alignment errors */ - __be32 false_carrier; /* False carrier detection */ - __be32 runt_pkts; /* Rx runt packets */ - __be32 jabber_pkts; /* Rx jabber packets */ - __be32 rx_pause_xon; /* Rx pause XON frames */ - __be32 rx_pause_xoff; /* Rx XOFF frames */ - __be32 tx_pause_xon; /* Tx XON frames */ - __be32 tx_pause_xoff; /* Tx XOFF frames */ - __be32 tx_s_collision; /* Single collision frames */ - __be32 tx_m_collision; /* Multiple collision frames */ - __be32 l_collision; /* Late collision frames */ - __be32 e_collision; /* Excessive collision frames */ - __be32 rx_ctl_frames; /* Rx control frames */ - __be32 rx_64_frames; /* Rx 64-bytes frames */ - __be32 rx_127_frames; /* Rx 65-127 bytes frames */ - __be32 rx_255_frames; /* Rx 128-255 bytes frames */ - __be32 rx_511_frames; /* Rx 256-511 bytes frames */ - __be32 rx_1023_frames; /* Rx 512-1023 bytes frames */ - __be32 rx_1522_frames; /* Rx 1024-1522 bytes frames */ - __be32 rx_9022_frames; /* Rx 1523-9022 bytes frames */ - __be32 tx_64_frames; /* Tx 64-bytes frames */ - __be32 tx_127_frames; /* Tx 65-127 bytes frames */ - __be32 tx_255_frames; /* Tx 128-255 bytes frames */ - __be32 tx_511_frames; /* Tx 256-511 bytes frames */ - __be32 tx_1023_frames; /* Tx 512-1023 bytes frames */ - __be32 tx_1522_frames; /* Tx 1024-1522 bytes frames */ - __be32 tx_9022_frames; /* Tx 1523-9022 bytes frames */ - __be32 rx_valid_bytes; /* Rx valid bytes */ - __be32 rx_runt_pkts; /* Rx error runt packets */ - __be32 rx_jabber_pkts; /* Rx error jabber packets */ - __be32 checksum; /* Checksum */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get NCSI Statistics */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gns_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 rx_cmds; /* Rx NCSI commands */ - __be32 dropped_cmds; /* Dropped commands */ - __be32 cmd_type_errs; /* Command type errors */ - __be32 cmd_csum_errs; /* Command checksum errors */ - __be32 rx_pkts; /* Rx NCSI packets */ - __be32 tx_pkts; /* Tx NCSI packets */ - __be32 tx_aen_pkts; /* Tx AEN packets */ - __be32 checksum; /* Checksum */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get NCSI Pass-through Statistics */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gnpts_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 tx_pkts; /* Tx packets */ - __be32 tx_dropped; /* Tx dropped packets */ - __be32 tx_channel_err; /* Tx channel errors */ - __be32 tx_us_err; /* Tx undersize errors */ - __be32 rx_pkts; /* Rx packets */ - __be32 rx_dropped; /* Rx dropped packets */ - __be32 rx_channel_err; /* Rx channel errors */ - __be32 rx_us_err; /* Rx undersize errors */ - __be32 rx_os_err; /* Rx oversize errors */ - __be32 checksum; /* Checksum */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get package status */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gps_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - __be32 status; /* Hardware arbitration status */ - __be32 checksum; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* Get package UUID */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_rsp_gpuuid_pkt { - struct ncsi_rsp_pkt_hdr rsp; /* Response header */ - unsigned char uuid[16]; /* UUID */ - __be32 checksum; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* AEN: Link State Change */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_aen_lsc_pkt { - struct ncsi_aen_pkt_hdr aen; /* AEN header */ - __be32 status; /* Link status */ - __be32 oem_status; /* OEM link status */ - __be32 checksum; /* Checksum */ - unsigned char pad[14]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* AEN: Configuration Required */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_aen_cr_pkt { - struct ncsi_aen_pkt_hdr aen; /* AEN header */ - __be32 checksum; /* Checksum */ - unsigned char pad[22]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* AEN: Host Network Controller Driver Status Change */ -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct ncsi_aen_hncdsc_pkt { - struct ncsi_aen_pkt_hdr aen; /* AEN header */ - __be32 status; /* Status */ - __be32 checksum; /* Checksum */ - unsigned char pad[18]; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -/* NCSI packet revision */ -#define NCSI_PKT_REVISION 0x01 - -/* NCSI packet commands */ -#define NCSI_PKT_CMD_CIS 0x00 /* Clear Initial State */ -#define NCSI_PKT_CMD_SP 0x01 /* Select Package */ -#define NCSI_PKT_CMD_DP 0x02 /* Deselect Package */ -#define NCSI_PKT_CMD_EC 0x03 /* Enable Channel */ -#define NCSI_PKT_CMD_DC 0x04 /* Disable Channel */ -#define NCSI_PKT_CMD_RC 0x05 /* Reset Channel */ -#define NCSI_PKT_CMD_ECNT 0x06 /* Enable Channel Network Tx */ -#define NCSI_PKT_CMD_DCNT 0x07 /* Disable Channel Network Tx */ -#define NCSI_PKT_CMD_AE 0x08 /* AEN Enable */ -#define NCSI_PKT_CMD_SL 0x09 /* Set Link */ -#define NCSI_PKT_CMD_GLS 0x0a /* Get Link */ -#define NCSI_PKT_CMD_SVF 0x0b /* Set VLAN Filter */ -#define NCSI_PKT_CMD_EV 0x0c /* Enable VLAN */ -#define NCSI_PKT_CMD_DV 0x0d /* Disable VLAN */ -#define NCSI_PKT_CMD_SMA 0x0e /* Set MAC address */ -#define NCSI_PKT_CMD_EBF 0x10 /* Enable Broadcast Filter */ -#define NCSI_PKT_CMD_DBF 0x11 /* Disable Broadcast Filter */ -#define NCSI_PKT_CMD_EGMF 0x12 /* Enable Global Multicast Filter */ -#define NCSI_PKT_CMD_DGMF 0x13 /* Disable Global Multicast Filter */ -#define NCSI_PKT_CMD_SNFC 0x14 /* Set NCSI Flow Control */ -#define NCSI_PKT_CMD_GVI 0x15 /* Get Version ID */ -#define NCSI_PKT_CMD_GC 0x16 /* Get Capabilities */ -#define NCSI_PKT_CMD_GP 0x17 /* Get Parameters */ -#define NCSI_PKT_CMD_GCPS 0x18 /* Get Controller Packet Statistics */ -#define NCSI_PKT_CMD_GNS 0x19 /* Get NCSI Statistics */ -#define NCSI_PKT_CMD_GNPTS 0x1a /* Get NCSI Pass-throu Statistics */ -#define NCSI_PKT_CMD_GPS 0x1b /* Get package status */ -#define NCSI_PKT_CMD_OEM 0x50 /* OEM */ -#define NCSI_PKT_CMD_PLDM 0x51 /* PLDM request over NCSI over RBT */ -#define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */ - -/* NCSI packet responses */ -#define NCSI_PKT_RSP_CIS (NCSI_PKT_CMD_CIS + 0x80) -#define NCSI_PKT_RSP_SP (NCSI_PKT_CMD_SP + 0x80) -#define NCSI_PKT_RSP_DP (NCSI_PKT_CMD_DP + 0x80) -#define NCSI_PKT_RSP_EC (NCSI_PKT_CMD_EC + 0x80) -#define NCSI_PKT_RSP_DC (NCSI_PKT_CMD_DC + 0x80) -#define NCSI_PKT_RSP_RC (NCSI_PKT_CMD_RC + 0x80) -#define NCSI_PKT_RSP_ECNT (NCSI_PKT_CMD_ECNT + 0x80) -#define NCSI_PKT_RSP_DCNT (NCSI_PKT_CMD_DCNT + 0x80) -#define NCSI_PKT_RSP_AE (NCSI_PKT_CMD_AE + 0x80) -#define NCSI_PKT_RSP_SL (NCSI_PKT_CMD_SL + 0x80) -#define NCSI_PKT_RSP_GLS (NCSI_PKT_CMD_GLS + 0x80) -#define NCSI_PKT_RSP_SVF (NCSI_PKT_CMD_SVF + 0x80) -#define NCSI_PKT_RSP_EV (NCSI_PKT_CMD_EV + 0x80) -#define NCSI_PKT_RSP_DV (NCSI_PKT_CMD_DV + 0x80) -#define NCSI_PKT_RSP_SMA (NCSI_PKT_CMD_SMA + 0x80) -#define NCSI_PKT_RSP_EBF (NCSI_PKT_CMD_EBF + 0x80) -#define NCSI_PKT_RSP_DBF (NCSI_PKT_CMD_DBF + 0x80) -#define NCSI_PKT_RSP_EGMF (NCSI_PKT_CMD_EGMF + 0x80) -#define NCSI_PKT_RSP_DGMF (NCSI_PKT_CMD_DGMF + 0x80) -#define NCSI_PKT_RSP_SNFC (NCSI_PKT_CMD_SNFC + 0x80) -#define NCSI_PKT_RSP_GVI (NCSI_PKT_CMD_GVI + 0x80) -#define NCSI_PKT_RSP_GC (NCSI_PKT_CMD_GC + 0x80) -#define NCSI_PKT_RSP_GP (NCSI_PKT_CMD_GP + 0x80) -#define NCSI_PKT_RSP_GCPS (NCSI_PKT_CMD_GCPS + 0x80) -#define NCSI_PKT_RSP_GNS (NCSI_PKT_CMD_GNS + 0x80) -#define NCSI_PKT_RSP_GNPTS (NCSI_PKT_CMD_GNPTS + 0x80) -#define NCSI_PKT_RSP_GPS (NCSI_PKT_CMD_GPS + 0x80) -#define NCSI_PKT_RSP_OEM (NCSI_PKT_CMD_OEM + 0x80) -#define NCSI_PKT_RSP_PLDM (NCSI_PKT_CMD_PLDM + 0x80) -#define NCSI_PKT_RSP_GPUUID (NCSI_PKT_CMD_GPUUID + 0x80) - -/* NCSI response code/reason */ -#define NCSI_PKT_RSP_C_COMPLETED 0x0000 /* Command Completed */ -#define NCSI_PKT_RSP_C_FAILED 0x0001 /* Command Failed */ -#define NCSI_PKT_RSP_C_UNAVAILABLE 0x0002 /* Command Unavailable */ -#define NCSI_PKT_RSP_C_UNSUPPORTED 0x0003 /* Command Unsupported */ -#define NCSI_PKT_RSP_R_NO_ERROR 0x0000 /* No Error */ -#define NCSI_PKT_RSP_R_INTERFACE 0x0001 /* Interface not ready */ -#define NCSI_PKT_RSP_R_PARAM 0x0002 /* Invalid Parameter */ -#define NCSI_PKT_RSP_R_CHANNEL 0x0003 /* Channel not Ready */ -#define NCSI_PKT_RSP_R_PACKAGE 0x0004 /* Package not Ready */ -#define NCSI_PKT_RSP_R_LENGTH 0x0005 /* Invalid payload length */ -#define NCSI_PKT_RSP_R_UNKNOWN 0x7fff /* Command type unsupported */ - -/* NCSI AEN packet type */ -#define NCSI_PKT_AEN 0xFF /* AEN Packet */ -#define NCSI_PKT_AEN_LSC 0x00 /* Link status change */ -#define NCSI_PKT_AEN_CR 0x01 /* Configuration required */ -#define NCSI_PKT_AEN_HNCDSC 0x02 /* HNC driver status change */ - -#endif /* NCSI_PKT_H */ diff --git a/src/network/slirp/ncsi.c b/src/network/slirp/ncsi.c deleted file mode 100644 index f3427bd66d..0000000000 --- a/src/network/slirp/ncsi.c +++ /dev/null @@ -1,197 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * NC-SI (Network Controller Sideband Interface) "echo" model - * - * Copyright (C) 2016-2018 IBM Corp. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "slirp.h" - -#include "ncsi-pkt.h" - -static uint32_t ncsi_calculate_checksum(uint8_t *data, int len) -{ - uint32_t checksum = 0; - int i; - - /* - * 32-bit unsigned sum of the NC-SI packet header and NC-SI packet - * payload interpreted as a series of 16-bit unsigned integer values. - */ - for (i = 0; i < len; i += 2) { - checksum += (((uint16_t) data[i]) << 8) + data[i+1]; - } - - checksum = (~checksum + 1); - return checksum; -} - -/* Get Capabilities */ -static int ncsi_rsp_handler_gc(struct ncsi_rsp_pkt_hdr *rnh) -{ - struct ncsi_rsp_gc_pkt *rsp = (struct ncsi_rsp_gc_pkt *)rnh; - - rsp->cap = htonl(~0); - rsp->bc_cap = htonl(~0); - rsp->mc_cap = htonl(~0); - rsp->buf_cap = htonl(~0); - rsp->aen_cap = htonl(~0); - rsp->vlan_mode = 0xff; - rsp->uc_cnt = 2; - return 0; -} - -/* Get Link status */ -static int ncsi_rsp_handler_gls(struct ncsi_rsp_pkt_hdr *rnh) -{ - struct ncsi_rsp_gls_pkt *rsp = (struct ncsi_rsp_gls_pkt *)rnh; - - rsp->status = htonl(0x1); - return 0; -} - -/* Get Parameters */ -static int ncsi_rsp_handler_gp(struct ncsi_rsp_pkt_hdr *rnh) -{ - struct ncsi_rsp_gp_pkt *rsp = (struct ncsi_rsp_gp_pkt *)rnh; - - /* no MAC address filters or VLAN filters on the channel */ - rsp->mac_cnt = 0; - rsp->mac_enable = 0; - rsp->vlan_cnt = 0; - rsp->vlan_enable = 0; - - return 0; -} - -static const struct ncsi_rsp_handler { - unsigned char type; - int payload; - int (*handler)(struct ncsi_rsp_pkt_hdr *rnh); -} ncsi_rsp_handlers[] = { { NCSI_PKT_RSP_CIS, 4, NULL }, - { NCSI_PKT_RSP_SP, 4, NULL }, - { NCSI_PKT_RSP_DP, 4, NULL }, - { NCSI_PKT_RSP_EC, 4, NULL }, - { NCSI_PKT_RSP_DC, 4, NULL }, - { NCSI_PKT_RSP_RC, 4, NULL }, - { NCSI_PKT_RSP_ECNT, 4, NULL }, - { NCSI_PKT_RSP_DCNT, 4, NULL }, - { NCSI_PKT_RSP_AE, 4, NULL }, - { NCSI_PKT_RSP_SL, 4, NULL }, - { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls }, - { NCSI_PKT_RSP_SVF, 4, NULL }, - { NCSI_PKT_RSP_EV, 4, NULL }, - { NCSI_PKT_RSP_DV, 4, NULL }, - { NCSI_PKT_RSP_SMA, 4, NULL }, - { NCSI_PKT_RSP_EBF, 4, NULL }, - { NCSI_PKT_RSP_DBF, 4, NULL }, - { NCSI_PKT_RSP_EGMF, 4, NULL }, - { NCSI_PKT_RSP_DGMF, 4, NULL }, - { NCSI_PKT_RSP_SNFC, 4, NULL }, - { NCSI_PKT_RSP_GVI, 40, NULL }, - { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc }, - { NCSI_PKT_RSP_GP, 40, ncsi_rsp_handler_gp }, - { NCSI_PKT_RSP_GCPS, 172, NULL }, - { NCSI_PKT_RSP_GNS, 172, NULL }, - { NCSI_PKT_RSP_GNPTS, 172, NULL }, - { NCSI_PKT_RSP_GPS, 8, NULL }, - { NCSI_PKT_RSP_OEM, 0, NULL }, - { NCSI_PKT_RSP_PLDM, 0, NULL }, - { NCSI_PKT_RSP_GPUUID, 20, NULL } }; - -/* - * packet format : ncsi header + payload + checksum - */ -#define NCSI_MAX_PAYLOAD 172 -#define NCSI_MAX_LEN (sizeof(struct ncsi_pkt_hdr) + NCSI_MAX_PAYLOAD + 4) - -void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) -{ - const struct ncsi_pkt_hdr *nh = - (const struct ncsi_pkt_hdr *)(pkt + ETH_HLEN); - uint8_t ncsi_reply[ETH_HLEN + NCSI_MAX_LEN]; - struct ethhdr *reh = (struct ethhdr *)ncsi_reply; - struct ncsi_rsp_pkt_hdr *rnh = - (struct ncsi_rsp_pkt_hdr *)(ncsi_reply + ETH_HLEN); - const struct ncsi_rsp_handler *handler = NULL; - int i; - int ncsi_rsp_len = sizeof(*nh); - uint32_t checksum; - uint32_t *pchecksum; - - if (pkt_len < ETH_HLEN + sizeof(struct ncsi_pkt_hdr)) { - return; /* packet too short */ - } - - memset(ncsi_reply, 0, sizeof(ncsi_reply)); - - memset(reh->h_dest, 0xff, ETH_ALEN); - memset(reh->h_source, 0xff, ETH_ALEN); - reh->h_proto = htons(ETH_P_NCSI); - - for (i = 0; i < G_N_ELEMENTS(ncsi_rsp_handlers); i++) { - if (ncsi_rsp_handlers[i].type == nh->type + 0x80) { - handler = &ncsi_rsp_handlers[i]; - break; - } - } - - rnh->common.mc_id = nh->mc_id; - rnh->common.revision = NCSI_PKT_REVISION; - rnh->common.id = nh->id; - rnh->common.type = nh->type + 0x80; - rnh->common.channel = nh->channel; - - if (handler) { - rnh->common.length = htons(handler->payload); - rnh->code = htons(NCSI_PKT_RSP_C_COMPLETED); - rnh->reason = htons(NCSI_PKT_RSP_R_NO_ERROR); - - if (handler->handler) { - /* TODO: handle errors */ - handler->handler(rnh); - } - ncsi_rsp_len += handler->payload; - } else { - rnh->common.length = 0; - rnh->code = htons(NCSI_PKT_RSP_C_UNAVAILABLE); - rnh->reason = htons(NCSI_PKT_RSP_R_UNKNOWN); - } - - /* Add the optional checksum at the end of the frame. */ - checksum = ncsi_calculate_checksum((uint8_t *)rnh, ncsi_rsp_len); - pchecksum = (uint32_t *)((void *)rnh + ncsi_rsp_len); - *pchecksum = htonl(checksum); - ncsi_rsp_len += 4; - - slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len); -} diff --git a/src/network/slirp/ndp_table.c b/src/network/slirp/ndp_table.c deleted file mode 100644 index fdb189d595..0000000000 --- a/src/network/slirp/ndp_table.c +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. - */ - -#include "slirp.h" - -void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr, - uint8_t ethaddr[ETH_ALEN]) -{ - char addrstr[INET6_ADDRSTRLEN]; - NdpTable *ndp_table = &slirp->ndp_table; - int i; - char ethaddr_str[ETH_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN); - - DEBUG_CALL("ndp_table_add"); - DEBUG_ARG("ip = %s", addrstr); - DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str, - sizeof(ethaddr_str))); - - if (IN6_IS_ADDR_MULTICAST(&ip_addr) || in6_zero(&ip_addr)) { - /* Do not register multicast or unspecified addresses */ - DEBUG_CALL(" abort: do not register multicast or unspecified address"); - return; - } - - /* Search for an entry */ - for (i = 0; i < NDP_TABLE_SIZE; i++) { - if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) { - DEBUG_CALL(" already in table: update the entry"); - /* Update the entry */ - memcpy(ndp_table->table[i].eth_addr, ethaddr, ETH_ALEN); - return; - } - } - - /* No entry found, create a new one */ - DEBUG_CALL(" create new entry"); - /* Save the first entry, it is the guest. */ - if (in6_zero(&ndp_table->guest_in6_addr)) { - ndp_table->guest_in6_addr = ip_addr; - } - ndp_table->table[ndp_table->next_victim].ip_addr = ip_addr; - memcpy(ndp_table->table[ndp_table->next_victim].eth_addr, ethaddr, - ETH_ALEN); - ndp_table->next_victim = (ndp_table->next_victim + 1) % NDP_TABLE_SIZE; -} - -bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, - uint8_t out_ethaddr[ETH_ALEN]) -{ - char addrstr[INET6_ADDRSTRLEN]; - NdpTable *ndp_table = &slirp->ndp_table; - int i; - char ethaddr_str[ETH_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN); - - DEBUG_CALL("ndp_table_search"); - DEBUG_ARG("ip = %s", addrstr); - - /* If unspecified address */ - if (in6_zero(&ip_addr)) { - /* return Ethernet broadcast address */ - memset(out_ethaddr, 0xff, ETH_ALEN); - return 1; - } - - /* Multicast address: fec0::abcd:efgh/8 -> 33:33:ab:cd:ef:gh */ - if (IN6_IS_ADDR_MULTICAST(&ip_addr)) { - out_ethaddr[0] = 0x33; - out_ethaddr[1] = 0x33; - out_ethaddr[2] = ip_addr.s6_addr[12]; - out_ethaddr[3] = ip_addr.s6_addr[13]; - out_ethaddr[4] = ip_addr.s6_addr[14]; - out_ethaddr[5] = ip_addr.s6_addr[15]; - DEBUG_ARG("multicast addr = %s", - slirp_ether_ntoa(out_ethaddr, ethaddr_str, - sizeof(ethaddr_str))); - return 1; - } - - for (i = 0; i < NDP_TABLE_SIZE; i++) { - if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) { - memcpy(out_ethaddr, ndp_table->table[i].eth_addr, ETH_ALEN); - DEBUG_ARG("found hw addr = %s", - slirp_ether_ntoa(out_ethaddr, ethaddr_str, - sizeof(ethaddr_str))); - return 1; - } - } - - DEBUG_CALL(" ip not found in table"); - return 0; -} diff --git a/src/network/slirp/sbuf.c b/src/network/slirp/sbuf.c deleted file mode 100644 index b357091705..0000000000 --- a/src/network/slirp/sbuf.c +++ /dev/null @@ -1,168 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" - -static void sbappendsb(struct sbuf *sb, struct mbuf *m); - -void sbfree(struct sbuf *sb) -{ - g_free(sb->sb_data); -} - -bool sbdrop(struct sbuf *sb, size_t num) -{ - int limit = sb->sb_datalen / 2; - - g_warn_if_fail(num <= sb->sb_cc); - if (num > sb->sb_cc) - num = sb->sb_cc; - - sb->sb_cc -= num; - sb->sb_rptr += num; - if (sb->sb_rptr >= sb->sb_data + sb->sb_datalen) - sb->sb_rptr -= sb->sb_datalen; - - if (sb->sb_cc < limit && sb->sb_cc + num >= limit) { - return true; - } - - return false; -} - -void sbreserve(struct sbuf *sb, size_t size) -{ - sb->sb_wptr = sb->sb_rptr = sb->sb_data = g_realloc(sb->sb_data, size); - sb->sb_cc = 0; - sb->sb_datalen = size; -} - -/* - * Try and write() to the socket, whatever doesn't get written - * append to the buffer... for a host with a fast net connection, - * this prevents an unnecessary copy of the data - * (the socket is non-blocking, so we won't hang) - */ -void sbappend(struct socket *so, struct mbuf *m) -{ - int ret = 0; - - DEBUG_CALL("sbappend"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("m->m_len = %d", m->m_len); - - /* Shouldn't happen, but... e.g. foreign host closes connection */ - if (m->m_len <= 0) { - m_free(m); - return; - } - - /* - * If there is urgent data, call sosendoob - * if not all was sent, sowrite will take care of the rest - * (The rest of this function is just an optimisation) - */ - if (so->so_urgc) { - sbappendsb(&so->so_rcv, m); - m_free(m); - sosendoob(so); - return; - } - - /* - * We only write if there's nothing in the buffer, - * ottherwise it'll arrive out of order, and hence corrupt - */ - if (!so->so_rcv.sb_cc) - ret = slirp_send(so, m->m_data, m->m_len, 0); - - if (ret <= 0) { - /* - * Nothing was written - * It's possible that the socket has closed, but - * we don't need to check because if it has closed, - * it will be detected in the normal way by soread() - */ - sbappendsb(&so->so_rcv, m); - } else if (ret != m->m_len) { - /* - * Something was written, but not everything.. - * sbappendsb the rest - */ - m->m_len -= ret; - m->m_data += ret; - sbappendsb(&so->so_rcv, m); - } /* else */ - /* Whatever happened, we free the mbuf */ - m_free(m); -} - -/* - * Copy the data from m into sb - * The caller is responsible to make sure there's enough room - */ -static void sbappendsb(struct sbuf *sb, struct mbuf *m) -{ - int len, n, nn; - - len = m->m_len; - - if (sb->sb_wptr < sb->sb_rptr) { - n = sb->sb_rptr - sb->sb_wptr; - if (n > len) - n = len; - memcpy(sb->sb_wptr, m->m_data, n); - } else { - /* Do the right edge first */ - n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; - if (n > len) - n = len; - memcpy(sb->sb_wptr, m->m_data, n); - len -= n; - if (len) { - /* Now the left edge */ - nn = sb->sb_rptr - sb->sb_data; - if (nn > len) - nn = len; - memcpy(sb->sb_data, m->m_data + n, nn); - n += nn; - } - } - - sb->sb_cc += n; - sb->sb_wptr += n; - if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) - sb->sb_wptr -= sb->sb_datalen; -} - -/* - * Copy data from sbuf to a normal, straight buffer - * Don't update the sbuf rptr, this will be - * done in sbdrop when the data is acked - */ -void sbcopy(struct sbuf *sb, size_t off, size_t len, char *to) -{ - char *from; - - g_assert(len + off <= sb->sb_cc); - - from = sb->sb_rptr + off; - if (from >= sb->sb_data + sb->sb_datalen) - from -= sb->sb_datalen; - - if (from < sb->sb_wptr) { - memcpy(to, from, len); - } else { - /* re-use off */ - off = (sb->sb_data + sb->sb_datalen) - from; - if (off > len) - off = len; - memcpy(to, from, off); - len -= off; - if (len) - memcpy(to + off, sb->sb_data, len); - } -} diff --git a/src/network/slirp/sbuf.h b/src/network/slirp/sbuf.h deleted file mode 100644 index 01886fbd01..0000000000 --- a/src/network/slirp/sbuf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef SBUF_H -#define SBUF_H - -#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) - -struct sbuf { - uint32_t sb_cc; /* actual chars in buffer */ - uint32_t sb_datalen; /* Length of data */ - char *sb_wptr; /* write pointer. points to where the next - * bytes should be written in the sbuf */ - char *sb_rptr; /* read pointer. points to where the next - * byte should be read from the sbuf */ - char *sb_data; /* Actual data */ -}; - -void sbfree(struct sbuf *sb); -bool sbdrop(struct sbuf *sb, size_t len); -void sbreserve(struct sbuf *sb, size_t size); -void sbappend(struct socket *sb, struct mbuf *mb); -void sbcopy(struct sbuf *sb, size_t off, size_t len, char *p); - -#endif diff --git a/src/network/slirp/slirp.c b/src/network/slirp/slirp.c deleted file mode 100644 index 0c2a20a9bd..0000000000 --- a/src/network/slirp/slirp.c +++ /dev/null @@ -1,1592 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * libslirp glue - * - * Copyright (c) 2004-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "slirp.h" - - -#ifndef _WIN32 -#include -#endif - -/* https://gitlab.freedesktop.org/slirp/libslirp/issues/18 */ -#if defined(__NetBSD__) && defined(if_mtu) -#undef if_mtu -#endif - -#if defined(_WIN32) - -#define INITIAL_DNS_ADDR_BUF_SIZE 32 * 1024 -#define REALLOC_RETRIES 5 - -// Broadcast site local DNS resolvers. We do not use these because they are -// highly unlikely to be valid. -// https://www.ietf.org/proceedings/52/I-D/draft-ietf-ipngwg-dns-discovery-03.txt -static const struct in6_addr SITE_LOCAL_DNS_BROADCAST_ADDRS[] = { - { - {{ - 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - }} - }, - { - {{ - 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 - }} - }, - { - {{ - 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - }} - }, -}; - -#endif - -int slirp_debug; - -/* Define to 1 if you want KEEPALIVE timers */ -bool slirp_do_keepalive; - -/* host loopback address */ -struct in_addr loopback_addr; -/* host loopback network mask */ -unsigned long loopback_mask; - -/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */ -static const uint8_t special_ethaddr[ETH_ALEN] = { 0x52, 0x55, 0x00, - 0x00, 0x00, 0x00 }; - -unsigned curtime; - -static struct in_addr dns_addr; -static struct in6_addr dns6_addr; -static uint32_t dns6_scope_id; -static unsigned dns_addr_time; -static unsigned dns6_addr_time; - -#define TIMEOUT_FAST 2 /* milliseconds */ -#define TIMEOUT_SLOW 499 /* milliseconds */ -/* for the aging of certain requests like DNS */ -#define TIMEOUT_DEFAULT 1000 /* milliseconds */ - -#if defined(_WIN32) - -int get_dns_addr(struct in_addr *pdns_addr) -{ - FIXED_INFO *FixedInfo = NULL; - ULONG BufLen; - DWORD ret; - IP_ADDR_STRING *pIPAddr; - struct in_addr tmp_addr; - - if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < TIMEOUT_DEFAULT) { - *pdns_addr = dns_addr; - return 0; - } - - FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); - BufLen = sizeof(FIXED_INFO); - - if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - FixedInfo = GlobalAlloc(GPTR, BufLen); - } - - if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { - printf("GetNetworkParams failed. ret = %08x\n", (unsigned)ret); - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return -1; - } - - pIPAddr = &(FixedInfo->DnsServerList); - inet_aton(pIPAddr->IpAddress.String, &tmp_addr); - *pdns_addr = tmp_addr; - dns_addr = tmp_addr; - dns_addr_time = curtime; - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return 0; -} - -int is_site_local_dns_broadcast(struct in6_addr *address) -{ - int i; - for (i = 0; i < G_N_ELEMENTS(SITE_LOCAL_DNS_BROADCAST_ADDRS); i++) { - if (in6_equal(address, &SITE_LOCAL_DNS_BROADCAST_ADDRS[i])) { - return 1; - } - } - return 0; -} - -void print_dns_v6_address(struct in6_addr address) -{ - char address_str[INET6_ADDRSTRLEN] = ""; - if (inet_ntop(AF_INET6, &address, address_str, INET6_ADDRSTRLEN) - == NULL) { - DEBUG_ERROR("Failed to stringify IPv6 address for logging."); - return; - } - DEBUG_CALL("IPv6 DNS server found: %s", address_str); -} - -// Gets the first valid DNS resolver with an IPv6 address. -// Ignores any site local broadcast DNS servers, as these -// are on deprecated addresses and not generally expected -// to work. Further details at: -// https://www.ietf.org/proceedings/52/I-D/draft-ietf-ipngwg-dns-discovery-03.txt -int get_ipv6_dns_server(struct in6_addr *dns_server_address, uint32_t *scope_id) -{ - PIP_ADAPTER_ADDRESSES addresses = NULL; - PIP_ADAPTER_ADDRESSES address = NULL; - IP_ADAPTER_DNS_SERVER_ADDRESS *dns_server = NULL; - struct sockaddr_in6 *dns_v6_addr = NULL; - - ULONG buf_size = INITIAL_DNS_ADDR_BUF_SIZE; - DWORD res = ERROR_BUFFER_OVERFLOW; - int i; - - for (i = 0; i < REALLOC_RETRIES; i++) { - // If non null, we hit buffer overflow, free it so we can try again. - if (addresses != NULL) { - g_free(addresses); - } - - addresses = g_malloc(buf_size); - res = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, - addresses, &buf_size); - - if (res != ERROR_BUFFER_OVERFLOW) { - break; - } - } - - if (res != NO_ERROR) { - DEBUG_ERROR("Failed to get IPv6 DNS addresses due to error %lX", res); - goto failure; - } - - address = addresses; - for (address = addresses; address != NULL; address = address->Next) { - for (dns_server = address->FirstDnsServerAddress; - dns_server != NULL; - dns_server = dns_server->Next) { - - if (dns_server->Address.lpSockaddr->sa_family != AF_INET6) { - continue; - } - - dns_v6_addr = (struct sockaddr_in6 *)dns_server->Address.lpSockaddr; - if (is_site_local_dns_broadcast(&dns_v6_addr->sin6_addr) == 0) { - print_dns_v6_address(dns_v6_addr->sin6_addr); - *dns_server_address = dns_v6_addr->sin6_addr; - *scope_id = dns_v6_addr->sin6_scope_id; - - g_free(addresses); - return 0; - } - } - } - - DEBUG_ERROR("No IPv6 DNS servers found.\n"); - -failure: - g_free(addresses); - return -1; -} - -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) -{ - if (!in6_zero(&dns6_addr) && (curtime - dns6_addr_time) < TIMEOUT_DEFAULT) { - *pdns6_addr = dns6_addr; - *scope_id = dns6_scope_id; - return 0; - } - - if (get_ipv6_dns_server(pdns6_addr, scope_id) == 0) { - dns6_addr = *pdns6_addr; - dns6_addr_time = curtime; - dns6_scope_id = *scope_id; - return 0; - } - - return -1; -} - -static void winsock_cleanup(void) -{ - WSACleanup(); -} - -#elif defined(__APPLE__) - -#include - -static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, - socklen_t addrlen, unsigned *cached_time) -{ - if (curtime - *cached_time < TIMEOUT_DEFAULT) { - memcpy(pdns_addr, cached_addr, addrlen); - return 0; - } - return 1; -} - -static int get_dns_addr_libresolv(int af, void *pdns_addr, void *cached_addr, - socklen_t addrlen, - uint32_t *scope_id, uint32_t *cached_scope_id, - unsigned *cached_time) -{ - struct __res_state state; - union res_sockaddr_union servers[NI_MAXSERV]; - int count; - int found; - void *addr; - - // we only support IPv4 and IPv4, we assume it's one or the other - assert(af == AF_INET || af == AF_INET6); - - if (res_ninit(&state) != 0) { - return -1; - } - - count = res_getservers(&state, servers, NI_MAXSERV); - found = 0; - DEBUG_MISC("IP address of your DNS(s):"); - for (int i = 0; i < count; i++) { - if (af == servers[i].sin.sin_family) { - found++; - } - if (af == AF_INET) { - addr = &servers[i].sin.sin_addr; - } else { // af == AF_INET6 - addr = &servers[i].sin6.sin6_addr; - } - - // we use the first found entry - if (found == 1) { - memcpy(pdns_addr, addr, addrlen); - memcpy(cached_addr, addr, addrlen); - if (scope_id) { - *scope_id = 0; - } - if (cached_scope_id) { - *cached_scope_id = 0; - } - *cached_time = curtime; - } - - if (found > 3) { - DEBUG_MISC(" (more)"); - break; - } else if (slirp_debug & DBG_MISC) { - char s[INET6_ADDRSTRLEN]; - const char *res = inet_ntop(af, addr, s, sizeof(s)); - if (!res) { - res = " (string conversion error)"; - } - DEBUG_MISC(" %s", res); - } - } - - res_ndestroy(&state); - if (!found) - return -1; - return 0; -} - -int get_dns_addr(struct in_addr *pdns_addr) -{ - if (dns_addr.s_addr != 0) { - int ret; - ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr), - &dns_addr_time); - if (ret <= 0) { - return ret; - } - } - return get_dns_addr_libresolv(AF_INET, pdns_addr, &dns_addr, - sizeof(dns_addr), NULL, NULL, &dns_addr_time); -} - -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) -{ - if (!in6_zero(&dns6_addr)) { - int ret; - ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr), - &dns6_addr_time); - if (ret == 0) { - *scope_id = dns6_scope_id; - } - if (ret <= 0) { - return ret; - } - } - return get_dns_addr_libresolv(AF_INET6, pdns6_addr, &dns6_addr, - sizeof(dns6_addr), - scope_id, &dns6_scope_id, &dns6_addr_time); -} - -#else // !defined(_WIN32) && !defined(__APPLE__) - -#if defined(__HAIKU__) -#define RESOLV_CONF_PATH "/boot/system/settings/network/resolv.conf" -#else -#define RESOLV_CONF_PATH "/etc/resolv.conf" -#endif - -static int get_dns_addr_cached(void *pdns_addr, void *cached_addr, - socklen_t addrlen, struct stat *cached_stat, - unsigned *cached_time) -{ - struct stat old_stat; - if (curtime - *cached_time < TIMEOUT_DEFAULT) { - memcpy(pdns_addr, cached_addr, addrlen); - return 0; - } - old_stat = *cached_stat; - if (stat(RESOLV_CONF_PATH, cached_stat) != 0) { - return -1; - } - if (cached_stat->st_dev == old_stat.st_dev && - cached_stat->st_ino == old_stat.st_ino && - cached_stat->st_size == old_stat.st_size && - cached_stat->st_mtime == old_stat.st_mtime) { - memcpy(pdns_addr, cached_addr, addrlen); - return 0; - } - return 1; -} - -static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr, - socklen_t addrlen, - uint32_t *scope_id, uint32_t *cached_scope_id, - unsigned *cached_time) -{ - char buff[512]; - char buff2[257]; - FILE *f; - int found = 0; - union { - struct in_addr dns_addr; - struct in6_addr dns6_addr; - } tmp_addr; - unsigned if_index; - - assert(sizeof(tmp_addr) >= addrlen); - f = fopen(RESOLV_CONF_PATH, "r"); - if (!f) - return -1; - - DEBUG_MISC("IP address of your DNS(s):"); - while (fgets(buff, 512, f) != NULL) { - if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { - char *c = strchr(buff2, '%'); - if (c) { - if_index = if_nametoindex(c + 1); - *c = '\0'; - } else { - if_index = 0; - } - - if (!inet_pton(af, buff2, &tmp_addr)) { - continue; - } - /* If it's the first one, set it to dns_addr */ - if (!found) { - memcpy(pdns_addr, &tmp_addr, addrlen); - memcpy(cached_addr, &tmp_addr, addrlen); - if (scope_id) { - *scope_id = if_index; - } - if (cached_scope_id) { - *cached_scope_id = if_index; - } - *cached_time = curtime; - } - - if (++found > 3) { - DEBUG_MISC(" (more)"); - break; - } else if (slirp_debug & DBG_MISC) { - char s[INET6_ADDRSTRLEN]; - const char *res = inet_ntop(af, &tmp_addr, s, sizeof(s)); - if (!res) { - res = " (string conversion error)"; - } - DEBUG_MISC(" %s", res); - } - } - } - fclose(f); - if (!found) - return -1; - return 0; -} - -int get_dns_addr(struct in_addr *pdns_addr) -{ - static struct stat dns_addr_stat; - - if (dns_addr.s_addr != 0) { - int ret; - ret = get_dns_addr_cached(pdns_addr, &dns_addr, sizeof(dns_addr), - &dns_addr_stat, &dns_addr_time); - if (ret <= 0) { - return ret; - } - } - return get_dns_addr_resolv_conf(AF_INET, pdns_addr, &dns_addr, - sizeof(dns_addr), - NULL, NULL, &dns_addr_time); -} - -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id) -{ - static struct stat dns6_addr_stat; - - if (!in6_zero(&dns6_addr)) { - int ret; - ret = get_dns_addr_cached(pdns6_addr, &dns6_addr, sizeof(dns6_addr), - &dns6_addr_stat, &dns6_addr_time); - if (ret == 0) { - *scope_id = dns6_scope_id; - } - if (ret <= 0) { - return ret; - } - } - return get_dns_addr_resolv_conf(AF_INET6, pdns6_addr, &dns6_addr, - sizeof(dns6_addr), - scope_id, &dns6_scope_id, &dns6_addr_time); -} - -#endif - -static void slirp_init_once(void) -{ - static int initialized; - const char *debug; -#ifdef _WIN32 - WSADATA Data; -#endif - - if (initialized) { - return; - } - initialized = 1; - -#ifdef _WIN32 - WSAStartup(MAKEWORD(2, 0), &Data); - atexit(winsock_cleanup); -#endif - - loopback_addr.s_addr = htonl(INADDR_LOOPBACK); - loopback_mask = htonl(IN_CLASSA_NET); - - debug = g_getenv("SLIRP_DEBUG"); - if (debug) { - const GDebugKey keys[] = { - { "call", DBG_CALL }, - { "misc", DBG_MISC }, - { "error", DBG_ERROR }, - { "tftp", DBG_TFTP }, - { "verbose_call", DBG_VERBOSE_CALL }, - }; - slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys)); - } -} - -static void ra_timer_handler_cb(void *opaque) -{ - Slirp *slirp = opaque; - - return ra_timer_handler(slirp, NULL); -} - -void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque) -{ -// g_return_if_fail(id >= 0 && id < SLIRP_TIMER_NUM); - - switch (id) { - case SLIRP_TIMER_RA: - return ra_timer_handler(slirp, cb_opaque); - default: - abort(); - } -} - -void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque) -{ - g_return_val_if_fail(id >= 0 && id < SLIRP_TIMER_NUM, NULL); - - if (slirp->cfg_version >= 4 && slirp->cb->timer_new_opaque) { - return slirp->cb->timer_new_opaque(id, cb_opaque, slirp->opaque); - } - - switch (id) { - case SLIRP_TIMER_RA: - g_return_val_if_fail(cb_opaque == NULL, NULL); - return slirp->cb->timer_new(ra_timer_handler_cb, slirp, slirp->opaque); - - default: - abort(); - } -} - -Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) -{ - Slirp *slirp; - - g_return_val_if_fail(cfg != NULL, NULL); - g_return_val_if_fail(cfg->version >= SLIRP_CONFIG_VERSION_MIN, NULL); - g_return_val_if_fail(cfg->version <= SLIRP_CONFIG_VERSION_MAX, NULL); - g_return_val_if_fail(cfg->if_mtu >= IF_MTU_MIN || cfg->if_mtu == 0, NULL); - g_return_val_if_fail(cfg->if_mtu <= IF_MTU_MAX, NULL); - g_return_val_if_fail(cfg->if_mru >= IF_MRU_MIN || cfg->if_mru == 0, NULL); - g_return_val_if_fail(cfg->if_mru <= IF_MRU_MAX, NULL); - g_return_val_if_fail(!cfg->bootfile || - (strlen(cfg->bootfile) < - G_SIZEOF_MEMBER(struct bootp_t, bp_file)), NULL); - - slirp = g_malloc0(sizeof(Slirp)); - - slirp_init_once(); - - slirp->cfg_version = cfg->version; - slirp->opaque = opaque; - slirp->cb = callbacks; - slirp->grand = g_rand_new(); - slirp->restricted = cfg->restricted; - - slirp->in_enabled = cfg->in_enabled; - slirp->in6_enabled = cfg->in6_enabled; - - if_init(slirp); - ip_init(slirp); - - m_init(slirp); - - slirp->vnetwork_addr = cfg->vnetwork; - slirp->vnetwork_mask = cfg->vnetmask; - slirp->vhost_addr = cfg->vhost; - slirp->vprefix_addr6 = cfg->vprefix_addr6; - slirp->vprefix_len = cfg->vprefix_len; - slirp->vhost_addr6 = cfg->vhost6; - if (cfg->vhostname) { - slirp_pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname), - cfg->vhostname); - } - slirp->tftp_prefix = g_strdup(cfg->tftp_path); - slirp->bootp_filename = g_strdup(cfg->bootfile); - slirp->vdomainname = g_strdup(cfg->vdomainname); - slirp->vdhcp_startaddr = cfg->vdhcp_start; - slirp->vnameserver_addr = cfg->vnameserver; - slirp->vnameserver_addr6 = cfg->vnameserver6; - slirp->tftp_server_name = g_strdup(cfg->tftp_server_name); - - if (cfg->vdnssearch) { - translate_dnssearch(slirp, cfg->vdnssearch); - } - slirp->if_mtu = cfg->if_mtu == 0 ? IF_MTU_DEFAULT : cfg->if_mtu; - slirp->if_mru = cfg->if_mru == 0 ? IF_MRU_DEFAULT : cfg->if_mru; - slirp->disable_host_loopback = cfg->disable_host_loopback; - slirp->enable_emu = cfg->enable_emu; - - if (cfg->version >= 2) { - slirp->outbound_addr = cfg->outbound_addr; - slirp->outbound_addr6 = cfg->outbound_addr6; - } else { - slirp->outbound_addr = NULL; - slirp->outbound_addr6 = NULL; - } - - if (cfg->version >= 3) { - slirp->disable_dns = cfg->disable_dns; - } else { - slirp->disable_dns = false; - } - - if (cfg->version >= 4) { - slirp->disable_dhcp = cfg->disable_dhcp; - } else { - slirp->disable_dhcp = false; - } - - if (slirp->cfg_version >= 4 && slirp->cb->init_completed) { - slirp->cb->init_completed(slirp, slirp->opaque); - } - - ip6_post_init(slirp); - return slirp; -} - -Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, - struct in_addr vnetmask, struct in_addr vhost, - bool in6_enabled, struct in6_addr vprefix_addr6, - uint8_t vprefix_len, struct in6_addr vhost6, - const char *vhostname, const char *tftp_server_name, - const char *tftp_path, const char *bootfile, - struct in_addr vdhcp_start, struct in_addr vnameserver, - struct in6_addr vnameserver6, const char **vdnssearch, - const char *vdomainname, const SlirpCb *callbacks, - void *opaque) -{ - SlirpConfig cfg; - memset(&cfg, 0, sizeof(cfg)); - cfg.version = 1; - cfg.restricted = restricted; - cfg.in_enabled = in_enabled; - cfg.vnetwork = vnetwork; - cfg.vnetmask = vnetmask; - cfg.vhost = vhost; - cfg.in6_enabled = in6_enabled; - cfg.vprefix_addr6 = vprefix_addr6; - cfg.vprefix_len = vprefix_len; - cfg.vhost6 = vhost6; - cfg.vhostname = vhostname; - cfg.tftp_server_name = tftp_server_name; - cfg.tftp_path = tftp_path; - cfg.bootfile = bootfile; - cfg.vdhcp_start = vdhcp_start; - cfg.vnameserver = vnameserver; - cfg.vnameserver6 = vnameserver6; - cfg.vdnssearch = vdnssearch; - cfg.vdomainname = vdomainname; - return slirp_new(&cfg, callbacks, opaque); -} - -void slirp_cleanup(Slirp *slirp) -{ - struct gfwd_list *e, *next; - - for (e = slirp->guestfwd_list; e; e = next) { - next = e->ex_next; - g_free(e->ex_exec); - g_free(e->ex_unix); - g_free(e); - } - - ip_cleanup(slirp); - ip6_cleanup(slirp); - m_cleanup(slirp); - - g_rand_free(slirp->grand); - - g_free(slirp->vdnssearch); - g_free(slirp->tftp_prefix); - g_free(slirp->bootp_filename); - g_free(slirp->vdomainname); - g_free(slirp); -} - -#define CONN_CANFSEND(so) \ - (((so)->so_state & (SS_FCANTSENDMORE | SS_ISFCONNECTED)) == SS_ISFCONNECTED) -#define CONN_CANFRCV(so) \ - (((so)->so_state & (SS_FCANTRCVMORE | SS_ISFCONNECTED)) == SS_ISFCONNECTED) - -static void slirp_update_timeout(Slirp *slirp, uint32_t *timeout) -{ - uint32_t t; - - if (*timeout <= TIMEOUT_FAST) { - return; - } - - t = MIN(1000, *timeout); - - /* If we have tcp timeout with slirp, then we will fill @timeout with - * more precise value. - */ - if (slirp->time_fasttimo) { - *timeout = TIMEOUT_FAST; - return; - } - if (slirp->do_slowtimo) { - t = MIN(TIMEOUT_SLOW, t); - } - *timeout = t; -} - -void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout, - SlirpAddPollCb add_poll, void *opaque) -{ - struct socket *so, *so_next; - - /* - * First, TCP sockets - */ - - /* - * *_slowtimo needs calling if there are IP fragments - * in the fragment queue, or there are TCP connections active - */ - slirp->do_slowtimo = ((slirp->tcb.so_next != &slirp->tcb) || - (&slirp->ipq.ip_link != slirp->ipq.ip_link.next)); - - for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so_next) { - int events = 0; - - so_next = so->so_next; - - so->pollfds_idx = -1; - - /* - * See if we need a tcp_fasttimo - */ - if (slirp->time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) { - slirp->time_fasttimo = curtime; /* Flag when want a fasttimo */ - } - - /* - * NOFDREF can include still connecting to local-host, - * newly socreated() sockets etc. Don't want to select these. - */ - if (so->so_state & SS_NOFDREF || so->s == -1) { - continue; - } - - /* - * Set for reading sockets which are accepting - */ - if (so->so_state & SS_FACCEPTCONN) { - so->pollfds_idx = add_poll( - so->s, SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque); - continue; - } - - /* - * Set for writing sockets which are connecting - */ - if (so->so_state & SS_ISFCONNECTING) { - so->pollfds_idx = - add_poll(so->s, SLIRP_POLL_OUT | SLIRP_POLL_ERR, opaque); - continue; - } - - /* - * Set for writing if we are connected, can send more, and - * we have something to send - */ - if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) { - events |= SLIRP_POLL_OUT | SLIRP_POLL_ERR; - } - - /* - * Set for reading (and urgent data) if we are connected, can - * receive more, and we have room for it. - * - * If sb is already half full, we will wait for the guest to consume it, - * and notify again in sbdrop() when the sb becomes less than half full. - */ - if (CONN_CANFRCV(so) && - (so->so_snd.sb_cc < (so->so_snd.sb_datalen / 2))) { - events |= SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR | - SLIRP_POLL_PRI; - } - - if (events) { - so->pollfds_idx = add_poll(so->s, events, opaque); - } - } - - /* - * UDP sockets - */ - for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) { - so_next = so->so_next; - - so->pollfds_idx = -1; - - /* - * See if it's timed out - */ - if (so->so_expire) { - if (so->so_expire <= curtime) { - udp_detach(so); - continue; - } else { - slirp->do_slowtimo = true; /* Let socket expire */ - } - } - - /* - * When UDP packets are received from over the - * link, they're sendto()'d straight away, so - * no need for setting for writing - * Limit the number of packets queued by this session - * to 4. Note that even though we try and limit this - * to 4 packets, the session could have more queued - * if the packets needed to be fragmented - * (XXX <= 4 ?) - */ - if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { - so->pollfds_idx = add_poll( - so->s, SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque); - } - } - - /* - * ICMP sockets - */ - for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) { - so_next = so->so_next; - - so->pollfds_idx = -1; - - /* - * See if it's timed out - */ - if (so->so_expire) { - if (so->so_expire <= curtime) { - icmp_detach(so); - continue; - } else { - slirp->do_slowtimo = true; /* Let socket expire */ - } - } - - if (so->so_state & SS_ISFCONNECTED) { - so->pollfds_idx = add_poll( - so->s, SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR, opaque); - } - } - - slirp_update_timeout(slirp, timeout); -} - -void slirp_pollfds_poll(Slirp *slirp, int select_error, - SlirpGetREventsCb get_revents, void *opaque) -{ - struct socket *so, *so_next; - int ret; - - curtime = slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS; - - /* - * See if anything has timed out - */ - if (slirp->time_fasttimo && - ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) { - tcp_fasttimo(slirp); - slirp->time_fasttimo = 0; - } - if (slirp->do_slowtimo && - ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) { - ip_slowtimo(slirp); - tcp_slowtimo(slirp); - slirp->last_slowtimo = curtime; - } - - /* - * Check sockets - */ - if (!select_error) { - /* - * Check TCP sockets - */ - for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so_next) { - int revents; - - so_next = so->so_next; - - revents = 0; - if (so->pollfds_idx != -1) { - revents = get_revents(so->pollfds_idx, opaque); - } - - if (so->so_state & SS_NOFDREF || so->s == -1) { - continue; - } - -#ifndef __APPLE__ - /* - * Check for URG data - * This will soread as well, so no need to - * test for SLIRP_POLL_IN below if this succeeds. - * - * This is however disabled on MacOS, which apparently always - * reports data as PRI when it is the last data of the - * connection. We would then report it out of band, which the guest - * would most probably not be ready for. - */ - if (revents & SLIRP_POLL_PRI) { - ret = sorecvoob(so); - if (ret < 0) { - /* Socket error might have resulted in the socket being - * removed, do not try to do anything more with it. */ - continue; - } - } - /* - * Check sockets for reading - */ - else -#endif - if (revents & - (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR | SLIRP_POLL_PRI)) { - /* - * Check for incoming connections - */ - if (so->so_state & SS_FACCEPTCONN) { - tcp_connect(so); - continue; - } /* else */ - ret = soread(so); - - /* Output it if we read something */ - if (ret > 0) { - tcp_output(sototcpcb(so)); - } - if (ret < 0) { - /* Socket error might have resulted in the socket being - * removed, do not try to do anything more with it. */ - continue; - } - } - - /* - * Check sockets for writing - */ - if (!(so->so_state & SS_NOFDREF) && - (revents & (SLIRP_POLL_OUT | SLIRP_POLL_ERR))) { - /* - * Check for non-blocking, still-connecting sockets - */ - if (so->so_state & SS_ISFCONNECTING) { - /* Connected */ - so->so_state &= ~SS_ISFCONNECTING; - - ret = send(so->s, (const void *)&ret, 0, 0); - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) { - continue; - } - - /* else failed */ - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_NOFDREF; - } - /* else so->so_state &= ~SS_ISFCONNECTING; */ - - /* - * Continue tcp_input - */ - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so, - so->so_ffamily); - /* continue; */ - } else { - ret = sowrite(so); - if (ret > 0) { - /* Call tcp_output in case we need to send a window - * update to the guest, otherwise it will be stuck - * until it sends a window probe. */ - tcp_output(sototcpcb(so)); - } - } - } - } - - /* - * Now UDP sockets. - * Incoming packets are sent straight away, they're not buffered. - * Incoming UDP data isn't buffered either. - */ - for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) { - int revents; - - so_next = so->so_next; - - revents = 0; - if (so->pollfds_idx != -1) { - revents = get_revents(so->pollfds_idx, opaque); - } - - if (so->s != -1 && - (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) { - sorecvfrom(so); - } - } - - /* - * Check incoming ICMP relies. - */ - for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) { - int revents; - - so_next = so->so_next; - - revents = 0; - if (so->pollfds_idx != -1) { - revents = get_revents(so->pollfds_idx, opaque); - } - - if (so->s != -1 && - (revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) { - icmp_receive(so); - } - } - } - - if_start(slirp); -} - -static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) -{ - const struct slirp_arphdr *ah = - (const struct slirp_arphdr *)(pkt + ETH_HLEN); - uint8_t arp_reply[MAX(ETH_HLEN + sizeof(struct slirp_arphdr), 64)]; - struct ethhdr *reh = (struct ethhdr *)arp_reply; - struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN); - int ar_op; - struct gfwd_list *ex_ptr; - - if (!slirp->in_enabled) { - return; - } - - if (pkt_len < ETH_HLEN + sizeof(struct slirp_arphdr)) { - return; /* packet too short */ - } - - ar_op = ntohs(ah->ar_op); - switch (ar_op) { - case ARPOP_REQUEST: - if (ah->ar_tip == ah->ar_sip) { - /* Gratuitous ARP */ - arp_table_add(slirp, ah->ar_sip, ah->ar_sha); - return; - } - - if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) == - slirp->vnetwork_addr.s_addr) { - if (ah->ar_tip == slirp->vnameserver_addr.s_addr || - ah->ar_tip == slirp->vhost_addr.s_addr) - goto arp_ok; - /* TODO: IPv6 */ - for (ex_ptr = slirp->guestfwd_list; ex_ptr; - ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_addr.s_addr == ah->ar_tip) - goto arp_ok; - } - return; - arp_ok: - memset(arp_reply, 0, sizeof(arp_reply)); - - arp_table_add(slirp, ah->ar_sip, ah->ar_sha); - - /* ARP request for alias/dns mac address */ - memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); - memcpy(&reh->h_source[2], &ah->ar_tip, 4); - reh->h_proto = htons(ETH_P_ARP); - - rah->ar_hrd = htons(1); - rah->ar_pro = htons(ETH_P_IP); - rah->ar_hln = ETH_ALEN; - rah->ar_pln = 4; - rah->ar_op = htons(ARPOP_REPLY); - memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); - rah->ar_sip = ah->ar_tip; - memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); - rah->ar_tip = ah->ar_sip; - slirp_send_packet_all(slirp, arp_reply, sizeof(arp_reply)); - } - break; - case ARPOP_REPLY: - arp_table_add(slirp, ah->ar_sip, ah->ar_sha); - break; - default: - break; - } -} - -void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) -{ - struct mbuf *m; - int proto; - - if (pkt_len < ETH_HLEN) - return; - - proto = (((uint16_t)pkt[12]) << 8) + pkt[13]; - switch (proto) { - case ETH_P_ARP: - arp_input(slirp, pkt, pkt_len); - break; - case ETH_P_IP: - case ETH_P_IPV6: - m = m_get(slirp); - if (!m) - return; - /* Note: we add 2 to align the IP header on 4 bytes, - * and add the margin for the tcpiphdr overhead */ - if (M_FREEROOM(m) < pkt_len + TCPIPHDR_DELTA + 2) { - m_inc(m, pkt_len + TCPIPHDR_DELTA + 2); - } - m->m_len = pkt_len + TCPIPHDR_DELTA + 2; - memcpy(m->m_data + TCPIPHDR_DELTA + 2, pkt, pkt_len); - - m->m_data += TCPIPHDR_DELTA + 2 + ETH_HLEN; - m->m_len -= TCPIPHDR_DELTA + 2 + ETH_HLEN; - - if (proto == ETH_P_IP) { - ip_input(m); - } else if (proto == ETH_P_IPV6) { - ip6_input(m); - } - break; - - case ETH_P_NCSI: - ncsi_input(slirp, pkt, pkt_len); - break; - - default: - break; - } -} - -/* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no - * packet should be sent, 0 if the packet must be re-queued, 2 if the packet - * is ready to go. - */ -static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh, - uint8_t ethaddr[ETH_ALEN]) -{ - const struct ip *iph = (const struct ip *)ifm->m_data; - - if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) { - uint8_t arp_req[ETH_HLEN + sizeof(struct slirp_arphdr)]; - struct ethhdr *reh = (struct ethhdr *)arp_req; - struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_req + ETH_HLEN); - - if (!ifm->resolution_requested) { - /* If the client addr is not known, send an ARP request */ - memset(reh->h_dest, 0xff, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); - memcpy(&reh->h_source[2], &slirp->vhost_addr, 4); - reh->h_proto = htons(ETH_P_ARP); - rah->ar_hrd = htons(1); - rah->ar_pro = htons(ETH_P_IP); - rah->ar_hln = ETH_ALEN; - rah->ar_pln = 4; - rah->ar_op = htons(ARPOP_REQUEST); - - /* source hw addr */ - memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4); - memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4); - - /* source IP */ - rah->ar_sip = slirp->vhost_addr.s_addr; - - /* target hw addr (none) */ - memset(rah->ar_tha, 0, ETH_ALEN); - - /* target IP */ - rah->ar_tip = iph->ip_dst.s_addr; - slirp->client_ipaddr = iph->ip_dst; - slirp_send_packet_all(slirp, arp_req, sizeof(arp_req)); - ifm->resolution_requested = true; - - /* Expire request and drop outgoing packet after 1 second */ - ifm->expiration_date = - slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL; - } - return 0; - } else { - memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4); - /* XXX: not correct */ - memcpy(&eh->h_source[2], &slirp->vhost_addr, 4); - eh->h_proto = htons(ETH_P_IP); - - /* Send this */ - return 2; - } -} - -/* Prepare the IPv6 packet to be sent to the ethernet device. Returns 1 if no - * packet should be sent, 0 if the packet must be re-queued, 2 if the packet - * is ready to go. - */ -static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh, - uint8_t ethaddr[ETH_ALEN]) -{ - const struct ip6 *ip6h = mtod(ifm, const struct ip6 *); - if (!ndp_table_search(slirp, ip6h->ip_dst, ethaddr)) { - if (!ifm->resolution_requested) { - ndp_send_ns(slirp, ip6h->ip_dst); - ifm->resolution_requested = true; - ifm->expiration_date = - slirp->cb->clock_get_ns(slirp->opaque) + 1000000000ULL; - } - return 0; - } else { - eh->h_proto = htons(ETH_P_IPV6); - in6_compute_ethaddr(ip6h->ip_src, eh->h_source); - - /* Send this */ - return 2; - } -} - -/* Output the IP packet to the ethernet device. Returns 0 if the packet must be - * re-queued. - */ -int if_encap(Slirp *slirp, struct mbuf *ifm) -{ - uint8_t buf[IF_MTU_MAX + 100]; - struct ethhdr *eh = (struct ethhdr *)buf; - uint8_t ethaddr[ETH_ALEN]; - const struct ip *iph = (const struct ip *)ifm->m_data; - int ret; -// char ethaddr_str[ETH_ADDRSTRLEN]; - - if (ifm->m_len + ETH_HLEN > sizeof(buf)) { - return 1; - } - - switch (iph->ip_v) { - case IPVERSION: - ret = if_encap4(slirp, ifm, eh, ethaddr); - if (ret < 2) { - return ret; - } - break; - - case IP6VERSION: - ret = if_encap6(slirp, ifm, eh, ethaddr); - if (ret < 2) { - return ret; - } - break; - - default: - g_assert_not_reached(); - } - - memcpy(eh->h_dest, ethaddr, ETH_ALEN); -/* - DEBUG_ARG("src = %s", slirp_ether_ntoa(eh->h_source, ethaddr_str, - sizeof(ethaddr_str))); - DEBUG_ARG("dst = %s", slirp_ether_ntoa(eh->h_dest, ethaddr_str, - sizeof(ethaddr_str))); -*/ - memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); - slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN); - return 1; -} - -/* Drop host forwarding rule, return 0 if found. */ -int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, - int host_port) -{ - struct socket *so; - struct socket *head = (is_udp ? &slirp->udb : &slirp->tcb); - struct sockaddr_in addr; - int port = htons(host_port); - socklen_t addr_len; - - for (so = head->so_next; so != head; so = so->so_next) { - addr_len = sizeof(addr); - if ((so->so_state & SS_HOSTFWD) && - getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 && - addr_len == sizeof(addr) && - addr.sin_family == AF_INET && - addr.sin_addr.s_addr == host_addr.s_addr && - addr.sin_port == port) { - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - sofree(so); - return 0; - } - } - - return -1; -} - -int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, - int host_port, struct in_addr guest_addr, int guest_port) -{ - if (!guest_addr.s_addr) { - guest_addr = slirp->vdhcp_startaddr; - } - if (is_udp) { - if (!udp_listen(slirp, host_addr.s_addr, htons(host_port), - guest_addr.s_addr, htons(guest_port), SS_HOSTFWD)) - return -1; - } else { - if (!tcp_listen(slirp, host_addr.s_addr, htons(host_port), - guest_addr.s_addr, htons(guest_port), SS_HOSTFWD)) - return -1; - } - return 0; -} - -int slirp_remove_hostxfwd(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - int flags) -{ - struct socket *so; - struct socket *head = (flags & SLIRP_HOSTFWD_UDP ? &slirp->udb : &slirp->tcb); - struct sockaddr_storage addr; - socklen_t addr_len; - - for (so = head->so_next; so != head; so = so->so_next) { - addr_len = sizeof(addr); - if ((so->so_state & SS_HOSTFWD) && - getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 && - sockaddr_equal(&addr, (const struct sockaddr_storage *) haddr)) { - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - sofree(so); - return 0; - } - } - - return -1; -} - -int slirp_add_hostxfwd(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *gaddr, socklen_t gaddrlen, - int flags) -{ - struct sockaddr_in gdhcp_addr; - int fwd_flags = SS_HOSTFWD; - - if (flags & SLIRP_HOSTFWD_V6ONLY) - fwd_flags |= SS_HOSTFWD_V6ONLY; - - if (gaddr->sa_family == AF_INET) { - const struct sockaddr_in *gaddr_in = (const struct sockaddr_in *) gaddr; - - if (gaddrlen < sizeof(struct sockaddr_in)) { - errno = EINVAL; - return -1; - } - - if (!gaddr_in->sin_addr.s_addr) { - gdhcp_addr = *gaddr_in; - gdhcp_addr.sin_addr = slirp->vdhcp_startaddr; - gaddr = (struct sockaddr *) &gdhcp_addr; - gaddrlen = sizeof(gdhcp_addr); - } - } else { - if (gaddrlen < sizeof(struct sockaddr_in6)) { - errno = EINVAL; - return -1; - } - - /* - * Libslirp currently only provides a stateless DHCPv6 server, thus - * we can't translate "addr-any" to the guest here. Instead, we defer - * performing the translation to when it's needed. See - * soassign_guest_addr_if_needed(). - */ - } - - if (flags & SLIRP_HOSTFWD_UDP) { - if (!udpx_listen(slirp, haddr, haddrlen, - gaddr, gaddrlen, - fwd_flags)) - return -1; - } else { - if (!tcpx_listen(slirp, haddr, haddrlen, - gaddr, gaddrlen, - fwd_flags)) - return -1; - } - return 0; -} - -/* TODO: IPv6 */ -static bool check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, - int guest_port) -{ - struct gfwd_list *tmp_ptr; - - if (!guest_addr->s_addr) { - guest_addr->s_addr = slirp->vnetwork_addr.s_addr | - (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr); - } - if ((guest_addr->s_addr & slirp->vnetwork_mask.s_addr) != - slirp->vnetwork_addr.s_addr || - guest_addr->s_addr == slirp->vhost_addr.s_addr || - guest_addr->s_addr == slirp->vnameserver_addr.s_addr) { - return false; - } - - /* check if the port is "bound" */ - for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { - if (guest_port == tmp_ptr->ex_fport && - guest_addr->s_addr == tmp_ptr->ex_addr.s_addr) - return false; - } - - return true; -} - -int slirp_add_exec(Slirp *slirp, const char *cmdline, - struct in_addr *guest_addr, int guest_port) -{ - if (!check_guestfwd(slirp, guest_addr, guest_port)) { - return -1; - } - - add_exec(&slirp->guestfwd_list, cmdline, *guest_addr, htons(guest_port)); - return 0; -} - -int slirp_add_unix(Slirp *slirp, const char *unixsock, - struct in_addr *guest_addr, int guest_port) -{ -#ifdef G_OS_UNIX - if (!check_guestfwd(slirp, guest_addr, guest_port)) { - return -1; - } - - add_unix(&slirp->guestfwd_list, unixsock, *guest_addr, htons(guest_port)); - return 0; -#else - g_warn_if_reached(); - return -1; -#endif -} - -int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, - struct in_addr *guest_addr, int guest_port) -{ - if (!check_guestfwd(slirp, guest_addr, guest_port)) { - return -1; - } - - add_guestfwd(&slirp->guestfwd_list, write_cb, opaque, *guest_addr, - htons(guest_port)); - return 0; -} - -int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, - int guest_port) -{ - return remove_guestfwd(&slirp->guestfwd_list, guest_addr, - htons(guest_port)); -} - -ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) -{ - if (so->s == -1 && so->guestfwd) { - /* XXX this blocks entire thread. Rewrite to use - * qemu_chr_fe_write and background I/O callbacks */ - so->guestfwd->write_cb(buf, len, so->guestfwd->opaque); - return len; - } - - if (so->s == -1) { - /* - * This should in theory not happen but it is hard to be - * sure because some code paths will end up with so->s == -1 - * on a failure but don't dispose of the struct socket. - * Check specifically, so we don't pass -1 to send(). - */ - errno = EBADF; - return -1; - } - - return send(so->s, buf, len, flags); -} - -struct socket *slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, - int guest_port) -{ - struct socket *so; - - /* TODO: IPv6 */ - for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) { - if (so->so_faddr.s_addr == guest_addr.s_addr && - htons(so->so_fport) == guest_port) { - return so; - } - } - return NULL; -} - -size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, - int guest_port) -{ - struct iovec iov[2]; - struct socket *so; - - so = slirp_find_ctl_socket(slirp, guest_addr, guest_port); - - if (!so || so->so_state & SS_NOFDREF) { - return 0; - } - - if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen / 2)) { - /* If the sb is already half full, we will wait for the guest to consume it, - * and notify again in sbdrop() when the sb becomes less than half full. */ - return 0; - } - - return sopreprbuf(so, iov, NULL); -} - -void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, - const uint8_t *buf, int size) -{ - int ret; - struct socket *so = slirp_find_ctl_socket(slirp, guest_addr, guest_port); - - if (!so) - return; - - ret = soreadbuf(so, (const char *)buf, size); - - if (ret > 0) - tcp_output(sototcpcb(so)); -} - -void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len) -{ - ssize_t ret = slirp->cb->send_packet(buf, len, slirp->opaque); - - if (ret < 0) { - g_critical("Failed to send packet, ret: %ld", (long)ret); - } else if (ret < len) { - DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu", (long)ret, - (unsigned long)len); - } -} diff --git a/src/network/slirp/slirp.h b/src/network/slirp/slirp.h deleted file mode 100644 index e50c2ffe4f..0000000000 --- a/src/network/slirp/slirp.h +++ /dev/null @@ -1,293 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -#ifndef SLIRP_H -#define SLIRP_H - -#ifdef _WIN32 - -/* as defined in sdkddkver.h */ -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 /* Windows Vista */ -#endif -/* reduces the number of implicitly included headers */ -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include -#include -#include -#include -#include - -#else -#define O_BINARY 0 -#endif - -#ifndef _WIN32 -#include -#include -#include -#include -#include -#endif - -#ifdef __APPLE__ -#include -#endif - -#include "debug.h" -#include "util.h" - -#include "libslirp.h" -#include "ip.h" -#include "ip6.h" -#include "tcp.h" -#include "tcp_timer.h" -#include "tcp_var.h" -#include "tcpip.h" -#include "udp.h" -#include "ip_icmp.h" -#include "ip6_icmp.h" -#include "mbuf.h" -#include "sbuf.h" -#include "socket.h" -#include "if.h" -#include "main.h" -#include "misc.h" - -#include "bootp.h" -#include "tftp.h" - -#define ARPOP_REQUEST 1 /* ARP request */ -#define ARPOP_REPLY 2 /* ARP reply */ - -struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct slirp_arphdr { - unsigned short ar_hrd; /* format of hardware address */ - unsigned short ar_pro; /* format of protocol address */ - unsigned char ar_hln; /* length of hardware address */ - unsigned char ar_pln; /* length of protocol address */ - unsigned short ar_op; /* ARP opcode (command) */ - - /* - * Ethernet looks like this : This bit is variable sized however... - */ - uint8_t ar_sha[ETH_ALEN]; /* sender hardware address */ - uint32_t ar_sip; /* sender IP address */ - uint8_t ar_tha[ETH_ALEN]; /* target hardware address */ - uint32_t ar_tip; /* target IP address */ -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#define ARP_TABLE_SIZE 16 - -typedef struct ArpTable { - struct slirp_arphdr table[ARP_TABLE_SIZE]; - int next_victim; -} ArpTable; - -void arp_table_add(Slirp *slirp, uint32_t ip_addr, - const uint8_t ethaddr[ETH_ALEN]); - -bool arp_table_search(Slirp *slirp, uint32_t ip_addr, - uint8_t out_ethaddr[ETH_ALEN]); - -struct ndpentry { - uint8_t eth_addr[ETH_ALEN]; /* sender hardware address */ - struct in6_addr ip_addr; /* sender IP address */ -}; - -#define NDP_TABLE_SIZE 16 - -typedef struct NdpTable { - struct ndpentry table[NDP_TABLE_SIZE]; - /* - * The table is a cache with old entries overwritten when the table fills. - * Preserve the first entry: it is the guest, which is needed for lazy - * hostfwd guest address assignment. - */ - struct in6_addr guest_in6_addr; - int next_victim; -} NdpTable; - -void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr, - uint8_t ethaddr[ETH_ALEN]); -bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr, - uint8_t out_ethaddr[ETH_ALEN]); - -struct Slirp { - int cfg_version; - - unsigned time_fasttimo; - unsigned last_slowtimo; - bool do_slowtimo; - - bool in_enabled, in6_enabled; - - /* virtual network configuration */ - struct in_addr vnetwork_addr; - struct in_addr vnetwork_mask; - struct in_addr vhost_addr; - struct in6_addr vprefix_addr6; - uint8_t vprefix_len; - struct in6_addr vhost_addr6; - bool disable_dhcp; /* slirp will not reply to any DHCP requests */ - struct in_addr vdhcp_startaddr; - struct in_addr vnameserver_addr; - struct in6_addr vnameserver_addr6; - - struct in_addr client_ipaddr; - char client_hostname[33]; - - int restricted; - struct gfwd_list *guestfwd_list; - - int if_mtu; - int if_mru; - - bool disable_host_loopback; - - /* mbuf states */ - struct slirp_quehead m_freelist; - struct slirp_quehead m_usedlist; - int mbuf_alloced; - - /* if states */ - struct slirp_quehead if_fastq; /* fast queue (for interactive data) */ - struct slirp_quehead if_batchq; /* queue for non-interactive data */ - bool if_start_busy; /* avoid if_start recursion */ - - /* ip states */ - struct ipq ipq; /* ip reass. queue */ - uint16_t ip_id; /* ip packet ctr, for ids */ - - /* bootp/dhcp states */ - BOOTPClient bootp_clients[NB_BOOTP_CLIENTS]; - char *bootp_filename; - size_t vdnssearch_len; - uint8_t *vdnssearch; - char *vdomainname; - - /* tcp states */ - struct socket tcb; - struct socket *tcp_last_so; - tcp_seq tcp_iss; /* tcp initial send seq # */ - uint32_t tcp_now; /* for RFC 1323 timestamps */ - - /* udp states */ - struct socket udb; - struct socket *udp_last_so; - - /* icmp states */ - struct socket icmp; - struct socket *icmp_last_so; - - /* tftp states */ - char *tftp_prefix; - struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; - char *tftp_server_name; - - ArpTable arp_table; - NdpTable ndp_table; - - GRand *grand; - void *ra_timer; - - bool enable_emu; - - const SlirpCb *cb; - void *opaque; - - struct sockaddr_in *outbound_addr; - struct sockaddr_in6 *outbound_addr6; - bool disable_dns; /* slirp will not redirect/serve any DNS packet */ -}; - -void if_start(Slirp *); - -int get_dns_addr(struct in_addr *pdns_addr); -int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id); - -/* ncsi.c */ -void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); - -#ifndef _WIN32 -#include -#endif - - -extern bool slirp_do_keepalive; - -#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL) - -/* dnssearch.c */ -int translate_dnssearch(Slirp *s, const char **names); - -/* cksum.c */ -int cksum(struct mbuf *m, int len); -int ip6_cksum(struct mbuf *m); - -/* if.c */ -void if_init(Slirp *); -void if_output(struct socket *, struct mbuf *); - -/* ip_input.c */ -void ip_init(Slirp *); -void ip_cleanup(Slirp *); -void ip_input(struct mbuf *); -void ip_slowtimo(Slirp *); -void ip_stripoptions(register struct mbuf *, struct mbuf *); - -/* ip_output.c */ -int ip_output(struct socket *, struct mbuf *); - -/* ip6_input.c */ -void ip6_post_init(Slirp *); -void ip6_cleanup(Slirp *); -void ip6_input(struct mbuf *); - -/* ip6_output */ -int ip6_output(struct socket *, struct mbuf *, int fast); - -/* tcp_input.c */ -void tcp_input(register struct mbuf *, int, struct socket *, unsigned short af); -int tcp_mss(register struct tcpcb *, unsigned); - -/* tcp_output.c */ -int tcp_output(register struct tcpcb *); -void tcp_setpersist(register struct tcpcb *); - -/* tcp_subr.c */ -void tcp_init(Slirp *); -void tcp_cleanup(Slirp *); -void tcp_template(struct tcpcb *); -void tcp_respond(struct tcpcb *, register struct tcpiphdr *, - register struct mbuf *, tcp_seq, tcp_seq, int, unsigned short); -struct tcpcb *tcp_newtcpcb(struct socket *); -struct tcpcb *tcp_close(register struct tcpcb *); -void tcp_sockclosed(struct tcpcb *); -int tcp_fconnect(struct socket *, unsigned short af); -void tcp_connect(struct socket *); -void tcp_attach(struct socket *); -uint8_t tcp_tos(struct socket *); -int tcp_emu(struct socket *, struct mbuf *); -int tcp_ctl(struct socket *); -struct tcpcb *tcp_drop(struct tcpcb *tp, int err); - -struct socket *slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr, - int guest_port); - -void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len); -void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque); - -#endif diff --git a/src/network/slirp/socket.c b/src/network/slirp/socket.c deleted file mode 100644 index 22144ffb89..0000000000 --- a/src/network/slirp/socket.c +++ /dev/null @@ -1,1233 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" -#include "ip_icmp.h" -#ifdef __sun__ -#include -#endif -#ifdef __linux__ -#include -#endif - -static void sofcantrcvmore(struct socket *so); -static void sofcantsendmore(struct socket *so); - -struct socket *solookup(struct socket **last, struct socket *head, - struct sockaddr_storage *lhost, - struct sockaddr_storage *fhost) -{ - struct socket *so = *last; - - /* Optimisation */ - if (so != head && sockaddr_equal(&(so->lhost.ss), lhost) && - (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) { - return so; - } - - for (so = head->so_next; so != head; so = so->so_next) { - if (sockaddr_equal(&(so->lhost.ss), lhost) && - (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) { - *last = so; - return so; - } - } - - return (struct socket *)NULL; -} - -/* - * Create a new socket, initialise the fields - * It is the responsibility of the caller to - * slirp_insque() it into the correct linked-list - */ -struct socket *socreate(Slirp *slirp, int type) -{ - struct socket *so = g_new(struct socket, 1); - - memset(so, 0, sizeof(struct socket)); - so->so_type = type; - so->so_state = SS_NOFDREF; - so->s = -1; - so->s_aux = -1; - so->slirp = slirp; - so->pollfds_idx = -1; - - return so; -} - -/* - * Remove references to so from the given message queue. - */ -static void soqfree(struct socket *so, struct slirp_quehead *qh) -{ - struct mbuf *ifq; - - for (ifq = (struct mbuf *)qh->qh_link; (struct slirp_quehead *)ifq != qh; - ifq = ifq->ifq_next) { - if (ifq->ifq_so == so) { - struct mbuf *ifm; - ifq->ifq_so = NULL; - for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) { - ifm->ifq_so = NULL; - } - } - } -} - -/* - * slirp_remque and free a socket, clobber cache - */ -void sofree(struct socket *so) -{ - Slirp *slirp = so->slirp; - - if (so->s_aux != -1) { - closesocket(so->s_aux); - } - - soqfree(so, &slirp->if_fastq); - soqfree(so, &slirp->if_batchq); - - if (so == slirp->tcp_last_so) { - slirp->tcp_last_so = &slirp->tcb; - } else if (so == slirp->udp_last_so) { - slirp->udp_last_so = &slirp->udb; - } else if (so == slirp->icmp_last_so) { - slirp->icmp_last_so = &slirp->icmp; - } - m_free(so->so_m); - - if (so->so_next && so->so_prev) - slirp_remque(so); /* crashes if so is not in a queue */ - - if (so->so_tcpcb) { - g_free(so->so_tcpcb); - } - g_free(so); -} - -size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np) -{ - int n, lss, total; - struct sbuf *sb = &so->so_snd; - int len = sb->sb_datalen - sb->sb_cc; - int mss = so->so_tcpcb->t_maxseg; - - DEBUG_CALL("sopreprbuf"); - DEBUG_ARG("so = %p", so); - - if (len <= 0) - return 0; - - iov[0].iov_base = sb->sb_wptr; - iov[1].iov_base = NULL; - iov[1].iov_len = 0; - if (sb->sb_wptr < sb->sb_rptr) { - iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) - iov[0].iov_len = len; - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len % mss; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) - iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_rptr - sb->sb_data; - if (iov[1].iov_len > len) - iov[1].iov_len = len; - total = iov[0].iov_len + iov[1].iov_len; - if (total > mss) { - lss = total % mss; - if (iov[1].iov_len > lss) { - iov[1].iov_len -= lss; - n = 2; - } else { - lss -= iov[1].iov_len; - iov[0].iov_len -= lss; - n = 1; - } - } else - n = 2; - } else { - if (iov[0].iov_len > mss) - iov[0].iov_len -= iov[0].iov_len % mss; - n = 1; - } - } - if (np) - *np = n; - - return iov[0].iov_len + (n - 1) * iov[1].iov_len; -} - -/* - * Read from so's socket into sb_snd, updating all relevant sbuf fields - * NOTE: This will only be called if it is select()ed for reading, so - * a read() of 0 (or less) means it's disconnected - */ -int soread(struct socket *so) -{ - int n = 0, nn; - size_t buf_len; - struct sbuf *sb = &so->so_snd; - struct iovec iov[2] = {{0, 0}, {0, 0}}; - - DEBUG_CALL("soread"); - DEBUG_ARG("so = %p", so); - - /* - * No need to check if there's enough room to read. - * soread wouldn't have been called if there weren't - */ - buf_len = sopreprbuf(so, iov, &n); - assert(buf_len != 0); - - nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, 0); - if (nn <= 0) { - if (nn < 0 && (errno == EINTR || errno == EAGAIN)) - return 0; - else { - int err; - socklen_t elen = sizeof err; - struct sockaddr_storage addr; - struct sockaddr *paddr = (struct sockaddr *)&addr; - socklen_t alen = sizeof addr; - - err = errno; - if (nn == 0) { - int shutdown_wr = so->so_state & SS_FCANTSENDMORE; - - if (!shutdown_wr && getpeername(so->s, paddr, &alen) < 0) { - err = errno; - } else { - getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &elen); - } - } - - DEBUG_MISC(" --- soread() disconnected, nn = %d, errno = %d-%s", nn, - errno, strerror(errno)); - sofcantrcvmore(so); - - if (err == ECONNABORTED || err == ECONNRESET || err == ECONNREFUSED || - err == ENOTCONN || err == EPIPE) { - tcp_drop(sototcpcb(so), err); - } else { - tcp_sockclosed(sototcpcb(so)); - } - return -1; - } - } - - /* - * If there was no error, try and read the second time round - * We read again if n = 2 (ie, there's another part of the buffer) - * and we read as much as we could in the first read - * We don't test for <= 0 this time, because there legitimately - * might not be any more data (since the socket is non-blocking), - * a close will be detected on next iteration. - * A return of -1 won't (shouldn't) happen, since it didn't happen above - */ - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = recv(so->s, iov[1].iov_base, iov[1].iov_len, 0); - if (ret > 0) - nn += ret; - } - - DEBUG_MISC(" ... read nn = %d bytes", nn); - - /* Update fields */ - sb->sb_cc += nn; - sb->sb_wptr += nn; - if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_wptr -= sb->sb_datalen; - return nn; -} - -int soreadbuf(struct socket *so, const char *buf, int size) -{ - int n, nn, copy = size; - struct sbuf *sb = &so->so_snd; - struct iovec iov[2] = {{0, 0}, {0, 0}}; - - DEBUG_CALL("soreadbuf"); - DEBUG_ARG("so = %p", so); - - /* - * No need to check if there's enough room to read. - * soread wouldn't have been called if there weren't - */ - assert(size > 0); - if (sopreprbuf(so, iov, &n) < size) - goto err; - - nn = MIN(iov[0].iov_len, copy); - memcpy(iov[0].iov_base, buf, nn); - - copy -= nn; - buf += nn; - - if (copy == 0) - goto done; - - memcpy(iov[1].iov_base, buf, copy); - -done: - /* Update fields */ - sb->sb_cc += size; - sb->sb_wptr += size; - if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_wptr -= sb->sb_datalen; - return size; -err: - - sofcantrcvmore(so); - tcp_sockclosed(sototcpcb(so)); - g_critical("soreadbuf buffer too small"); - return -1; -} - -/* - * Get urgent data - * - * When the socket is created, we set it SO_OOBINLINE, - * so when OOB data arrives, we soread() it and everything - * in the send buffer is sent as urgent data - */ -int sorecvoob(struct socket *so) -{ - struct tcpcb *tp = sototcpcb(so); - int ret; - - DEBUG_CALL("sorecvoob"); - DEBUG_ARG("so = %p", so); - - /* - * We take a guess at how much urgent data has arrived. - * In most situations, when urgent data arrives, the next - * read() should get all the urgent data. This guess will - * be wrong however if more data arrives just after the - * urgent data, or the read() doesn't return all the - * urgent data. - */ - ret = soread(so); - if (ret > 0) { - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_force = 1; - tcp_output(tp); - tp->t_force = 0; - } - - return ret; -} - -/* - * Send urgent data - * There's a lot duplicated code here, but... - */ -int sosendoob(struct socket *so) -{ - struct sbuf *sb = &so->so_rcv; - char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ - - int n; - - DEBUG_CALL("sosendoob"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); - - if (so->so_urgc > sizeof(buff)) - so->so_urgc = sizeof(buff); /* XXXX */ - - if (sb->sb_rptr < sb->sb_wptr) { - /* We can send it directly */ - n = slirp_send(so, sb->sb_rptr, so->so_urgc, - (MSG_OOB)); /* |MSG_DONTWAIT)); */ - } else { - /* - * Since there's no sendv or sendtov like writev, - * we must copy all data to a linear buffer then - * send it all - */ - uint32_t urgc = so->so_urgc; /* Amount of room left in buff */ - int len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (len > urgc) { - len = urgc; - } - memcpy(buff, sb->sb_rptr, len); - urgc -= len; - if (urgc) { - /* We still have some room for the rest */ - n = sb->sb_wptr - sb->sb_data; - if (n > urgc) { - n = urgc; - } - memcpy((buff + len), sb->sb_data, n); - len += n; - } - n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */ -#ifdef SLIRP_DEBUG - if (n != len) { - DEBUG_ERROR("Didn't send all data urgently XXXXX"); - } -#endif - } - - if (n < 0) { - return n; - } - so->so_urgc -= n; - DEBUG_MISC(" ---2 sent %d bytes urgent data, %d urgent bytes left", n, - so->so_urgc); - - sb->sb_cc -= n; - sb->sb_rptr += n; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - return n; -} - -/* - * Write data from so_rcv to so's socket, - * updating all sbuf field as necessary - */ -int sowrite(struct socket *so) -{ - int n, nn; - struct sbuf *sb = &so->so_rcv; - int len = sb->sb_cc; - struct iovec iov[2] = {{0, 0}, {0, 0}}; - - DEBUG_CALL("sowrite"); - DEBUG_ARG("so = %p", so); - - if (so->so_urgc) { - uint32_t expected = so->so_urgc; - if (sosendoob(so) < expected) { - /* Treat a short write as a fatal error too, - * rather than continuing on and sending the urgent - * data as if it were non-urgent and leaving the - * so_urgc count wrong. - */ - goto err_disconnected; - } - if (sb->sb_cc == 0) - return 0; - } - - /* - * No need to check if there's something to write, - * sowrite wouldn't have been called otherwise - */ - - iov[0].iov_base = sb->sb_rptr; - iov[1].iov_base = NULL; - iov[1].iov_len = 0; - if (sb->sb_rptr < sb->sb_wptr) { - iov[0].iov_len = sb->sb_wptr - sb->sb_rptr; - /* Should never succeed, but... */ - if (iov[0].iov_len > len) - iov[0].iov_len = len; - n = 1; - } else { - iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; - if (iov[0].iov_len > len) - iov[0].iov_len = len; - len -= iov[0].iov_len; - if (len) { - iov[1].iov_base = sb->sb_data; - iov[1].iov_len = sb->sb_wptr - sb->sb_data; - if (iov[1].iov_len > len) - iov[1].iov_len = len; - n = 2; - } else - n = 1; - } - /* Check if there's urgent data to send, and if so, send it */ - - nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len, 0); - /* This should never happen, but people tell me it does *shrug* */ - if (nn < 0 && (errno == EAGAIN || errno == EINTR)) - return 0; - - if (nn <= 0) { - goto err_disconnected; - } - - if (n == 2 && nn == iov[0].iov_len) { - int ret; - ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len, 0); - if (ret > 0) - nn += ret; - } - DEBUG_MISC(" ... wrote nn = %d bytes", nn); - - /* Update sbuf */ - sb->sb_cc -= nn; - sb->sb_rptr += nn; - if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) - sb->sb_rptr -= sb->sb_datalen; - - /* - * If in DRAIN mode, and there's no more data, set - * it CANTSENDMORE - */ - if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) - sofcantsendmore(so); - - return nn; - -err_disconnected: - DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d", - so->so_state, errno); - sofcantsendmore(so); - tcp_sockclosed(sototcpcb(so)); - return -1; -} - -/* - * recvfrom() a UDP socket - */ -void sorecvfrom(struct socket *so) -{ - struct sockaddr_storage addr; - struct sockaddr_storage saddr, daddr; - socklen_t addrlen = sizeof(struct sockaddr_storage); - char buff[256]; - -#ifdef __linux__ - ssize_t size; - struct msghdr msg; - struct iovec iov; - char control[1024]; - - /* First look for errors */ - memset(&msg, 0, sizeof(msg)); - msg.msg_name = &saddr; - msg.msg_namelen = sizeof(saddr); - msg.msg_control = control; - msg.msg_controllen = sizeof(control); - iov.iov_base = buff; - iov.iov_len = sizeof(buff); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - size = recvmsg(so->s, &msg, MSG_ERRQUEUE); - if (size >= 0) { - struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == IP_RECVERR) { - struct sock_extended_err *ee = - (struct sock_extended_err *) CMSG_DATA(cmsg); - - if (ee->ee_origin == SO_EE_ORIGIN_ICMP) { - /* Got an ICMP error, forward it */ - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *) SO_EE_OFFENDER(ee); - icmp_forward_error(so->so_m, ee->ee_type, ee->ee_code, - 0, NULL, &sin->sin_addr); - } - } - else if (cmsg->cmsg_level == IPPROTO_IPV6 && - cmsg->cmsg_type == IPV6_RECVERR) { - struct sock_extended_err *ee = - (struct sock_extended_err *) CMSG_DATA(cmsg); - - if (ee->ee_origin == SO_EE_ORIGIN_ICMP6) { - /* Got an ICMPv6 error, forward it */ - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *) SO_EE_OFFENDER(ee); - icmp6_forward_error(so->so_m, ee->ee_type, ee->ee_code, - &sin6->sin6_addr); - } - } - } - return; - } -#endif - - DEBUG_CALL("sorecvfrom"); - DEBUG_ARG("so = %p", so); - - if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ - int len; - - len = recvfrom(so->s, buff, 256, 0, (struct sockaddr *)&addr, &addrlen); - /* XXX Check if reply is "correct"? */ - - if (len == -1 || len == 0) { - uint8_t code = ICMP_UNREACH_PORT; - - if (errno == EHOSTUNREACH) - code = ICMP_UNREACH_HOST; - else if (errno == ENETUNREACH) - code = ICMP_UNREACH_NET; - - DEBUG_MISC(" udp icmp rx errno = %d-%s", errno, strerror(errno)); - icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno)); - } else { - icmp_reflect(so->so_m); - so->so_m = NULL; /* Don't m_free() it again! */ - } - /* No need for this socket anymore, udp_detach it */ - udp_detach(so); - } else { /* A "normal" UDP packet */ - struct mbuf *m; - int len; -#ifdef _WIN32 - unsigned long n; -#else - int n; -#endif - - if (ioctlsocket(so->s, FIONREAD, &n) != 0) { - DEBUG_MISC(" ioctlsocket errno = %d-%s\n", errno, strerror(errno)); - return; - } - - m = m_get(so->slirp); - if (!m) { - return; - } - switch (so->so_ffamily) { - case AF_INET: - m->m_data += IF_MAXLINKHDR + sizeof(struct udpiphdr); - break; - case AF_INET6: - m->m_data += - IF_MAXLINKHDR + sizeof(struct ip6) + sizeof(struct udphdr); - break; - default: - g_assert_not_reached(); - } - - /* - * XXX Shouldn't FIONREAD packets destined for port 53, - * but I don't know the max packet size for DNS lookups - */ - len = M_FREEROOM(m); - /* if (so->so_fport != htons(53)) { */ - - if (n > len) { - n = (m->m_data - m->m_dat) + m->m_len + n + 1; - m_inc(m, n); - len = M_FREEROOM(m); - } - /* } */ - - m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr, - &addrlen); - DEBUG_MISC(" did recvfrom %d, errno = %d-%s", m->m_len, errno, - strerror(errno)); - if (m->m_len < 0) { - /* Report error as ICMP */ - switch (so->so_lfamily) { - uint8_t code; - case AF_INET: - code = ICMP_UNREACH_PORT; - - if (errno == EHOSTUNREACH) { - code = ICMP_UNREACH_HOST; - } else if (errno == ENETUNREACH) { - code = ICMP_UNREACH_NET; - } - - DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code); - icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, - strerror(errno)); - break; - case AF_INET6: - code = ICMP6_UNREACH_PORT; - - if (errno == EHOSTUNREACH) { - code = ICMP6_UNREACH_ADDRESS; - } else if (errno == ENETUNREACH) { - code = ICMP6_UNREACH_NO_ROUTE; - } - - DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code); - icmp6_send_error(so->so_m, ICMP6_UNREACH, code); - break; - default: - g_assert_not_reached(); - } - m_free(m); - } else { - /* - * Hack: domain name lookup will be used the most for UDP, - * and since they'll only be used once there's no need - * for the 4 minute (or whatever) timeout... So we time them - * out much quicker (10 seconds for now...) - */ - if (so->so_expire) { - if (so->so_fport == htons(53)) - so->so_expire = curtime + SO_EXPIREFAST; - else - so->so_expire = curtime + SO_EXPIRE; - } - - /* - * If this packet was destined for CTL_ADDR, - * make it look like that's where it came from - */ - saddr = addr; - sotranslate_in(so, &saddr); - - /* Perform lazy guest IP address resolution if needed. */ - if (so->so_state & SS_HOSTFWD) { - if (soassign_guest_addr_if_needed(so) < 0) { - DEBUG_MISC(" guest address not available yet"); - switch (so->so_lfamily) { - case AF_INET: - icmp_send_error(so->so_m, ICMP_UNREACH, - ICMP_UNREACH_HOST, 0, - "guest address not available yet"); - break; - case AF_INET6: - icmp6_send_error(so->so_m, ICMP6_UNREACH, - ICMP6_UNREACH_ADDRESS); - break; - default: - g_assert_not_reached(); - } - m_free(m); - return; - } - } - daddr = so->lhost.ss; - - switch (so->so_ffamily) { - case AF_INET: - udp_output(so, m, (struct sockaddr_in *)&saddr, - (struct sockaddr_in *)&daddr, so->so_iptos); - break; - case AF_INET6: - udp6_output(so, m, (struct sockaddr_in6 *)&saddr, - (struct sockaddr_in6 *)&daddr); - break; - default: - g_assert_not_reached(); - } - } /* rx error */ - } /* if ping packet */ -} - -/* - * sendto() a socket - */ -int sosendto(struct socket *so, struct mbuf *m) -{ - int ret; - struct sockaddr_storage addr; - - DEBUG_CALL("sosendto"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - - addr = so->fhost.ss; - DEBUG_CALL(" sendto()ing)"); - if (sotranslate_out(so, &addr) < 0) { - return -1; - } - - /* Don't care what port we get */ - ret = sendto(so->s, m->m_data, m->m_len, 0, (struct sockaddr *)&addr, - sockaddr_size(&addr)); - if (ret < 0) - return -1; - - /* - * Kill the socket if there's no reply in 4 minutes, - * but only if it's an expirable socket - */ - if (so->so_expire) - so->so_expire = curtime + SO_EXPIRE; - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */ - return 0; -} - -/* - * Listen for incoming TCP connections - * On failure errno contains the reason. - */ -struct socket *tcpx_listen(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *laddr, socklen_t laddrlen, - int flags) -{ - struct socket *so; - int s, opt = 1; - socklen_t addrlen; - - DEBUG_CALL("tcpx_listen"); - /* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */ - char addrstr[INET6_ADDRSTRLEN]; - char portstr[6]; - int ret; - switch (haddr->sa_family) { - case AF_INET: - case AF_INET6: - ret = getnameinfo(haddr, haddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); - g_assert(ret == 0); - DEBUG_ARG("hfamily = INET"); - DEBUG_ARG("haddr = %s", addrstr); - DEBUG_ARG("hport = %s", portstr); - break; -#ifndef _WIN32 - case AF_UNIX: - DEBUG_ARG("hfamily = UNIX"); - DEBUG_ARG("hpath = %s", ((struct sockaddr_un *) haddr)->sun_path); - break; -#endif - default: - g_assert_not_reached(); - } - switch (laddr->sa_family) { - case AF_INET: - case AF_INET6: - ret = getnameinfo(laddr, laddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); - g_assert(ret == 0); - DEBUG_ARG("laddr = %s", addrstr); - DEBUG_ARG("lport = %s", portstr); - break; - default: - g_assert_not_reached(); - } - DEBUG_ARG("flags = %x", flags); - - /* - * SS_HOSTFWD sockets can be accepted multiple times, so they can't be - * SS_FACCEPTONCE. Also, SS_HOSTFWD connections can be accepted and - * immediately closed if the guest address isn't available yet, which is - * incompatible with the "accept once" concept. Correct code will never - * request both, so disallow their combination by assertion. - */ - g_assert(!((flags & SS_HOSTFWD) && (flags & SS_FACCEPTONCE))); - - so = socreate(slirp, IPPROTO_TCP); - - /* Don't tcp_attach... we don't need so_snd nor so_rcv */ - so->so_tcpcb = tcp_newtcpcb(so); - slirp_insque(so, &slirp->tcb); - - /* - * SS_FACCEPTONCE sockets must time out. - */ - if (flags & SS_FACCEPTONCE) - so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT * 2; - - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= (SS_FACCEPTCONN | flags); - - sockaddr_copy(&so->lhost.sa, sizeof(so->lhost), laddr, laddrlen); - - s = slirp_socket(haddr->sa_family, SOCK_STREAM, 0); - if ((s < 0) || - (haddr->sa_family == AF_INET6 && slirp_socket_set_v6only(s, (flags & SS_HOSTFWD_V6ONLY) != 0) < 0) || - (slirp_socket_set_fast_reuse(s) < 0) || - (bind(s, haddr, haddrlen) < 0) || - (listen(s, 1) < 0)) { - int tmperrno = errno; /* Don't clobber the real reason we failed */ - if (s >= 0) { - closesocket(s); - } - sofree(so); - /* Restore the real errno */ -#ifdef _WIN32 - WSASetLastError(tmperrno); -#else - errno = tmperrno; -#endif - return NULL; - } - setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int)); - slirp_socket_set_nodelay(s); - - addrlen = sizeof(so->fhost); - getsockname(s, &so->fhost.sa, &addrlen); - sotranslate_accept(so); - - so->s = s; - return so; -} - -struct socket *tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, - uint32_t laddr, unsigned lport, int flags) -{ - struct sockaddr_in hsa, lsa; - - memset(&hsa, 0, sizeof(hsa)); - hsa.sin_family = AF_INET; - hsa.sin_addr.s_addr = haddr; - hsa.sin_port = hport; - - memset(&lsa, 0, sizeof(lsa)); - lsa.sin_family = AF_INET; - lsa.sin_addr.s_addr = laddr; - lsa.sin_port = lport; - - return tcpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags); -} - -/* - * Various session state calls - * XXX Should be #define's - * The socket state stuff needs work, these often get call 2 or 3 - * times each when only 1 was needed - */ -void soisfconnecting(struct socket *so) -{ - so->so_state &= ~(SS_NOFDREF | SS_ISFCONNECTED | SS_FCANTRCVMORE | - SS_FCANTSENDMORE | SS_FWDRAIN); - so->so_state |= SS_ISFCONNECTING; /* Clobber other states */ -} - -void soisfconnected(struct socket *so) -{ - so->so_state &= ~(SS_ISFCONNECTING | SS_FWDRAIN | SS_NOFDREF); - so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ -} - -static void sofcantrcvmore(struct socket *so) -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s, 0); - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTSENDMORE) { - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_NOFDREF; /* Don't select it */ - } else { - so->so_state |= SS_FCANTRCVMORE; - } -} - -static void sofcantsendmore(struct socket *so) -{ - if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s, 1); /* send FIN to fhost */ - } - so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTRCVMORE) { - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_NOFDREF; /* as above */ - } else { - so->so_state |= SS_FCANTSENDMORE; - } -} - -/* - * Set write drain mode - * Set CANTSENDMORE once all data has been write()n - */ -void sofwdrain(struct socket *so) -{ - if (so->so_rcv.sb_cc) - so->so_state |= SS_FWDRAIN; - else - sofcantsendmore(so); -} - -static bool sotranslate_out4(Slirp *s, struct socket *so, struct sockaddr_in *sin) -{ - if (!s->disable_dns && so->so_faddr.s_addr == s->vnameserver_addr.s_addr) { - return so->so_fport == htons(53) && get_dns_addr(&sin->sin_addr) >= 0; - } - - if (so->so_faddr.s_addr == s->vhost_addr.s_addr || - so->so_faddr.s_addr == 0xffffffff) { - if (s->disable_host_loopback) { - return false; - } - - sin->sin_addr = loopback_addr; - } - - return true; -} - -static bool sotranslate_out6(Slirp *s, struct socket *so, struct sockaddr_in6 *sin) -{ - if (!s->disable_dns && in6_equal(&so->so_faddr6, &s->vnameserver_addr6)) { - uint32_t scope_id; - if (so->so_fport == htons(53) && get_dns6_addr(&sin->sin6_addr, &scope_id) >= 0) { - sin->sin6_scope_id = scope_id; - return true; - } - return false; - } - - if (in6_equal_net(&so->so_faddr6, &s->vprefix_addr6, s->vprefix_len) || - in6_equal(&so->so_faddr6, &(struct in6_addr)ALLNODES_MULTICAST)) { - if (s->disable_host_loopback) { - return false; - } - - sin->sin6_addr = in6addr_loopback; - } - - return true; -} - - -/* - * Translate addr in host addr when it is a virtual address - */ -int sotranslate_out(struct socket *so, struct sockaddr_storage *addr) -{ - bool ok = true; - - switch (addr->ss_family) { - case AF_INET: - ok = sotranslate_out4(so->slirp, so, (struct sockaddr_in *)addr); - break; - case AF_INET6: - ok = sotranslate_out6(so->slirp, so, (struct sockaddr_in6 *)addr); - break; - } - - if (!ok) { - errno = EPERM; - return -1; - } - - return 0; -} - -void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) -{ - Slirp *slirp = so->slirp; - struct sockaddr_in *sin = (struct sockaddr_in *)addr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; - - switch (addr->ss_family) { - case AF_INET: - if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) == - slirp->vnetwork_addr.s_addr) { - uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr; - - if ((so->so_faddr.s_addr & inv_mask) == inv_mask) { - sin->sin_addr = slirp->vhost_addr; - } else if (sin->sin_addr.s_addr == loopback_addr.s_addr || - so->so_faddr.s_addr != slirp->vhost_addr.s_addr) { - sin->sin_addr = so->so_faddr; - } - } - break; - - case AF_INET6: - if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6, - slirp->vprefix_len)) { - if (in6_equal(&sin6->sin6_addr, &in6addr_loopback) || - !in6_equal(&so->so_faddr6, &slirp->vhost_addr6)) { - sin6->sin6_addr = so->so_faddr6; - } - } - break; - - default: - break; - } -} - -/* - * Translate connections from localhost to the real hostname - */ -void sotranslate_accept(struct socket *so) -{ - Slirp *slirp = so->slirp; - - switch (so->so_ffamily) { - case AF_INET: - if (so->so_faddr.s_addr == INADDR_ANY || - (so->so_faddr.s_addr & loopback_mask) == - (loopback_addr.s_addr & loopback_mask)) { - so->so_faddr = slirp->vhost_addr; - } - break; - - case AF_INET6: - if (in6_equal(&so->so_faddr6, &in6addr_any) || - in6_equal(&so->so_faddr6, &in6addr_loopback)) { - so->so_faddr6 = slirp->vhost_addr6; - } - break; - - case AF_UNIX: { - /* Translate Unix socket to random ephemeral source port. We obtain - * this source port by binding to port 0 so that the OS allocates a - * port for us. If this fails, we fall back to choosing a random port - * with a random number generator. */ - int s; - struct sockaddr_in in_addr; - struct sockaddr_in6 in6_addr; - socklen_t in_addr_len; - - if (so->slirp->in_enabled) { - so->so_ffamily = AF_INET; - so->so_faddr = slirp->vhost_addr; - so->so_fport = 0; - - switch (so->so_type) { - case IPPROTO_TCP: - s = slirp_socket(PF_INET, SOCK_STREAM, 0); - break; - case IPPROTO_UDP: - s = slirp_socket(PF_INET, SOCK_DGRAM, 0); - break; - default: - g_assert_not_reached(); - break; - } - if (s < 0) { - g_error("Ephemeral slirp_socket() allocation failed"); - goto unix2inet_cont; - } - memset(&in_addr, 0, sizeof(in_addr)); - in_addr.sin_family = AF_INET; - in_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - in_addr.sin_port = htons(0); - if (bind(s, (struct sockaddr *) &in_addr, sizeof(in_addr))) { - g_error("Ephemeral bind() failed"); - closesocket(s); - goto unix2inet_cont; - } - in_addr_len = sizeof(in_addr); - if (getsockname(s, (struct sockaddr *) &in_addr, &in_addr_len)) { - g_error("Ephemeral getsockname() failed"); - closesocket(s); - goto unix2inet_cont; - } - so->s_aux = s; - so->so_fport = in_addr.sin_port; - -unix2inet_cont: - if (!so->so_fport) { - g_warning("Falling back to random port allocation"); - so->so_fport = htons(g_rand_int_range(slirp->grand, 49152, 65536)); - } - } else if (so->slirp->in6_enabled) { - so->so_ffamily = AF_INET6; - so->so_faddr6 = slirp->vhost_addr6; - so->so_fport6 = 0; - - switch (so->so_type) { - case IPPROTO_TCP: - s = slirp_socket(PF_INET6, SOCK_STREAM, 0); - break; - case IPPROTO_UDP: - s = slirp_socket(PF_INET6, SOCK_DGRAM, 0); - break; - default: - g_assert_not_reached(); - break; - } - if (s < 0) { - g_error("Ephemeral slirp_socket() allocation failed"); - goto unix2inet6_cont; - } - memset(&in6_addr, 0, sizeof(in6_addr)); - in6_addr.sin6_family = AF_INET6; - in6_addr.sin6_addr = in6addr_loopback; - in6_addr.sin6_port = htons(0); - if (bind(s, (struct sockaddr *) &in6_addr, sizeof(in6_addr))) { - g_error("Ephemeral bind() failed"); - closesocket(s); - goto unix2inet6_cont; - } - in_addr_len = sizeof(in6_addr); - if (getsockname(s, (struct sockaddr *) &in6_addr, &in_addr_len)) { - g_error("Ephemeral getsockname() failed"); - closesocket(s); - goto unix2inet6_cont; - } - so->s_aux = s; - so->so_fport6 = in6_addr.sin6_port; - -unix2inet6_cont: - if (!so->so_fport6) { - g_warning("Falling back to random port allocation"); - so->so_fport6 = htons(g_rand_int_range(slirp->grand, 49152, 65536)); - } - } else { - g_assert_not_reached(); - } - break; - } /* case AF_UNIX */ - - default: - break; - } -} - -void sodrop(struct socket *s, int num) -{ - if (sbdrop(&s->so_snd, num)) { - s->slirp->cb->notify(s->slirp->opaque); - } -} - -/* - * Translate "addr-any" in so->lhost to the guest's actual address. - * Returns 0 for success, or -1 if the guest doesn't have an address yet - * with errno set to EHOSTUNREACH. - * - * The guest address is taken from the first entry in the ARP table for IPv4 - * and the first entry in the NDP table for IPv6. - * Note: The IPv4 path isn't exercised yet as all hostfwd "" guest translations - * are handled immediately by using slirp->vdhcp_startaddr. - */ -int soassign_guest_addr_if_needed(struct socket *so) -{ - Slirp *slirp = so->slirp; - /* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */ - char addrstr[INET6_ADDRSTRLEN]; - char portstr[6]; - - g_assert(so->so_state & SS_HOSTFWD); - - switch (so->so_ffamily) { - case AF_INET: - if (so->so_laddr.s_addr == INADDR_ANY) { - g_assert_not_reached(); - } - break; - - case AF_INET6: - if (in6_zero(&so->so_laddr6)) { - int ret; - if (in6_zero(&slirp->ndp_table.guest_in6_addr)) { - errno = EHOSTUNREACH; - return -1; - } - so->so_laddr6 = slirp->ndp_table.guest_in6_addr; - ret = getnameinfo((const struct sockaddr *) &so->lhost.ss, - sizeof(so->lhost.ss), addrstr, sizeof(addrstr), - portstr, sizeof(portstr), - NI_NUMERICHOST|NI_NUMERICSERV); - g_assert(ret == 0); - DEBUG_MISC("%s: new ip = [%s]:%s", __func__, addrstr, portstr); - } - break; - - default: - break; - } - - return 0; -} diff --git a/src/network/slirp/socket.h b/src/network/slirp/socket.h deleted file mode 100644 index ca8c103ec7..0000000000 --- a/src/network/slirp/socket.h +++ /dev/null @@ -1,206 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1995 Danny Gasparovski. - */ - -#ifndef SLIRP_SOCKET_H -#define SLIRP_SOCKET_H - -#include - -#ifndef _WIN32 -#include -#endif - -#include "misc.h" -#include "sbuf.h" - -#define SO_EXPIRE 240000 -#define SO_EXPIREFAST 10000 - -/* Helps unify some in/in6 routines. */ -union in4or6_addr { - struct in_addr addr4; - struct in6_addr addr6; -}; -typedef union in4or6_addr in4or6_addr; - -/* - * Our socket structure - */ - -union slirp_sockaddr { - struct sockaddr sa; - struct sockaddr_storage ss; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; -}; - -struct socket { - struct socket *so_next, *so_prev; /* For a linked list of sockets */ - - int s; /* The actual socket */ - int s_aux; /* An auxiliary socket for miscellaneous use. Currently used to - * reserve OS ports in UNIX-to-inet translation. */ - struct gfwd_list *guestfwd; - - int pollfds_idx; /* GPollFD GArray index */ - - Slirp *slirp; /* managing slirp instance */ - - /* XXX union these with not-yet-used sbuf params */ - struct mbuf *so_m; /* Pointer to the original SYN packet, - * for non-blocking connect()'s, and - * PING reply's */ - struct tcpiphdr *so_ti; /* Pointer to the original ti within - * so_mconn, for non-blocking connections */ - uint32_t so_urgc; - union slirp_sockaddr fhost; /* Foreign host */ -#define so_faddr fhost.sin.sin_addr -#define so_fport fhost.sin.sin_port -#define so_faddr6 fhost.sin6.sin6_addr -#define so_fport6 fhost.sin6.sin6_port -#define so_ffamily fhost.ss.ss_family - - union slirp_sockaddr lhost; /* Local host */ -#define so_laddr lhost.sin.sin_addr -#define so_lport lhost.sin.sin_port -#define so_laddr6 lhost.sin6.sin6_addr -#define so_lport6 lhost.sin6.sin6_port -#define so_lfamily lhost.ss.ss_family - - uint8_t so_iptos; /* Type of service */ - uint8_t so_emu; /* Is the socket emulated? */ - - uint8_t so_type; /* Protocol of the socket. May be 0 if loading old - * states. */ - int32_t so_state; /* internal state flags SS_*, below */ - - struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ - unsigned so_expire; /* When the socket will expire */ - - int so_queued; /* Number of packets queued from this socket */ - int so_nqueued; /* Number of packets queued in a row - * Used to determine when to "downgrade" a session - * from fastq to batchq */ - - struct sbuf so_rcv; /* Receive buffer */ - struct sbuf so_snd; /* Send buffer */ -}; - - -/* - * Socket state bits. (peer means the host on the Internet, - * local host means the host on the other end of the modem) - */ -#define SS_NOFDREF 0x001 /* No fd reference */ - -#define SS_ISFCONNECTING \ - 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */ -#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */ -#define SS_FCANTRCVMORE \ - 0x008 /* Socket can't receive more from peer (for half-closes) */ -#define SS_FCANTSENDMORE \ - 0x010 /* Socket can't send more to peer (for half-closes) */ -#define SS_FWDRAIN \ - 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ - -#define SS_CTL 0x080 -#define SS_FACCEPTCONN \ - 0x100 /* Socket is accepting connections from a host on the internet */ -#define SS_FACCEPTONCE \ - 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ - -#define SS_PERSISTENT_MASK 0xf000 /* Unremovable state bits */ -#define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */ -#define SS_INCOMING \ - 0x2000 /* Connection was initiated by a host on the internet */ -#define SS_HOSTFWD_V6ONLY 0x4000 /* Only bind on v6 addresses */ - -static inline int sockaddr_equal(const struct sockaddr_storage *a, - const struct sockaddr_storage *b) -{ - if (a->ss_family != b->ss_family) { - return 0; - } - - switch (a->ss_family) { - case AF_INET: { - const struct sockaddr_in *a4 = (const struct sockaddr_in *)a; - const struct sockaddr_in *b4 = (const struct sockaddr_in *)b; - return a4->sin_addr.s_addr == b4->sin_addr.s_addr && - a4->sin_port == b4->sin_port; - } - case AF_INET6: { - const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)a; - const struct sockaddr_in6 *b6 = (const struct sockaddr_in6 *)b; - return (in6_equal(&a6->sin6_addr, &b6->sin6_addr) && - a6->sin6_port == b6->sin6_port); - } -#ifndef _WIN32 - case AF_UNIX: { - const struct sockaddr_un *aun = (const struct sockaddr_un *)a; - const struct sockaddr_un *bun = (const struct sockaddr_un *)b; - return strncmp(aun->sun_path, bun->sun_path, sizeof(aun->sun_path)) == 0; - } -#endif - default: - g_assert_not_reached(); - } - - return 0; -} - -static inline socklen_t sockaddr_size(const struct sockaddr_storage *a) -{ - switch (a->ss_family) { - case AF_INET: - return sizeof(struct sockaddr_in); - case AF_INET6: - return sizeof(struct sockaddr_in6); -#ifndef _WIN32 - case AF_UNIX: - return sizeof(struct sockaddr_un); -#endif - default: - g_assert_not_reached(); - } -} - -static inline void sockaddr_copy(struct sockaddr *dst, socklen_t dstlen, const struct sockaddr *src, socklen_t srclen) -{ - socklen_t len = sockaddr_size((const struct sockaddr_storage *) src); - g_assert(len <= srclen); - g_assert(len <= dstlen); - memcpy(dst, src, len); -} - -struct socket *solookup(struct socket **, struct socket *, - struct sockaddr_storage *, struct sockaddr_storage *); -struct socket *socreate(Slirp *, int); -void sofree(struct socket *); -int soread(struct socket *); -int sorecvoob(struct socket *); -int sosendoob(struct socket *); -int sowrite(struct socket *); -void sorecvfrom(struct socket *); -int sosendto(struct socket *, struct mbuf *); -struct socket *tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int); -struct socket *tcpx_listen(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *laddr, socklen_t laddrlen, - int flags); -void soisfconnecting(register struct socket *); -void soisfconnected(register struct socket *); -void sofwdrain(struct socket *); -struct iovec; /* For win32 */ -size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np); -int soreadbuf(struct socket *so, const char *buf, int size); - -int sotranslate_out(struct socket *, struct sockaddr_storage *); -void sotranslate_in(struct socket *, struct sockaddr_storage *); -void sotranslate_accept(struct socket *); -void sodrop(struct socket *, int num); -int soassign_guest_addr_if_needed(struct socket *so); - -#endif /* SLIRP_SOCKET_H */ diff --git a/src/network/slirp/state.c b/src/network/slirp/state.c deleted file mode 100644 index 8708547476..0000000000 --- a/src/network/slirp/state.c +++ /dev/null @@ -1,379 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * libslirp - * - * Copyright (c) 2004-2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "slirp.h" -#include "vmstate.h" -#include "stream.h" - -static int slirp_tcp_post_load(void *opaque, int version) -{ - tcp_template((struct tcpcb *)opaque); - - return 0; -} - -static const VMStateDescription vmstate_slirp_tcp = { - .name = "slirp-tcp", - .version_id = 0, - .post_load = slirp_tcp_post_load, - .fields = (VMStateField[]){ VMSTATE_INT16(t_state, struct tcpcb), - VMSTATE_INT16_ARRAY(t_timer, struct tcpcb, - TCPT_NTIMERS), - VMSTATE_INT16(t_rxtshift, struct tcpcb), - VMSTATE_INT16(t_rxtcur, struct tcpcb), - VMSTATE_INT16(t_dupacks, struct tcpcb), - VMSTATE_UINT16(t_maxseg, struct tcpcb), - VMSTATE_UINT8(t_force, struct tcpcb), - VMSTATE_UINT16(t_flags, struct tcpcb), - VMSTATE_UINT32(snd_una, struct tcpcb), - VMSTATE_UINT32(snd_nxt, struct tcpcb), - VMSTATE_UINT32(snd_up, struct tcpcb), - VMSTATE_UINT32(snd_wl1, struct tcpcb), - VMSTATE_UINT32(snd_wl2, struct tcpcb), - VMSTATE_UINT32(iss, struct tcpcb), - VMSTATE_UINT32(snd_wnd, struct tcpcb), - VMSTATE_UINT32(rcv_wnd, struct tcpcb), - VMSTATE_UINT32(rcv_nxt, struct tcpcb), - VMSTATE_UINT32(rcv_up, struct tcpcb), - VMSTATE_UINT32(irs, struct tcpcb), - VMSTATE_UINT32(rcv_adv, struct tcpcb), - VMSTATE_UINT32(snd_max, struct tcpcb), - VMSTATE_UINT32(snd_cwnd, struct tcpcb), - VMSTATE_UINT32(snd_ssthresh, struct tcpcb), - VMSTATE_INT16(t_idle, struct tcpcb), - VMSTATE_INT16(t_rtt, struct tcpcb), - VMSTATE_UINT32(t_rtseq, struct tcpcb), - VMSTATE_INT16(t_srtt, struct tcpcb), - VMSTATE_INT16(t_rttvar, struct tcpcb), - VMSTATE_UINT16(t_rttmin, struct tcpcb), - VMSTATE_UINT32(max_sndwnd, struct tcpcb), - VMSTATE_UINT8(t_oobflags, struct tcpcb), - VMSTATE_UINT8(t_iobc, struct tcpcb), - VMSTATE_INT16(t_softerror, struct tcpcb), - VMSTATE_UINT8(snd_scale, struct tcpcb), - VMSTATE_UINT8(rcv_scale, struct tcpcb), - VMSTATE_UINT8(request_r_scale, struct tcpcb), - VMSTATE_UINT8(requested_s_scale, struct tcpcb), - VMSTATE_UINT32(ts_recent, struct tcpcb), - VMSTATE_UINT32(ts_recent_age, struct tcpcb), - VMSTATE_UINT32(last_ack_sent, struct tcpcb), - VMSTATE_END_OF_LIST() } -}; - -/* The sbuf has a pair of pointers that are migrated as offsets; - * we calculate the offsets and restore the pointers using - * pre_save/post_load on a tmp structure. - */ -struct sbuf_tmp { - struct sbuf *parent; - uint32_t roff, woff; -}; - -static int sbuf_tmp_pre_save(void *opaque) -{ - struct sbuf_tmp *tmp = opaque; - tmp->woff = tmp->parent->sb_wptr - tmp->parent->sb_data; - tmp->roff = tmp->parent->sb_rptr - tmp->parent->sb_data; - - return 0; -} - -static int sbuf_tmp_post_load(void *opaque, int version) -{ - struct sbuf_tmp *tmp = opaque; - uint32_t requested_len = tmp->parent->sb_datalen; - - /* Allocate the buffer space used by the field after the tmp */ - sbreserve(tmp->parent, tmp->parent->sb_datalen); - - if (tmp->woff >= requested_len || tmp->roff >= requested_len) { - g_critical("invalid sbuf offsets r/w=%u/%u len=%u", tmp->roff, - tmp->woff, requested_len); - return -EINVAL; - } - - tmp->parent->sb_wptr = tmp->parent->sb_data + tmp->woff; - tmp->parent->sb_rptr = tmp->parent->sb_data + tmp->roff; - - return 0; -} - - -static const VMStateDescription vmstate_slirp_sbuf_tmp = { - .name = "slirp-sbuf-tmp", - .post_load = sbuf_tmp_post_load, - .pre_save = sbuf_tmp_pre_save, - .version_id = 0, - .fields = (VMStateField[]){ VMSTATE_UINT32(woff, struct sbuf_tmp), - VMSTATE_UINT32(roff, struct sbuf_tmp), - VMSTATE_END_OF_LIST() } -}; - -static const VMStateDescription vmstate_slirp_sbuf = { - .name = "slirp-sbuf", - .version_id = 0, - .fields = (VMStateField[]){ VMSTATE_UINT32(sb_cc, struct sbuf), - VMSTATE_UINT32(sb_datalen, struct sbuf), - VMSTATE_WITH_TMP(struct sbuf, struct sbuf_tmp, - vmstate_slirp_sbuf_tmp), - VMSTATE_VBUFFER_UINT32(sb_data, struct sbuf, 0, - NULL, sb_datalen), - VMSTATE_END_OF_LIST() } -}; - -static bool slirp_older_than_v4(void *opaque, int version_id) -{ - return version_id < 4; -} - -static bool slirp_family_inet(void *opaque, int version_id) -{ - union slirp_sockaddr *ssa = (union slirp_sockaddr *)opaque; - return ssa->ss.ss_family == AF_INET; -} - -static int slirp_socket_pre_load(void *opaque) -{ - struct socket *so = opaque; - - tcp_attach(so); - /* Older versions don't load these fields */ - so->so_ffamily = AF_INET; - so->so_lfamily = AF_INET; - return 0; -} - -#ifndef _WIN32 -#define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_UINT32_TEST(f, s, t) -#else -/* Win uses u_long rather than uint32_t - but it's still 32bits long */ -#define VMSTATE_SIN4_ADDR(f, s, t) \ - VMSTATE_SINGLE_TEST(f, s, t, 0, slirp_vmstate_info_uint32, u_long) -#endif - -/* The OS provided ss_family field isn't that portable; it's size - * and type varies (16/8 bit, signed, unsigned) - * and the values it contains aren't fully portable. - */ -typedef struct SS_FamilyTmpStruct { - union slirp_sockaddr *parent; - uint16_t portable_family; -} SS_FamilyTmpStruct; - -#define SS_FAMILY_MIG_IPV4 2 /* Linux, BSD, Win... */ -#define SS_FAMILY_MIG_IPV6 10 /* Linux */ -#define SS_FAMILY_MIG_OTHER 0xffff - -static int ss_family_pre_save(void *opaque) -{ - SS_FamilyTmpStruct *tss = opaque; - - tss->portable_family = SS_FAMILY_MIG_OTHER; - - if (tss->parent->ss.ss_family == AF_INET) { - tss->portable_family = SS_FAMILY_MIG_IPV4; - } else if (tss->parent->ss.ss_family == AF_INET6) { - tss->portable_family = SS_FAMILY_MIG_IPV6; - } - - return 0; -} - -static int ss_family_post_load(void *opaque, int version_id) -{ - SS_FamilyTmpStruct *tss = opaque; - - switch (tss->portable_family) { - case SS_FAMILY_MIG_IPV4: - tss->parent->ss.ss_family = AF_INET; - break; - case SS_FAMILY_MIG_IPV6: - case 23: /* compatibility: AF_INET6 from mingw */ - case 28: /* compatibility: AF_INET6 from FreeBSD sys/socket.h */ - tss->parent->ss.ss_family = AF_INET6; - break; - default: - g_critical("invalid ss_family type %x", tss->portable_family); - return -EINVAL; - } - - return 0; -} - -static const VMStateDescription vmstate_slirp_ss_family = { - .name = "slirp-socket-addr/ss_family", - .pre_save = ss_family_pre_save, - .post_load = ss_family_post_load, - .fields = - (VMStateField[]){ VMSTATE_UINT16(portable_family, SS_FamilyTmpStruct), - VMSTATE_END_OF_LIST() } -}; - -static const VMStateDescription vmstate_slirp_socket_addr = { - .name = "slirp-socket-addr", - .version_id = 4, - .fields = - (VMStateField[]){ - VMSTATE_WITH_TMP(union slirp_sockaddr, SS_FamilyTmpStruct, - vmstate_slirp_ss_family), - VMSTATE_SIN4_ADDR(sin.sin_addr.s_addr, union slirp_sockaddr, - slirp_family_inet), - VMSTATE_UINT16_TEST(sin.sin_port, union slirp_sockaddr, - slirp_family_inet), - -#if 0 - /* Untested: Needs checking by someone with IPv6 test */ - VMSTATE_BUFFER_TEST(sin6.sin6_addr, union slirp_sockaddr, - slirp_family_inet6), - VMSTATE_UINT16_TEST(sin6.sin6_port, union slirp_sockaddr, - slirp_family_inet6), - VMSTATE_UINT32_TEST(sin6.sin6_flowinfo, union slirp_sockaddr, - slirp_family_inet6), - VMSTATE_UINT32_TEST(sin6.sin6_scope_id, union slirp_sockaddr, - slirp_family_inet6), -#endif - - VMSTATE_END_OF_LIST() } -}; - -static const VMStateDescription vmstate_slirp_socket = { - .name = "slirp-socket", - .version_id = 4, - .pre_load = slirp_socket_pre_load, - .fields = - (VMStateField[]){ - VMSTATE_UINT32(so_urgc, struct socket), - /* Pre-v4 versions */ - VMSTATE_SIN4_ADDR(so_faddr.s_addr, struct socket, - slirp_older_than_v4), - VMSTATE_SIN4_ADDR(so_laddr.s_addr, struct socket, - slirp_older_than_v4), - VMSTATE_UINT16_TEST(so_fport, struct socket, slirp_older_than_v4), - VMSTATE_UINT16_TEST(so_lport, struct socket, slirp_older_than_v4), - /* v4 and newer */ - VMSTATE_STRUCT(fhost, struct socket, 4, vmstate_slirp_socket_addr, - union slirp_sockaddr), - VMSTATE_STRUCT(lhost, struct socket, 4, vmstate_slirp_socket_addr, - union slirp_sockaddr), - - VMSTATE_UINT8(so_iptos, struct socket), - VMSTATE_UINT8(so_emu, struct socket), - VMSTATE_UINT8(so_type, struct socket), - VMSTATE_INT32(so_state, struct socket), - VMSTATE_STRUCT(so_rcv, struct socket, 0, vmstate_slirp_sbuf, - struct sbuf), - VMSTATE_STRUCT(so_snd, struct socket, 0, vmstate_slirp_sbuf, - struct sbuf), - VMSTATE_STRUCT_POINTER(so_tcpcb, struct socket, vmstate_slirp_tcp, - struct tcpcb), - VMSTATE_END_OF_LIST() } -}; - -static const VMStateDescription vmstate_slirp_bootp_client = { - .name = "slirp_bootpclient", - .fields = (VMStateField[]){ VMSTATE_UINT16(allocated, BOOTPClient), - VMSTATE_BUFFER(macaddr, BOOTPClient), - VMSTATE_END_OF_LIST() } -}; - -static const VMStateDescription vmstate_slirp = { - .name = "slirp", - .version_id = 4, - .fields = (VMStateField[]){ VMSTATE_UINT16_V(ip_id, Slirp, 2), - VMSTATE_STRUCT_ARRAY( - bootp_clients, Slirp, NB_BOOTP_CLIENTS, 3, - vmstate_slirp_bootp_client, BOOTPClient), - VMSTATE_END_OF_LIST() } -}; - -void slirp_state_save(Slirp *slirp, SlirpWriteCb write_cb, void *opaque) -{ - struct gfwd_list *ex_ptr; - SlirpOStream f = { - .write_cb = write_cb, - .opaque = opaque, - }; - - for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) - if (ex_ptr->write_cb) { - struct socket *so; - so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr, - ntohs(ex_ptr->ex_fport)); - if (!so) { - continue; - } - - slirp_ostream_write_u8(&f, 42); - slirp_vmstate_save_state(&f, &vmstate_slirp_socket, so); - } - slirp_ostream_write_u8(&f, 0); - - slirp_vmstate_save_state(&f, &vmstate_slirp, slirp); -} - - -int slirp_state_load(Slirp *slirp, int version_id, SlirpReadCb read_cb, - void *opaque) -{ - struct gfwd_list *ex_ptr; - SlirpIStream f = { - .read_cb = read_cb, - .opaque = opaque, - }; - - while (slirp_istream_read_u8(&f)) { - int ret; - struct socket *so = socreate(slirp, -1); - - ret = - slirp_vmstate_load_state(&f, &vmstate_slirp_socket, so, version_id); - if (ret < 0) { - return ret; - } - - if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) != - slirp->vnetwork_addr.s_addr) { - return -EINVAL; - } - for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->write_cb && - so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr && - so->so_fport == ex_ptr->ex_fport) { - break; - } - } - if (!ex_ptr) { - return -EINVAL; - } - - so->guestfwd = ex_ptr; - } - - return slirp_vmstate_load_state(&f, &vmstate_slirp, slirp, version_id); -} - -int slirp_state_version(void) -{ - return 4; -} diff --git a/src/network/slirp/stream.c b/src/network/slirp/stream.c deleted file mode 100644 index 541986e6cd..0000000000 --- a/src/network/slirp/stream.c +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * libslirp io streams - * - * Copyright (c) 2018 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "stream.h" -#include - -bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size) -{ - return f->read_cb(buf, size, f->opaque) == size; -} - -bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size) -{ - return f->write_cb(buf, size, f->opaque) == size; -} - -uint8_t slirp_istream_read_u8(SlirpIStream *f) -{ - uint8_t b; - - if (slirp_istream_read(f, &b, sizeof(b))) { - return b; - } - - return 0; -} - -bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b) -{ - return slirp_ostream_write(f, &b, sizeof(b)); -} - -uint16_t slirp_istream_read_u16(SlirpIStream *f) -{ - uint16_t b; - - if (slirp_istream_read(f, &b, sizeof(b))) { - return GUINT16_FROM_BE(b); - } - - return 0; -} - -bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b) -{ - b = GUINT16_TO_BE(b); - return slirp_ostream_write(f, &b, sizeof(b)); -} - -uint32_t slirp_istream_read_u32(SlirpIStream *f) -{ - uint32_t b; - - if (slirp_istream_read(f, &b, sizeof(b))) { - return GUINT32_FROM_BE(b); - } - - return 0; -} - -bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b) -{ - b = GUINT32_TO_BE(b); - return slirp_ostream_write(f, &b, sizeof(b)); -} - -int16_t slirp_istream_read_i16(SlirpIStream *f) -{ - int16_t b; - - if (slirp_istream_read(f, &b, sizeof(b))) { - return GINT16_FROM_BE(b); - } - - return 0; -} - -bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b) -{ - b = GINT16_TO_BE(b); - return slirp_ostream_write(f, &b, sizeof(b)); -} - -int32_t slirp_istream_read_i32(SlirpIStream *f) -{ - int32_t b; - - if (slirp_istream_read(f, &b, sizeof(b))) { - return GINT32_FROM_BE(b); - } - - return 0; -} - -bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b) -{ - b = GINT32_TO_BE(b); - return slirp_ostream_write(f, &b, sizeof(b)); -} diff --git a/src/network/slirp/stream.h b/src/network/slirp/stream.h deleted file mode 100644 index 08bb5b6610..0000000000 --- a/src/network/slirp/stream.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -#ifndef STREAM_H_ -#define STREAM_H_ - -#include "libslirp.h" - -typedef struct SlirpIStream { - SlirpReadCb read_cb; - void *opaque; -} SlirpIStream; - -typedef struct SlirpOStream { - SlirpWriteCb write_cb; - void *opaque; -} SlirpOStream; - -bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size); -bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size); - -uint8_t slirp_istream_read_u8(SlirpIStream *f); -bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b); - -uint16_t slirp_istream_read_u16(SlirpIStream *f); -bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b); - -uint32_t slirp_istream_read_u32(SlirpIStream *f); -bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b); - -int16_t slirp_istream_read_i16(SlirpIStream *f); -bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b); - -int32_t slirp_istream_read_i32(SlirpIStream *f); -bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b); - -#endif /* STREAM_H_ */ diff --git a/src/network/slirp/tcp.h b/src/network/slirp/tcp.h deleted file mode 100644 index 211dfec39c..0000000000 --- a/src/network/slirp/tcp.h +++ /dev/null @@ -1,169 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp.h 8.1 (Berkeley) 6/10/93 - * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp - */ - -#ifndef TCP_H -#define TCP_H - -#include - -typedef uint32_t tcp_seq; - -#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ -#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ - -#define TCP_SNDSPACE 1024 * 128 -#define TCP_RCVSPACE 1024 * 128 -#define TCP_MAXSEG_MAX 32768 - -/* - * TCP header. - * Per RFC 793, September, 1981. - */ -#define tcphdr slirp_tcphdr -struct tcphdr { - uint16_t th_sport; /* source port */ - uint16_t th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ -#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER) - uint8_t th_off : 4, /* data offset */ - th_x2 : 4; /* (unused) */ -#else - uint8_t th_x2 : 4, /* (unused) */ - th_off : 4; /* data offset */ -#endif - uint8_t th_flags; - uint16_t th_win; /* window */ - uint16_t th_sum; /* checksum */ - uint16_t th_urp; /* urgent pointer */ -}; - -#include "tcp_var.h" - -#ifndef TH_FIN -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 -#endif - -#ifndef TCPOPT_EOL -#define TCPOPT_EOL 0 -#define TCPOPT_NOP 1 -#define TCPOPT_MAXSEG 2 -#define TCPOPT_WINDOW 3 -#define TCPOPT_SACK_PERMITTED 4 /* Experimental */ -#define TCPOPT_SACK 5 /* Experimental */ -#define TCPOPT_TIMESTAMP 8 - -#define TCPOPT_TSTAMP_HDR \ - (TCPOPT_NOP << 24 | TCPOPT_NOP << 16 | TCPOPT_TIMESTAMP << 8 | \ - TCPOLEN_TIMESTAMP) -#endif - -#ifndef TCPOLEN_MAXSEG -#define TCPOLEN_MAXSEG 4 -#define TCPOLEN_WINDOW 3 -#define TCPOLEN_SACK_PERMITTED 2 -#define TCPOLEN_TIMESTAMP 10 -#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP + 2) /* appendix A */ -#endif - -#undef TCP_MAXWIN -#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ - -#undef TCP_MAX_WINSHIFT -#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ - -/* - * User-settable options (used with setsockopt). - * - * We don't use the system headers on unix because we have conflicting - * local structures. We can't avoid the system definitions on Windows, - * so we undefine them. - */ -#undef TCP_NODELAY -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#undef TCP_MAXSEG - -/* - * TCP FSM state definitions. - * Per RFC793, September, 1981. - */ - -#define TCP_NSTATES 11 - -#define TCPS_CLOSED 0 /* closed */ -#define TCPS_LISTEN 1 /* listening for connection */ -#define TCPS_SYN_SENT 2 /* active, have sent syn */ -#define TCPS_SYN_RECEIVED 3 /* have send and received syn */ -/* states < TCPS_ESTABLISHED are those where connections not established */ -#define TCPS_ESTABLISHED 4 /* established */ -#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ -/* states > TCPS_CLOSE_WAIT are those where user has closed */ -#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ -#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ -#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ -/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ -#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ -#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ - -#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) -#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) -#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) - -/* - * TCP sequence numbers are 32 bit integers operated - * on with modular arithmetic. These macros can be - * used to compare such integers. - */ -#define SEQ_LT(a, b) ((int)((a) - (b)) < 0) -#define SEQ_LEQ(a, b) ((int)((a) - (b)) <= 0) -#define SEQ_GT(a, b) ((int)((a) - (b)) > 0) -#define SEQ_GEQ(a, b) ((int)((a) - (b)) >= 0) - -/* - * Macros to initialize tcp sequence numbers for - * send and receive from initial send and receive - * sequence numbers. - */ -#define tcp_rcvseqinit(tp) (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1 - -#define tcp_sendseqinit(tp) \ - (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss - -#define TCP_ISSINCR (125 * 1024) /* increment for tcp_iss each second */ - -#endif diff --git a/src/network/slirp/tcp_input.c b/src/network/slirp/tcp_input.c deleted file mode 100644 index ecca972ee6..0000000000 --- a/src/network/slirp/tcp_input.c +++ /dev/null @@ -1,1552 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 - * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" -#include "ip_icmp.h" - -#define TCPREXMTTHRESH 3 - -#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) - -/* for modulo comparisons of timestamps */ -#define TSTMP_LT(a, b) ((int)((a) - (b)) < 0) -#define TSTMP_GEQ(a, b) ((int)((a) - (b)) >= 0) - -/* - * Insert segment ti into reassembly queue of tcp with - * control block tp. Return TH_FIN if reassembly now includes - * a segment with FIN. The macro form does the common case inline - * (segment is the next to be received on an established connection, - * and the queue is empty), avoiding linkage into and removal - * from the queue and repetition of various conversions. - * Set DELACK for segments received in order, but ack immediately - * when segments are out of order (so fast retransmit can work). - */ -#define TCP_REASS(tp, ti, m, so, flags) \ - { \ - if ((ti)->ti_seq == (tp)->rcv_nxt && tcpfrag_list_empty(tp) && \ - (tp)->t_state == TCPS_ESTABLISHED) { \ - tp->t_flags |= TF_DELACK; \ - (tp)->rcv_nxt += (ti)->ti_len; \ - flags = (ti)->ti_flags & TH_FIN; \ - if (so->so_emu) { \ - if (tcp_emu((so), (m))) \ - sbappend(so, (m)); \ - } else \ - sbappend((so), (m)); \ - } else { \ - (flags) = tcp_reass((tp), (ti), (m)); \ - tp->t_flags |= TF_ACKNOW; \ - } \ - } - -static void tcp_dooptions(struct tcpcb *tp, uint8_t *cp, int cnt, - struct tcpiphdr *ti); -static void tcp_xmit_timer(register struct tcpcb *tp, int rtt); - -static int tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, - struct mbuf *m) -{ - register struct tcpiphdr *q; - struct socket *so = tp->t_socket; - int flags; - - /* - * Call with ti==NULL after become established to - * force pre-ESTABLISHED data up to user socket. - */ - if (ti == NULL) - goto present; - - /* - * Find a segment which begins after this one does. - */ - for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); - q = tcpiphdr_next(q)) - if (SEQ_GT(q->ti_seq, ti->ti_seq)) - break; - - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { - register int i; - q = tcpiphdr_prev(q); - /* conversion to int (in i) handles seq wraparound */ - i = q->ti_seq + q->ti_len - ti->ti_seq; - if (i > 0) { - if (i >= ti->ti_len) { - m_free(m); - /* - * Try to present any queued data - * at the left window edge to the user. - * This is needed after the 3-WHS - * completes. - */ - goto present; /* ??? */ - } - m_adj(m, i); - ti->ti_len -= i; - ti->ti_seq += i; - } - q = tcpiphdr_next(q); - } - ti->ti_mbuf = m; - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (!tcpfrag_list_end(q, tp)) { - register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; - if (i <= 0) - break; - if (i < q->ti_len) { - q->ti_seq += i; - q->ti_len -= i; - m_adj(q->ti_mbuf, i); - break; - } - q = tcpiphdr_next(q); - m = tcpiphdr_prev(q)->ti_mbuf; - slirp_remque(tcpiphdr2qlink(tcpiphdr_prev(q))); - m_free(m); - } - - /* - * Stick new segment in its place. - */ - slirp_insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); - -present: - /* - * Present data to user, advancing rcv_nxt through - * completed sequence space. - */ - if (!TCPS_HAVEESTABLISHED(tp->t_state)) - return (0); - ti = tcpfrag_list_first(tp); - if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt) - return (0); - if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) - return (0); - do { - tp->rcv_nxt += ti->ti_len; - flags = ti->ti_flags & TH_FIN; - slirp_remque(tcpiphdr2qlink(ti)); - m = ti->ti_mbuf; - ti = tcpiphdr_next(ti); - if (so->so_state & SS_FCANTSENDMORE) - m_free(m); - else { - if (so->so_emu) { - if (tcp_emu(so, m)) - sbappend(so, m); - } else - sbappend(so, m); - } - } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); - return (flags); -} - -/* - * TCP input routine, follows pages 65-76 of the - * protocol specification dated September, 1981 very closely. - */ -void tcp_input(struct mbuf *m, int iphlen, struct socket *inso, - unsigned short af) -{ - struct ip save_ip, *ip; - struct ip6 save_ip6, *ip6; - register struct tcpiphdr *ti; - char *optp = NULL; - int optlen = 0; - int len, tlen, off; - register struct tcpcb *tp = NULL; - register int tiflags; - struct socket *so = NULL; - int todrop, acked, ourfinisacked, needoutput = 0; - int iss = 0; - uint32_t tiwin; - int ret; - struct sockaddr_storage lhost, fhost; - struct sockaddr_in *lhost4, *fhost4; - struct sockaddr_in6 *lhost6, *fhost6; - struct gfwd_list *ex_ptr; - Slirp *slirp; - - DEBUG_CALL("tcp_input"); - DEBUG_ARG("m = %p iphlen = %2d inso = %p", m, iphlen, inso); - - memset(&lhost, 0, sizeof(struct sockaddr_storage)); - memset(&fhost, 0, sizeof(struct sockaddr_storage)); - - /* - * If called with m == 0, then we're continuing the connect - */ - if (m == NULL) { - so = inso; - slirp = so->slirp; - - /* Re-set a few variables */ - tp = sototcpcb(so); - m = so->so_m; - so->so_m = NULL; - ti = so->so_ti; - tiwin = ti->ti_win; - tiflags = ti->ti_flags; - - goto cont_conn; - } - slirp = m->slirp; - switch (af) { - case AF_INET: - M_DUP_DEBUG(slirp, m, 0, - sizeof(struct tcpiphdr) - sizeof(struct ip) - sizeof(struct tcphdr)); - break; - case AF_INET6: - M_DUP_DEBUG(slirp, m, 0, - sizeof(struct tcpiphdr) - sizeof(struct ip6) - sizeof(struct tcphdr)); - break; - } - - ip = mtod(m, struct ip *); - ip6 = mtod(m, struct ip6 *); - - switch (af) { - case AF_INET: - if (iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen = sizeof(struct ip); - } - /* XXX Check if too short */ - - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip = *ip; - save_ip.ip_len += iphlen; - - /* - * Get IP and TCP header together in first mbuf. - * Note: IP leaves IP header in first mbuf. - */ - m->m_data -= - sizeof(struct tcpiphdr) - sizeof(struct ip) - sizeof(struct tcphdr); - m->m_len += - sizeof(struct tcpiphdr) - sizeof(struct ip) - sizeof(struct tcphdr); - ti = mtod(m, struct tcpiphdr *); - - /* - * Checksum extended TCP header and data. - */ - tlen = ip->ip_len; - tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL; - memset(&ti->ih_mbuf, 0, sizeof(struct mbuf_ptr)); - memset(&ti->ti, 0, sizeof(ti->ti)); - ti->ti_x0 = 0; - ti->ti_src = save_ip.ip_src; - ti->ti_dst = save_ip.ip_dst; - ti->ti_pr = save_ip.ip_p; - ti->ti_len = htons((uint16_t)tlen); - break; - - case AF_INET6: - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip6 = *ip6; - /* - * Get IP and TCP header together in first mbuf. - * Note: IP leaves IP header in first mbuf. - */ - m->m_data -= sizeof(struct tcpiphdr) - - (sizeof(struct ip6) + sizeof(struct tcphdr)); - m->m_len += sizeof(struct tcpiphdr) - - (sizeof(struct ip6) + sizeof(struct tcphdr)); - ti = mtod(m, struct tcpiphdr *); - - tlen = ip6->ip_pl; - tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL; - memset(&ti->ih_mbuf, 0, sizeof(struct mbuf_ptr)); - memset(&ti->ti, 0, sizeof(ti->ti)); - ti->ti_x0 = 0; - ti->ti_src6 = save_ip6.ip_src; - ti->ti_dst6 = save_ip6.ip_dst; - ti->ti_nh6 = save_ip6.ip_nh; - ti->ti_len = htons((uint16_t)tlen); - break; - - default: - g_assert_not_reached(); - } - - len = ((sizeof(struct tcpiphdr) - sizeof(struct tcphdr)) + tlen); - if (cksum(m, len)) { - goto drop; - } - - /* - * Check that TCP offset makes sense, - * pull out TCP options and adjust length. XXX - */ - off = ti->ti_off << 2; - if (off < sizeof(struct tcphdr) || off > tlen) { - goto drop; - } - tlen -= off; - ti->ti_len = tlen; - if (off > sizeof(struct tcphdr)) { - optlen = off - sizeof(struct tcphdr); - optp = mtod(m, char *) + sizeof(struct tcpiphdr); - } - tiflags = ti->ti_flags; - - /* - * Convert TCP protocol specific fields to host format. - */ - NTOHL(ti->ti_seq); - NTOHL(ti->ti_ack); - NTOHS(ti->ti_win); - NTOHS(ti->ti_urp); - - /* - * Drop TCP, IP headers and TCP options. - */ - m->m_data += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - - /* - * Locate pcb for segment. - */ -findso: - lhost.ss_family = af; - fhost.ss_family = af; - switch (af) { - case AF_INET: - lhost4 = (struct sockaddr_in *)&lhost; - lhost4->sin_addr = ti->ti_src; - lhost4->sin_port = ti->ti_sport; - fhost4 = (struct sockaddr_in *)&fhost; - fhost4->sin_addr = ti->ti_dst; - fhost4->sin_port = ti->ti_dport; - break; - case AF_INET6: - lhost6 = (struct sockaddr_in6 *)&lhost; - lhost6->sin6_addr = ti->ti_src6; - lhost6->sin6_port = ti->ti_sport; - fhost6 = (struct sockaddr_in6 *)&fhost; - fhost6->sin6_addr = ti->ti_dst6; - fhost6->sin6_port = ti->ti_dport; - break; - default: - g_assert_not_reached(); - } - - so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost); - - /* - * If the state is CLOSED (i.e., TCB does not exist) then - * all data in the incoming segment is discarded. - * If the TCB exists but is in CLOSED state, it is embryonic, - * but should either do a listen or a connect soon. - * - * state == CLOSED means we've done socreate() but haven't - * attached it to a protocol yet... - * - * XXX If a TCB does not exist, and the TH_SYN flag is - * the only flag set, then create a session, mark it - * as if it was LISTENING, and continue... - */ - if (so == NULL) { - /* TODO: IPv6 */ - if (slirp->restricted) { - /* Any hostfwds will have an existing socket, so we only get here - * for non-hostfwd connections. These should be dropped, unless it - * happens to be a guestfwd. - */ - for (ex_ptr = slirp->guestfwd_list; ex_ptr; - ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == ti->ti_dport && - ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) { - break; - } - } - if (!ex_ptr) { - goto dropwithreset; - } - } - - if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN) - goto dropwithreset; - - so = socreate(slirp, IPPROTO_TCP); - tcp_attach(so); - - sbreserve(&so->so_snd, TCP_SNDSPACE); - sbreserve(&so->so_rcv, TCP_RCVSPACE); - - so->lhost.ss = lhost; - so->fhost.ss = fhost; - - so->so_iptos = tcp_tos(so); - if (so->so_iptos == 0) { - switch (af) { - case AF_INET: - so->so_iptos = ((struct ip *)ti)->ip_tos; - break; - case AF_INET6: - break; - default: - g_assert_not_reached(); - } - } - - tp = sototcpcb(so); - tp->t_state = TCPS_LISTEN; - } - - /* - * If this is a still-connecting socket, this probably - * a retransmit of the SYN. Whether it's a retransmit SYN - * or something else, we nuke it. - */ - if (so->so_state & SS_ISFCONNECTING) - goto drop; - - tp = sototcpcb(so); - - /* XXX Should never fail */ - if (tp == NULL) - goto dropwithreset; - if (tp->t_state == TCPS_CLOSED) - goto drop; - - tiwin = ti->ti_win; - - /* - * Segment received on connection. - * Reset idle time and keep-alive timer. - */ - tp->t_idle = 0; - if (slirp_do_keepalive) - tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL; - else - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE; - - /* - * Process options if not in LISTEN state, - * else do it below (after getting remote address). - */ - if (optp && tp->t_state != TCPS_LISTEN) - tcp_dooptions(tp, (uint8_t *)optp, optlen, ti); - - /* - * Header prediction: check for the two common cases - * of a uni-directional data xfer. If the packet has - * no control flags, is in-sequence, the window didn't - * change and we're not retransmitting, it's a - * candidate. If the length is zero and the ack moved - * forward, we're the sender side of the xfer. Just - * free the data acked & wake any higher level process - * that was blocked waiting for space. If the length - * is non-zero and the ack didn't move, we're the - * receiver side. If we're getting packets in-order - * (the reassembly queue is empty), add the data to - * the socket buffer and note that we need a delayed ack. - * - * XXX Some of these tests are not needed - * eg: the tiwin == tp->snd_wnd prevents many more - * predictions.. with no *real* advantage.. - */ - if (tp->t_state == TCPS_ESTABLISHED && - (tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK && - ti->ti_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd && - tp->snd_nxt == tp->snd_max) { - if (ti->ti_len == 0) { - if (SEQ_GT(ti->ti_ack, tp->snd_una) && - SEQ_LEQ(ti->ti_ack, tp->snd_max) && - tp->snd_cwnd >= tp->snd_wnd) { - /* - * this is a pure ack for outstanding data. - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); - acked = ti->ti_ack - tp->snd_una; - sodrop(so, acked); - tp->snd_una = ti->ti_ack; - m_free(m); - - /* - * If all outstanding data are acked, stop - * retransmit timer, otherwise restart timer - * using current (possibly backed-off) value. - * If process is waiting for space, - * wakeup/selwakeup/signal. If data - * are ready to send, let tcp_output - * decide between more output or persist. - */ - if (tp->snd_una == tp->snd_max) - tp->t_timer[TCPT_REXMT] = 0; - else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - - /* - * This is called because sowwakeup might have - * put data into so_snd. Since we don't so sowwakeup, - * we don't need this.. XXX??? - */ - if (so->so_snd.sb_cc) - tcp_output(tp); - - return; - } - } else if (ti->ti_ack == tp->snd_una && tcpfrag_list_empty(tp) && - ti->ti_len <= sbspace(&so->so_rcv)) { - /* - * this is a pure, in-sequence data packet - * with nothing on the reassembly queue and - * we have enough buffer space to take it. - */ - tp->rcv_nxt += ti->ti_len; - /* - * Add data to socket buffer. - */ - if (so->so_emu) { - if (tcp_emu(so, m)) - sbappend(so, m); - } else - sbappend(so, m); - - /* - * If this is a short packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * It is better to not delay acks at all to maximize - * TCP throughput. See RFC 2581. - */ - tp->t_flags |= TF_ACKNOW; - tcp_output(tp); - return; - } - } /* header prediction */ - /* - * Calculate amount of space in receive window, - * and then do TCP input processing. - * Receive window is amount of space in rcv queue, - * but not less than advertised window. - */ - { - int win; - win = sbspace(&so->so_rcv); - if (win < 0) - win = 0; - tp->rcv_wnd = MAX(win, (int)(tp->rcv_adv - tp->rcv_nxt)); - } - - switch (tp->t_state) { - /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial - * tp->iss, and send a segment: - * - * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. - * Fill in remote peer address fields if not previously specified. - * Enter SYN_RECEIVED state, and process any other fields of this - * segment in this state. - */ - case TCPS_LISTEN: { - if (tiflags & TH_RST) - goto drop; - if (tiflags & TH_ACK) - goto dropwithreset; - if ((tiflags & TH_SYN) == 0) - goto drop; - - /* - * This has way too many gotos... - * But a bit of spaghetti code never hurt anybody :) - */ - - /* - * If this is destined for the control address, then flag to - * tcp_ctl once connected, otherwise connect - */ - /* TODO: IPv6 */ - if (af == AF_INET && - (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) == - slirp->vnetwork_addr.s_addr) { - if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr && - so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) { - /* May be an add exec */ - for (ex_ptr = slirp->guestfwd_list; ex_ptr; - ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) { - so->so_state |= SS_CTL; - break; - } - } - if (so->so_state & SS_CTL) { - goto cont_input; - } - } - /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ - } - - if (so->so_emu & EMU_NOCONNECT) { - so->so_emu &= ~EMU_NOCONNECT; - goto cont_input; - } - - if ((tcp_fconnect(so, so->so_ffamily) == -1) && (errno != EAGAIN) && - (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { - uint8_t code; - DEBUG_MISC(" tcp fconnect errno = %d-%s", errno, strerror(errno)); - if (errno == ECONNREFUSED) { - /* ACK the SYN, send RST to refuse the connection */ - tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq)0, - TH_RST | TH_ACK, af); - } else { - switch (af) { - case AF_INET: - code = ICMP_UNREACH_NET; - if (errno == EHOSTUNREACH) { - code = ICMP_UNREACH_HOST; - } - break; - case AF_INET6: - code = ICMP6_UNREACH_NO_ROUTE; - if (errno == EHOSTUNREACH) { - code = ICMP6_UNREACH_ADDRESS; - } - break; - default: - g_assert_not_reached(); - } - HTONL(ti->ti_seq); /* restore tcp header */ - HTONL(ti->ti_ack); - HTONS(ti->ti_win); - HTONS(ti->ti_urp); - m->m_data -= - sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len += - sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - switch (af) { - case AF_INET: - m->m_data += sizeof(struct tcpiphdr) - sizeof(struct ip) - - sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct ip) - - sizeof(struct tcphdr); - *ip = save_ip; - icmp_send_error(m, ICMP_UNREACH, code, 0, strerror(errno)); - break; - case AF_INET6: - m->m_data += sizeof(struct tcpiphdr) - - (sizeof(struct ip6) + sizeof(struct tcphdr)); - m->m_len -= sizeof(struct tcpiphdr) - - (sizeof(struct ip6) + sizeof(struct tcphdr)); - *ip6 = save_ip6; - icmp6_send_error(m, ICMP6_UNREACH, code); - break; - default: - g_assert_not_reached(); - } - } - tcp_close(tp); - m_free(m); - } else { - /* - * Haven't connected yet, save the current mbuf - * and ti, and return - * XXX Some OS's don't tell us whether the connect() - * succeeded or not. So we must time it out. - */ - so->so_m = m; - so->so_ti = ti; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->t_state = TCPS_SYN_RECEIVED; - /* - * Initialize receive sequence numbers now so that we can send a - * valid RST if the remote end rejects our connection. - */ - tp->irs = ti->ti_seq; - tcp_rcvseqinit(tp); - tcp_template(tp); - } - return; - - cont_conn: - /* m==NULL - * Check if the connect succeeded - */ - if (so->so_state & SS_NOFDREF) { - tp = tcp_close(tp); - goto dropwithreset; - } - cont_input: - tcp_template(tp); - - if (optp) - tcp_dooptions(tp, (uint8_t *)optp, optlen, ti); - - if (iss) - tp->iss = iss; - else - tp->iss = slirp->tcp_iss; - slirp->tcp_iss += TCP_ISSINCR / 2; - tp->irs = ti->ti_seq; - tcp_sendseqinit(tp); - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - goto trimthenstep6; - } /* case TCPS_LISTEN */ - - /* - * If the state is SYN_SENT: - * if seg contains an ACK, but not for our SYN, drop the input. - * if seg contains a RST, then drop the connection. - * if seg does not contain SYN, then drop it. - * Otherwise this is an acceptable SYN segment - * initialize tp->rcv_nxt and tp->irs - * if seg contains ack then advance tp->snd_una - * if SYN has been acked change to ESTABLISHED else SYN_RCVD state - * arrange for segment to be acked (eventually) - * continue processing rest of data/controls, beginning with URG - */ - case TCPS_SYN_SENT: - if ((tiflags & TH_ACK) && - (SEQ_LEQ(ti->ti_ack, tp->iss) || SEQ_GT(ti->ti_ack, tp->snd_max))) - goto dropwithreset; - - if (tiflags & TH_RST) { - if (tiflags & TH_ACK) { - tcp_drop(tp, 0); /* XXX Check t_softerror! */ - } - goto drop; - } - - if ((tiflags & TH_SYN) == 0) - goto drop; - if (tiflags & TH_ACK) { - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - } - - tp->t_timer[TCPT_REXMT] = 0; - tp->irs = ti->ti_seq; - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { - soisfconnected(so); - tp->t_state = TCPS_ESTABLISHED; - - tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); - /* - * if we didn't have to retransmit the SYN, - * use its rtt as our initial srtt & rtt var. - */ - if (tp->t_rtt) - tcp_xmit_timer(tp, tp->t_rtt); - } else - tp->t_state = TCPS_SYN_RECEIVED; - - trimthenstep6: - /* - * Advance ti->ti_seq to correspond to first data byte. - * If data, trim to stay within window, - * dropping FIN if necessary. - */ - ti->ti_seq++; - if (ti->ti_len > tp->rcv_wnd) { - todrop = ti->ti_len - tp->rcv_wnd; - m_adj(m, -todrop); - ti->ti_len = tp->rcv_wnd; - tiflags &= ~TH_FIN; - } - tp->snd_wl1 = ti->ti_seq - 1; - tp->rcv_up = ti->ti_seq; - goto step6; - } /* switch tp->t_state */ - /* - * States other than LISTEN or SYN_SENT. - * Check that at least some bytes of segment are within - * receive window. If segment begins before rcv_nxt, - * drop leading data (and SYN); if nothing left, just ack. - */ - todrop = tp->rcv_nxt - ti->ti_seq; - if (todrop > 0) { - if (tiflags & TH_SYN) { - tiflags &= ~TH_SYN; - ti->ti_seq++; - if (ti->ti_urp > 1) - ti->ti_urp--; - else - tiflags &= ~TH_URG; - todrop--; - } - /* - * Following if statement from Stevens, vol. 2, p. 960. - */ - if (todrop > ti->ti_len || - (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { - /* - * Any valid FIN must be to the left of the window. - * At this point the FIN must be a duplicate or out - * of sequence; drop it. - */ - tiflags &= ~TH_FIN; - - /* - * Send an ACK to resynchronize and drop any data. - * But keep on processing for RST or ACK. - */ - tp->t_flags |= TF_ACKNOW; - todrop = ti->ti_len; - } - m_adj(m, todrop); - ti->ti_seq += todrop; - ti->ti_len -= todrop; - if (ti->ti_urp > todrop) - ti->ti_urp -= todrop; - else { - tiflags &= ~TH_URG; - ti->ti_urp = 0; - } - } - /* - * If new data are received on a connection after the - * user processes are gone, then RST the other end. - */ - if ((so->so_state & SS_NOFDREF) && tp->t_state > TCPS_CLOSE_WAIT && - ti->ti_len) { - tp = tcp_close(tp); - goto dropwithreset; - } - - /* - * If segment ends after window, drop trailing data - * (and PUSH and FIN); if nothing left, just ACK. - */ - todrop = (ti->ti_seq + ti->ti_len) - (tp->rcv_nxt + tp->rcv_wnd); - if (todrop > 0) { - if (todrop >= ti->ti_len) { - /* - * If a new connection request is received - * while in TIME_WAIT, drop the old connection - * and start over if the sequence numbers - * are above the previous ones. - */ - if (tiflags & TH_SYN && tp->t_state == TCPS_TIME_WAIT && - SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { - iss = tp->rcv_nxt + TCP_ISSINCR; - tp = tcp_close(tp); - goto findso; - } - /* - * If window is closed can only take segments at - * window edge, and have to drop data and PUSH from - * incoming segments. Continue processing, but - * remember to ack. Otherwise, drop segment - * and ack. - */ - if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { - tp->t_flags |= TF_ACKNOW; - } else { - goto dropafterack; - } - } - m_adj(m, -todrop); - ti->ti_len -= todrop; - tiflags &= ~(TH_PUSH | TH_FIN); - } - - /* - * If the RST bit is set examine the state: - * SYN_RECEIVED STATE: - * If passive open, return to LISTEN state. - * If active open, inform user that connection was refused. - * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: - * Inform user that connection was reset, and close tcb. - * CLOSING, LAST_ACK, TIME_WAIT STATES - * Close the tcb. - */ - if (tiflags & TH_RST) - switch (tp->t_state) { - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: - tp->t_state = TCPS_CLOSED; - tcp_close(tp); - goto drop; - - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - tcp_close(tp); - goto drop; - } - - /* - * If a SYN is in the window, then this is an - * error and we send an RST and drop the connection. - */ - if (tiflags & TH_SYN) { - tp = tcp_drop(tp, 0); - goto dropwithreset; - } - - /* - * If the ACK bit is off we drop the segment and return. - */ - if ((tiflags & TH_ACK) == 0) - goto drop; - - /* - * Ack processing. - */ - switch (tp->t_state) { - /* - * In SYN_RECEIVED state if the ack ACKs our SYN then enter - * ESTABLISHED state and continue processing, otherwise - * send an RST. una<=ack<=max - */ - case TCPS_SYN_RECEIVED: - - if (SEQ_GT(tp->snd_una, ti->ti_ack) || SEQ_GT(ti->ti_ack, tp->snd_max)) - goto dropwithreset; - tp->t_state = TCPS_ESTABLISHED; - /* - * The sent SYN is ack'ed with our sequence number +1 - * The first data byte already in the buffer will get - * lost if no correction is made. This is only needed for - * SS_CTL since the buffer is empty otherwise. - * tp->snd_una++; or: - */ - tp->snd_una = ti->ti_ack; - if (so->so_state & SS_CTL) { - /* So tcp_ctl reports the right state */ - ret = tcp_ctl(so); - if (ret == 1) { - soisfconnected(so); - so->so_state &= ~SS_CTL; /* success XXX */ - } else if (ret == 2) { - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_NOFDREF; /* CTL_CMD */ - } else { - needoutput = 1; - tp->t_state = TCPS_FIN_WAIT_1; - } - } else { - soisfconnected(so); - } - - tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); - tp->snd_wl1 = ti->ti_seq - 1; - /* Avoid ack processing; snd_una==ti_ack => dup ack */ - goto synrx_to_est; - /* fall into ... */ - - /* - * In ESTABLISHED state: drop duplicate ACKs; ACK out of range - * ACKs. If the ack is in the range - * tp->snd_una < ti->ti_ack <= tp->snd_max - * then advance tp->snd_una to ti->ti_ack and drop - * data from the retransmission queue. If this ACK reflects - * more up to date window information we update our window information. - */ - case TCPS_ESTABLISHED: - case TCPS_FIN_WAIT_1: - case TCPS_FIN_WAIT_2: - case TCPS_CLOSE_WAIT: - case TCPS_CLOSING: - case TCPS_LAST_ACK: - case TCPS_TIME_WAIT: - - if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { - if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - DEBUG_MISC(" dup ack m = %p so = %p", m, so); - /* - * If we have outstanding data (other than - * a window probe), this is a completely - * duplicate ack (ie, window info didn't - * change), the ack is the biggest we've - * seen and we've seen exactly our rexmt - * threshold of them, assume a packet - * has been dropped and retransmit it. - * Kludge snd_nxt & the congestion - * window so we send only this one - * packet. - * - * We know we're losing at the current - * window size so do congestion avoidance - * (set ssthresh to half the current window - * and pull our congestion window back to - * the new ssthresh). - * - * Dup acks mean that packets have left the - * network (they're now cached at the receiver) - * so bump cwnd by the amount in the receiver - * to keep a constant cwnd packets in the - * network. - */ - if (tp->t_timer[TCPT_REXMT] == 0 || ti->ti_ack != tp->snd_una) - tp->t_dupacks = 0; - else if (++tp->t_dupacks == TCPREXMTTHRESH) { - tcp_seq onxt = tp->snd_nxt; - unsigned win = - MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; - - if (win < 2) - win = 2; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_timer[TCPT_REXMT] = 0; - tp->t_rtt = 0; - tp->snd_nxt = ti->ti_ack; - tp->snd_cwnd = tp->t_maxseg; - tcp_output(tp); - tp->snd_cwnd = - tp->snd_ssthresh + tp->t_maxseg * tp->t_dupacks; - if (SEQ_GT(onxt, tp->snd_nxt)) - tp->snd_nxt = onxt; - goto drop; - } else if (tp->t_dupacks > TCPREXMTTHRESH) { - tp->snd_cwnd += tp->t_maxseg; - tcp_output(tp); - goto drop; - } - } else - tp->t_dupacks = 0; - break; - } - synrx_to_est: - /* - * If the congestion window was inflated to account - * for the other side's cached packets, retract it. - */ - if (tp->t_dupacks > TCPREXMTTHRESH && tp->snd_cwnd > tp->snd_ssthresh) - tp->snd_cwnd = tp->snd_ssthresh; - tp->t_dupacks = 0; - if (SEQ_GT(ti->ti_ack, tp->snd_max)) { - goto dropafterack; - } - acked = ti->ti_ack - tp->snd_una; - - /* - * If transmit timer is running and timed sequence - * number was acked, update smoothed round trip time. - * Since we now have an rtt measurement, cancel the - * timer backoff (cf., Phil Karn's retransmit alg.). - * Recompute the initial retransmit timer. - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); - - /* - * If all outstanding data is acked, stop retransmit - * timer and remember to restart (more output or persist). - * If there is more data to be acked, restart retransmit - * timer, using current (possibly backed-off) value. - */ - if (ti->ti_ack == tp->snd_max) { - tp->t_timer[TCPT_REXMT] = 0; - needoutput = 1; - } else if (tp->t_timer[TCPT_PERSIST] == 0) - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * When new data is acked, open the congestion window. - * If the window gives us less than ssthresh packets - * in flight, open exponentially (maxseg per packet). - * Otherwise open linearly: maxseg per window - * (maxseg^2 / cwnd per packet). - */ - { - register unsigned cw = tp->snd_cwnd; - register unsigned incr = tp->t_maxseg; - - if (cw > tp->snd_ssthresh) - incr = incr * incr / cw; - tp->snd_cwnd = MIN(cw + incr, TCP_MAXWIN << tp->snd_scale); - } - if (acked > so->so_snd.sb_cc) { - tp->snd_wnd -= so->so_snd.sb_cc; - sodrop(so, (int)so->so_snd.sb_cc); - ourfinisacked = 1; - } else { - sodrop(so, acked); - tp->snd_wnd -= acked; - ourfinisacked = 0; - } - tp->snd_una = ti->ti_ack; - if (SEQ_LT(tp->snd_nxt, tp->snd_una)) - tp->snd_nxt = tp->snd_una; - - switch (tp->t_state) { - /* - * In FIN_WAIT_1 STATE in addition to the processing - * for the ESTABLISHED state if our FIN is now acknowledged - * then enter FIN_WAIT_2. - */ - case TCPS_FIN_WAIT_1: - if (ourfinisacked) { - /* - * If we can't receive any more - * data, then closing user can proceed. - * Starting the timer is contrary to the - * specification, but if we don't get a FIN - * we'll hang forever. - */ - if (so->so_state & SS_FCANTRCVMORE) { - tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE; - } - tp->t_state = TCPS_FIN_WAIT_2; - } - break; - - /* - * In CLOSING STATE in addition to the processing for - * the ESTABLISHED state if the ACK acknowledges our FIN - * then enter the TIME-WAIT state, otherwise ignore - * the segment. - */ - case TCPS_CLOSING: - if (ourfinisacked) { - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - } - break; - - /* - * In LAST_ACK, we may still be waiting for data to drain - * and/or to be acked, as well as for the ack of our FIN. - * If our FIN is now acknowledged, delete the TCB, - * enter the closed state and return. - */ - case TCPS_LAST_ACK: - if (ourfinisacked) { - tcp_close(tp); - goto drop; - } - break; - - /* - * In TIME_WAIT state the only thing that should arrive - * is a retransmission of the remote FIN. Acknowledge - * it and restart the finack timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - goto dropafterack; - } - } /* switch(tp->t_state) */ - -step6: - /* - * Update window information. - * Don't look at window if no ACK: TAC's send garbage on first SYN. - */ - if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || - (tp->snd_wl1 == ti->ti_seq && - (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { - tp->snd_wnd = tiwin; - tp->snd_wl1 = ti->ti_seq; - tp->snd_wl2 = ti->ti_ack; - if (tp->snd_wnd > tp->max_sndwnd) - tp->max_sndwnd = tp->snd_wnd; - needoutput = 1; - } - - /* - * Process segments with URG. - */ - if ((tiflags & TH_URG) && ti->ti_urp && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * This is a kludge, but if we receive and accept - * random urgent pointers, we'll crash in - * soreceive. It's hard to imagine someone - * actually wanting to send this much urgent data. - */ - if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) { - ti->ti_urp = 0; - tiflags &= ~TH_URG; - goto dodata; - } - /* - * If this segment advances the known urgent pointer, - * then mark the data stream. This should not happen - * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since - * a FIN has been received from the remote side. - * In these states we ignore the URG. - * - * According to RFC961 (Assigned Protocols), - * the urgent pointer points to the last octet - * of urgent data. We continue, however, - * to consider it to indicate the first octet - * of data past the urgent section as the original - * spec states (in one of two places). - */ - if (SEQ_GT(ti->ti_seq + ti->ti_urp, tp->rcv_up)) { - tp->rcv_up = ti->ti_seq + ti->ti_urp; - so->so_urgc = - so->so_rcv.sb_cc + (tp->rcv_up - tp->rcv_nxt); /* -1; */ - tp->rcv_up = ti->ti_seq + ti->ti_urp; - } - } else - /* - * If no out of band data is expected, - * pull receive urgent pointer along - * with the receive window. - */ - if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) - tp->rcv_up = tp->rcv_nxt; -dodata: - - /* - * If this is a small packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - */ - if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { - tp->t_flags |= TF_ACKNOW; - } - - /* - * Process the segment text, merging it into the TCP sequencing queue, - * and arranging for acknowledgment of receipt if necessary. - * This process logically involves adjusting tp->rcv_wnd as data - * is presented to the user (this happens in tcp_usrreq.c, - * case PRU_RCVD). If a FIN has already been received on this - * connection then we just ignore the text. - */ - if ((ti->ti_len || (tiflags & TH_FIN)) && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { - TCP_REASS(tp, ti, m, so, tiflags); - } else { - m_free(m); - tiflags &= ~TH_FIN; - } - - /* - * If FIN is received ACK the FIN and let the user know - * that the connection is closing. - */ - if (tiflags & TH_FIN) { - if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { - /* - * If we receive a FIN we can't send more data, - * set it SS_FDRAIN - * Shutdown the socket if there is no rx data in the - * buffer. - * soread() is called on completion of shutdown() and - * will got to TCPS_LAST_ACK, and use tcp_output() - * to send the FIN. - */ - sofwdrain(so); - - tp->t_flags |= TF_ACKNOW; - tp->rcv_nxt++; - } - switch (tp->t_state) { - /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. - */ - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - if (so->so_emu == EMU_CTL) /* no shutdown on socket */ - tp->t_state = TCPS_LAST_ACK; - else - tp->t_state = TCPS_CLOSE_WAIT; - break; - - /* - * If still in FIN_WAIT_1 STATE FIN has not been acked so - * enter the CLOSING state. - */ - case TCPS_FIN_WAIT_1: - tp->t_state = TCPS_CLOSING; - break; - - /* - * In FIN_WAIT_2 state enter the TIME_WAIT state, - * starting the time-wait timer, turning off the other - * standard timers. - */ - case TCPS_FIN_WAIT_2: - tp->t_state = TCPS_TIME_WAIT; - tcp_canceltimers(tp); - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - break; - - /* - * In TIME_WAIT state restart the 2 MSL time_wait timer. - */ - case TCPS_TIME_WAIT: - tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; - break; - } - } - - /* - * Return any desired output. - */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) { - tcp_output(tp); - } - return; - -dropafterack: - /* - * Generate an ACK dropping incoming segment if it occupies - * sequence space, where the ACK reflects our state. - */ - if (tiflags & TH_RST) - goto drop; - m_free(m); - tp->t_flags |= TF_ACKNOW; - tcp_output(tp); - return; - -dropwithreset: - /* reuses m if m!=NULL, m_free() unnecessary */ - if (tiflags & TH_ACK) - tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST, af); - else { - if (tiflags & TH_SYN) - ti->ti_len++; - tcp_respond(tp, ti, m, ti->ti_seq + ti->ti_len, (tcp_seq)0, - TH_RST | TH_ACK, af); - } - - return; - -drop: - /* - * Drop space held by incoming segment and return. - */ - m_free(m); -} - -static void tcp_dooptions(struct tcpcb *tp, uint8_t *cp, int cnt, - struct tcpiphdr *ti) -{ - uint16_t mss; - int opt, optlen; - - DEBUG_CALL("tcp_dooptions"); - DEBUG_ARG("tp = %p cnt=%i", tp, cnt); - - for (; cnt > 0; cnt -= optlen, cp += optlen) { - opt = cp[0]; - if (opt == TCPOPT_EOL) - break; - if (opt == TCPOPT_NOP) - optlen = 1; - else { - optlen = cp[1]; - if (optlen <= 0) - break; - } - switch (opt) { - default: - continue; - - case TCPOPT_MAXSEG: - if (optlen != TCPOLEN_MAXSEG) - continue; - if (!(ti->ti_flags & TH_SYN)) - continue; - memcpy((char *)&mss, (char *)cp + 2, sizeof(mss)); - NTOHS(mss); - tcp_mss(tp, mss); /* sets t_maxseg */ - break; - } - } -} - -/* - * Collect new round-trip time estimate - * and update averages and current timeout. - */ - -static void tcp_xmit_timer(register struct tcpcb *tp, int rtt) -{ - register short delta; - - DEBUG_CALL("tcp_xmit_timer"); - DEBUG_ARG("tp = %p", tp); - DEBUG_ARG("rtt = %d", rtt); - - if (tp->t_srtt != 0) { - /* - * srtt is stored as fixed point with 3 bits after the - * binary point (i.e., scaled by 8). The following magic - * is equivalent to the smoothing algorithm in rfc793 with - * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed - * point). Adjust rtt to origin 0. - */ - delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); - if ((tp->t_srtt += delta) <= 0) - tp->t_srtt = 1; - /* - * We accumulate a smoothed rtt variance (actually, a - * smoothed mean difference), then set the retransmit - * timer to smoothed rtt + 4 times the smoothed variance. - * rttvar is stored as fixed point with 2 bits after the - * binary point (scaled by 4). The following is - * equivalent to rfc793 smoothing with an alpha of .75 - * (rttvar = rttvar*3/4 + |delta| / 4). This replaces - * rfc793's wired-in beta. - */ - if (delta < 0) - delta = -delta; - delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); - if ((tp->t_rttvar += delta) <= 0) - tp->t_rttvar = 1; - } else { - /* - * No rtt measurement yet - use the unsmoothed rtt. - * Set the variance to half the rtt (so our first - * retransmit happens at 3*rtt). - */ - tp->t_srtt = rtt << TCP_RTT_SHIFT; - tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); - } - tp->t_rtt = 0; - tp->t_rxtshift = 0; - - /* - * the retransmit should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - */ - TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), (short)tp->t_rttmin, - TCPTV_REXMTMAX); /* XXX */ - - /* - * We received an ack for a packet that wasn't retransmitted; - * it is probably safe to discard any error indications we've - * received recently. This isn't quite right, but close enough - * for now (a route might have failed after we sent a segment, - * and the return path might not be symmetrical). - */ - tp->t_softerror = 0; -} - -/* - * Determine a reasonable value for maxseg size. - * If the route is known, check route for mtu. - * If none, use an mss that can be handled on the outgoing - * interface without forcing IP to fragment; if bigger than - * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES - * to utilize large mbufs. If no route is found, route has no mtu, - * or the destination isn't local, use a default, hopefully conservative - * size (usually 512 or the default IP max size, but no more than the mtu - * of the interface), as we can't discover anything about intervening - * gateways or networks. We also initialize the congestion/slow start - * window to be a single segment if the destination isn't local. - * While looking at the routing entry, we also initialize other path-dependent - * parameters from pre-set or cached values in the routing entry. - */ - -int tcp_mss(struct tcpcb *tp, unsigned offer) -{ - struct socket *so = tp->t_socket; - int mss; - - DEBUG_CALL("tcp_mss"); - DEBUG_ARG("tp = %p", tp); - DEBUG_ARG("offer = %d", offer); - - switch (so->so_ffamily) { - case AF_INET: - mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) - - sizeof(struct tcphdr) - sizeof(struct ip); - break; - case AF_INET6: - mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) - - sizeof(struct tcphdr) - sizeof(struct ip6); - break; - default: - g_assert_not_reached(); - } - - if (offer) - mss = MIN(mss, offer); - mss = MAX(mss, 32); - if (mss < tp->t_maxseg || offer != 0) - tp->t_maxseg = MIN(mss, TCP_MAXSEG_MAX); - - tp->snd_cwnd = mss; - - sbreserve(&so->so_snd, - TCP_SNDSPACE + - ((TCP_SNDSPACE % mss) ? (mss - (TCP_SNDSPACE % mss)) : 0)); - sbreserve(&so->so_rcv, - TCP_RCVSPACE + - ((TCP_RCVSPACE % mss) ? (mss - (TCP_RCVSPACE % mss)) : 0)); - - DEBUG_MISC(" returning mss = %d", mss); - - return mss; -} diff --git a/src/network/slirp/tcp_output.c b/src/network/slirp/tcp_output.c deleted file mode 100644 index 383fe31dcf..0000000000 --- a/src/network/slirp/tcp_output.c +++ /dev/null @@ -1,516 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93 - * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" - -static const uint8_t tcp_outflags[TCP_NSTATES] = { - TH_RST | TH_ACK, 0, TH_SYN, TH_SYN | TH_ACK, - TH_ACK, TH_ACK, TH_FIN | TH_ACK, TH_FIN | TH_ACK, - TH_FIN | TH_ACK, TH_ACK, TH_ACK, -}; - - -#undef MAX_TCPOPTLEN -#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */ - -/* - * Tcp output routine: figure out what should be sent and send it. - */ -int tcp_output(struct tcpcb *tp) -{ - register struct socket *so = tp->t_socket; - register long len, win; - int off, flags, error; - register struct mbuf *m; - register struct tcpiphdr *ti, tcpiph_save; - struct ip *ip; - struct ip6 *ip6; - uint8_t opt[MAX_TCPOPTLEN]; - unsigned optlen, hdrlen; - int idle, sendalot; - - DEBUG_CALL("tcp_output"); - DEBUG_ARG("tp = %p", tp); - - /* - * Determine length of data that should be transmitted, - * and flags that will be used. - * If there is some data or critical controls (SYN, RST) - * to send, then transmit; otherwise, investigate further. - */ - idle = (tp->snd_max == tp->snd_una); - if (idle && tp->t_idle >= tp->t_rxtcur) - /* - * We have been idle for "a while" and no acks are - * expected to clock out any data we send -- - * slow start to get ack "clock" running again. - */ - tp->snd_cwnd = tp->t_maxseg; -again: - sendalot = 0; - off = tp->snd_nxt - tp->snd_una; - win = MIN(tp->snd_wnd, tp->snd_cwnd); - - flags = tcp_outflags[tp->t_state]; - - DEBUG_MISC(" --- tcp_output flags = 0x%x", flags); - - /* - * If in persist timeout with window of 0, send 1 byte. - * Otherwise, if window is small but nonzero - * and timer expired, we will send what we can - * and go to transmit state. - */ - if (tp->t_force) { - if (win == 0) { - /* - * If we still have some data to send, then - * clear the FIN bit. Usually this would - * happen below when it realizes that we - * aren't sending all the data. However, - * if we have exactly 1 byte of unset data, - * then it won't clear the FIN bit below, - * and if we are in persist state, we wind - * up sending the packet without recording - * that we sent the FIN bit. - * - * We can't just blindly clear the FIN bit, - * because if we don't have any more data - * to send then the probe will be the FIN - * itself. - */ - if (off < so->so_snd.sb_cc) - flags &= ~TH_FIN; - win = 1; - } else { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - - len = MIN(so->so_snd.sb_cc, win) - off; - - if (len < 0) { - /* - * If FIN has been sent but not acked, - * but we haven't been called to retransmit, - * len will be -1. Otherwise, window shrank - * after we sent into it. If window shrank to 0, - * cancel pending retransmit and pull snd_nxt - * back to (closed) window. We will enter persist - * state below. If the window didn't close completely, - * just wait for an ACK. - */ - len = 0; - if (win == 0) { - tp->t_timer[TCPT_REXMT] = 0; - tp->snd_nxt = tp->snd_una; - } - } - - if (len > tp->t_maxseg) { - len = tp->t_maxseg; - sendalot = 1; - } - if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) - flags &= ~TH_FIN; - - win = sbspace(&so->so_rcv); - - /* - * Sender silly window avoidance. If connection is idle - * and can send all data, a maximum segment, - * at least a maximum default-size segment do it, - * or are forced, do it; otherwise don't bother. - * If peer's buffer is tiny, then send - * when window is at least half open. - * If retransmitting (possibly after persist timer forced us - * to send into a small window), then must resend. - */ - if (len) { - if (len == tp->t_maxseg) - goto send; - if ((1 || idle || tp->t_flags & TF_NODELAY) && - len + off >= so->so_snd.sb_cc) - goto send; - if (tp->t_force) - goto send; - if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) - goto send; - if (SEQ_LT(tp->snd_nxt, tp->snd_max)) - goto send; - } - - /* - * Compare available window to amount of window - * known to peer (as advertised window less - * next expected input). If the difference is at least two - * max size segments, or at least 50% of the maximum possible - * window, then want to send a window update to peer. - */ - if (win > 0) { - /* - * "adv" is the amount we can increase the window, - * taking into account that we are limited by - * TCP_MAXWIN << tp->rcv_scale. - */ - long adv = MIN(win, (long)TCP_MAXWIN << tp->rcv_scale) - - (tp->rcv_adv - tp->rcv_nxt); - - if (adv >= (long)(2 * tp->t_maxseg)) - goto send; - if (2 * adv >= (long)so->so_rcv.sb_datalen) - goto send; - } - - /* - * Send if we owe peer an ACK. - */ - if (tp->t_flags & TF_ACKNOW) - goto send; - if (flags & (TH_SYN | TH_RST)) - goto send; - if (SEQ_GT(tp->snd_up, tp->snd_una)) - goto send; - /* - * If our state indicates that FIN should be sent - * and we have not yet done so, or we're retransmitting the FIN, - * then we need to send. - */ - if (flags & TH_FIN && - ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) - goto send; - - /* - * TCP window updates are not reliable, rather a polling protocol - * using ``persist'' packets is used to insure receipt of window - * updates. The three ``states'' for the output side are: - * idle not doing retransmits or persists - * persisting to move a small or zero window - * (re)transmitting and thereby not persisting - * - * tp->t_timer[TCPT_PERSIST] - * is set when we are in persist state. - * tp->t_force - * is set when we are called to send a persist packet. - * tp->t_timer[TCPT_REXMT] - * is set when we are retransmitting - * The output side is idle when both timers are zero. - * - * If send window is too small, there is data to transmit, and no - * retransmit or persist is pending, then go to persist state. - * If nothing happens soon, send when timer expires: - * if window is nonzero, transmit what we can, - * otherwise force out a byte. - */ - if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && - tp->t_timer[TCPT_PERSIST] == 0) { - tp->t_rxtshift = 0; - tcp_setpersist(tp); - } - - /* - * No reason to send a segment, just return. - */ - return (0); - -send: - /* - * Before ESTABLISHED, force sending of initial options - * unless TCP set not to do any options. - * NOTE: we assume that the IP/TCP header plus TCP options - * always fit in a single mbuf, leaving room for a maximum - * link header, i.e. - * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN - */ - optlen = 0; - hdrlen = sizeof(struct tcpiphdr); - if (flags & TH_SYN) { - tp->snd_nxt = tp->iss; - if ((tp->t_flags & TF_NOOPT) == 0) { - uint16_t mss; - - opt[0] = TCPOPT_MAXSEG; - opt[1] = 4; - mss = htons((uint16_t)tcp_mss(tp, 0)); - memcpy((char *)(opt + 2), (char *)&mss, sizeof(mss)); - optlen = 4; - } - } - - hdrlen += optlen; - - /* - * Adjust data length if insertion of options will - * bump the packet length beyond the t_maxseg length. - */ - if (len > tp->t_maxseg - optlen) { - len = tp->t_maxseg - optlen; - sendalot = 1; - } - - /* - * Grab a header mbuf, attaching a copy of data to - * be transmitted, and initialize the header from - * the template for sends on this connection. - */ - if (len) { - m = m_get(so->slirp); - if (m == NULL) { - error = 1; - goto out; - } - m->m_data += IF_MAXLINKHDR; - m->m_len = hdrlen; - - sbcopy(&so->so_snd, off, (int)len, mtod(m, char *) + hdrlen); - m->m_len += len; - - /* - * If we're sending everything we've got, set PUSH. - * (This will keep happy those implementations which only - * give data to the user when a buffer fills or - * a PUSH comes in.) - */ - if (off + len == so->so_snd.sb_cc) - flags |= TH_PUSH; - } else { - m = m_get(so->slirp); - if (m == NULL) { - error = 1; - goto out; - } - m->m_data += IF_MAXLINKHDR; - m->m_len = hdrlen; - } - - ti = mtod(m, struct tcpiphdr *); - - memcpy((char *)ti, &tp->t_template, sizeof(struct tcpiphdr)); - - /* - * Fill in fields, remembering maximum advertised - * window for use in delaying messages about window sizes. - * If resending a FIN, be sure not to use a new sequence number. - */ - if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && - tp->snd_nxt == tp->snd_max) - tp->snd_nxt--; - /* - * If we are doing retransmissions, then snd_nxt will - * not reflect the first unsent octet. For ACK only - * packets, we do not want the sequence number of the - * retransmitted packet, we want the sequence number - * of the next unsent octet. So, if there is no data - * (and no SYN or FIN), use snd_max instead of snd_nxt - * when filling in ti_seq. But if we are in persist - * state, snd_max might reflect one byte beyond the - * right edge of the window, so use snd_nxt in that - * case, since we know we aren't doing a retransmission. - * (retransmit and persist are mutually exclusive...) - */ - if (len || (flags & (TH_SYN | TH_FIN)) || tp->t_timer[TCPT_PERSIST]) - ti->ti_seq = htonl(tp->snd_nxt); - else - ti->ti_seq = htonl(tp->snd_max); - ti->ti_ack = htonl(tp->rcv_nxt); - if (optlen) { - memcpy((char *)(ti + 1), (char *)opt, optlen); - ti->ti_off = (sizeof(struct tcphdr) + optlen) >> 2; - } - ti->ti_flags = flags; - /* - * Calculate receive window. Don't shrink window, - * but avoid silly window syndrome. - */ - if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) - win = 0; - if (win > (long)TCP_MAXWIN << tp->rcv_scale) - win = (long)TCP_MAXWIN << tp->rcv_scale; - if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) - win = (long)(tp->rcv_adv - tp->rcv_nxt); - ti->ti_win = htons((uint16_t)(win >> tp->rcv_scale)); - - if (SEQ_GT(tp->snd_up, tp->snd_una)) { - ti->ti_urp = htons((uint16_t)(tp->snd_up - ntohl(ti->ti_seq))); - ti->ti_flags |= TH_URG; - } else - /* - * If no urgent pointer to send, then we pull - * the urgent pointer to the left edge of the send window - * so that it doesn't drift into the send window on sequence - * number wraparound. - */ - tp->snd_up = tp->snd_una; /* drag it along */ - - /* - * Put TCP length in extended header, and then - * checksum extended header and data. - */ - if (len + optlen) - ti->ti_len = htons((uint16_t)(sizeof(struct tcphdr) + optlen + len)); - ti->ti_sum = cksum(m, (int)(hdrlen + len)); - - /* - * In transmit state, time the transmission and arrange for - * the retransmit. In persist state, just set snd_max. - */ - if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { - tcp_seq startseq = tp->snd_nxt; - - /* - * Advance snd_nxt over sequence space of this segment. - */ - if (flags & (TH_SYN | TH_FIN)) { - if (flags & TH_SYN) - tp->snd_nxt++; - if (flags & TH_FIN) { - tp->snd_nxt++; - tp->t_flags |= TF_SENTFIN; - } - } - tp->snd_nxt += len; - if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { - tp->snd_max = tp->snd_nxt; - /* - * Time this transmission if not a retransmission and - * not currently timing anything. - */ - if (tp->t_rtt == 0) { - tp->t_rtt = 1; - tp->t_rtseq = startseq; - } - } - - /* - * Set retransmit timer if not currently set, - * and not doing an ack or a keep-alive probe. - * Initial value for retransmit timer is smoothed - * round-trip time + 2 * round-trip time variance. - * Initialize shift counter which is used for backoff - * of retransmit time. - */ - if (tp->t_timer[TCPT_REXMT] == 0 && tp->snd_nxt != tp->snd_una) { - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - if (tp->t_timer[TCPT_PERSIST]) { - tp->t_timer[TCPT_PERSIST] = 0; - tp->t_rxtshift = 0; - } - } - } else if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) - tp->snd_max = tp->snd_nxt + len; - - /* - * Fill in IP length and desired time to live and - * send to IP level. There should be a better way - * to handle ttl and tos; we could keep them in - * the template, but need a way to checksum without them. - */ - m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ - tcpiph_save = *mtod(m, struct tcpiphdr *); - - switch (so->so_ffamily) { - case AF_INET: - m->m_data += - sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - sizeof(struct ip); - m->m_len -= - sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - sizeof(struct ip); - ip = mtod(m, struct ip *); - - ip->ip_len = m->m_len; - ip->ip_dst = tcpiph_save.ti_dst; - ip->ip_src = tcpiph_save.ti_src; - ip->ip_p = tcpiph_save.ti_pr; - - ip->ip_ttl = IPDEFTTL; - ip->ip_tos = so->so_iptos; - error = ip_output(so, m); - break; - - case AF_INET6: - m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - - sizeof(struct ip6); - m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - - sizeof(struct ip6); - ip6 = mtod(m, struct ip6 *); - - ip6->ip_pl = tcpiph_save.ti_len; - ip6->ip_dst = tcpiph_save.ti_dst6; - ip6->ip_src = tcpiph_save.ti_src6; - ip6->ip_nh = tcpiph_save.ti_nh6; - - error = ip6_output(so, m, 0); - break; - - default: - g_assert_not_reached(); - } - - if (error) { - out: - return (error); - } - - /* - * Data sent (as far as we can tell). - * If this advertises a larger window than any other segment, - * then remember the size of the advertised window. - * Any pending ACK has now been sent. - */ - if (win > 0 && SEQ_GT(tp->rcv_nxt + win, tp->rcv_adv)) - tp->rcv_adv = tp->rcv_nxt + win; - tp->last_ack_sent = tp->rcv_nxt; - tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); - if (sendalot) - goto again; - - return (0); -} - -void tcp_setpersist(struct tcpcb *tp) -{ - int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; - - /* - * Start/restart persistence timer. - */ - TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], t * tcp_backoff[tp->t_rxtshift], - TCPTV_PERSMIN, TCPTV_PERSMAX); - if (tp->t_rxtshift < TCP_MAXRXTSHIFT) - tp->t_rxtshift++; -} diff --git a/src/network/slirp/tcp_subr.c b/src/network/slirp/tcp_subr.c deleted file mode 100644 index 112448483e..0000000000 --- a/src/network/slirp/tcp_subr.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 - * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - */ - -#include "slirp.h" - -/* patchable/settable parameters for tcp */ -/* Don't do rfc1323 performance enhancements */ -#define TCP_DO_RFC1323 0 - -/* - * Tcp initialization - */ -void tcp_init(Slirp *slirp) -{ - slirp->tcp_iss = 1; /* wrong */ - slirp->tcb.so_next = slirp->tcb.so_prev = &slirp->tcb; - slirp->tcp_last_so = &slirp->tcb; -} - -void tcp_cleanup(Slirp *slirp) -{ - while (slirp->tcb.so_next != &slirp->tcb) { - tcp_close(sototcpcb(slirp->tcb.so_next)); - } -} - -/* - * Create template to be used to send tcp packets on a connection. - * Call after host entry created, fills - * in a skeletal tcp/ip header, minimizing the amount of work - * necessary when the connection is used. - */ -void tcp_template(struct tcpcb *tp) -{ - struct socket *so = tp->t_socket; - register struct tcpiphdr *n = &tp->t_template; - - n->ti_mbuf = NULL; - memset(&n->ti, 0, sizeof(n->ti)); - n->ti_x0 = 0; - switch (so->so_ffamily) { - case AF_INET: - n->ti_pr = IPPROTO_TCP; - n->ti_len = htons(sizeof(struct tcphdr)); - n->ti_src = so->so_faddr; - n->ti_dst = so->so_laddr; - n->ti_sport = so->so_fport; - n->ti_dport = so->so_lport; - break; - - case AF_INET6: - n->ti_nh6 = IPPROTO_TCP; - n->ti_len = htons(sizeof(struct tcphdr)); - n->ti_src6 = so->so_faddr6; - n->ti_dst6 = so->so_laddr6; - n->ti_sport = so->so_fport6; - n->ti_dport = so->so_lport6; - break; - - default: - g_assert_not_reached(); - } - - n->ti_seq = 0; - n->ti_ack = 0; - n->ti_x2 = 0; - n->ti_off = 5; - n->ti_flags = 0; - n->ti_win = 0; - n->ti_sum = 0; - n->ti_urp = 0; -} - -/* - * Send a single message to the TCP at address specified by - * the given TCP/IP header. If m == 0, then we make a copy - * of the tcpiphdr at ti and send directly to the addressed host. - * This is used to force keep alive messages out using the TCP - * template for a connection tp->t_template. If flags are given - * then we send a message back to the TCP which originated the - * segment ti, and discard the mbuf containing it and any other - * attached mbufs. - * - * In any case the ack and sequence number of the transmitted - * segment are as specified by the parameters. - */ -void tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, - tcp_seq ack, tcp_seq seq, int flags, unsigned short af) -{ - register int tlen; - int win = 0; - - DEBUG_CALL("tcp_respond"); - DEBUG_ARG("tp = %p", tp); - DEBUG_ARG("ti = %p", ti); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("ack = %u", ack); - DEBUG_ARG("seq = %u", seq); - DEBUG_ARG("flags = %x", flags); - - if (tp) - win = sbspace(&tp->t_socket->so_rcv); - if (m == NULL) { - if (!tp || (m = m_get(tp->t_socket->slirp)) == NULL) - return; - tlen = 0; - m->m_data += IF_MAXLINKHDR; - *mtod(m, struct tcpiphdr *) = *ti; - ti = mtod(m, struct tcpiphdr *); - switch (af) { - case AF_INET: - ti->ti.ti_i4.ih_x1 = 0; - break; - case AF_INET6: - ti->ti.ti_i6.ih_x1 = 0; - break; - default: - g_assert_not_reached(); - } - flags = TH_ACK; - } else { - /* - * ti points into m so the next line is just making - * the mbuf point to ti - */ - m->m_data = (char *)ti; - - m->m_len = sizeof(struct tcpiphdr); - tlen = 0; -#define xchg(a, b, type) \ - { \ - type t; \ - t = a; \ - a = b; \ - b = t; \ - } - switch (af) { - case AF_INET: - xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, uint32_t); - xchg(ti->ti_dport, ti->ti_sport, uint16_t); - break; - case AF_INET6: - xchg(ti->ti_dst6, ti->ti_src6, struct in6_addr); - xchg(ti->ti_dport, ti->ti_sport, uint16_t); - break; - default: - g_assert_not_reached(); - } -#undef xchg - } - ti->ti_len = htons((uint16_t)(sizeof(struct tcphdr) + tlen)); - tlen += sizeof(struct tcpiphdr); - m->m_len = tlen; - - ti->ti_mbuf = NULL; - ti->ti_x0 = 0; - ti->ti_seq = htonl(seq); - ti->ti_ack = htonl(ack); - ti->ti_x2 = 0; - ti->ti_off = sizeof(struct tcphdr) >> 2; - ti->ti_flags = flags; - if (tp) - ti->ti_win = htons((uint16_t)(win >> tp->rcv_scale)); - else - ti->ti_win = htons((uint16_t)win); - ti->ti_urp = 0; - ti->ti_sum = 0; - ti->ti_sum = cksum(m, tlen); - - struct tcpiphdr tcpiph_save = *(mtod(m, struct tcpiphdr *)); - struct ip *ip; - struct ip6 *ip6; - - switch (af) { - case AF_INET: - m->m_data += - sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - sizeof(struct ip); - m->m_len -= - sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - sizeof(struct ip); - ip = mtod(m, struct ip *); - ip->ip_len = m->m_len; - ip->ip_dst = tcpiph_save.ti_dst; - ip->ip_src = tcpiph_save.ti_src; - ip->ip_p = tcpiph_save.ti_pr; - - if (flags & TH_RST) { - ip->ip_ttl = MAXTTL; - } else { - ip->ip_ttl = IPDEFTTL; - } - - ip_output(NULL, m); - break; - - case AF_INET6: - m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - - sizeof(struct ip6); - m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr) - - sizeof(struct ip6); - ip6 = mtod(m, struct ip6 *); - ip6->ip_pl = tcpiph_save.ti_len; - ip6->ip_dst = tcpiph_save.ti_dst6; - ip6->ip_src = tcpiph_save.ti_src6; - ip6->ip_nh = tcpiph_save.ti_nh6; - - ip6_output(NULL, m, 0); - break; - - default: - g_assert_not_reached(); - } -} - -/* - * Create a new TCP control block, making an - * empty reassembly queue and hooking it to the argument - * protocol control block. - */ -struct tcpcb *tcp_newtcpcb(struct socket *so) -{ - register struct tcpcb *tp; - - tp = g_new0(struct tcpcb, 1); - tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; - /* - * 40: length of IPv4 header (20) + TCP header (20) - * 60: length of IPv6 header (40) + TCP header (20) - */ - tp->t_maxseg = - MIN(so->slirp->if_mtu - ((so->so_ffamily == AF_INET) ? 40 : 60), - TCP_MAXSEG_MAX); - - tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE | TF_REQ_TSTMP) : 0; - tp->t_socket = so; - - /* - * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no - * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives - * reasonable initial retransmit time. - */ - tp->t_srtt = TCPTV_SRTTBASE; - tp->t_rttvar = TCPTV_SRTTDFLT << 2; - tp->t_rttmin = TCPTV_MIN; - - TCPT_RANGESET(tp->t_rxtcur, - ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, - TCPTV_MIN, TCPTV_REXMTMAX); - - tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; - tp->t_state = TCPS_CLOSED; - - so->so_tcpcb = tp; - - return (tp); -} - -/* - * Drop a TCP connection, reporting - * the specified error. If connection is synchronized, - * then send a RST to peer. - */ -struct tcpcb *tcp_drop(struct tcpcb *tp, int err) -{ - DEBUG_CALL("tcp_drop"); - DEBUG_ARG("tp = %p", tp); - DEBUG_ARG("errno = %d", errno); - - if (TCPS_HAVERCVDSYN(tp->t_state)) { - tp->t_state = TCPS_CLOSED; - tcp_output(tp); - } - return (tcp_close(tp)); -} - -/* - * Close a TCP control block: - * discard all space held by the tcp - * discard internet protocol block - * wake up any sleepers - */ -struct tcpcb *tcp_close(struct tcpcb *tp) -{ - register struct tcpiphdr *t; - struct socket *so = tp->t_socket; - Slirp *slirp = so->slirp; - register struct mbuf *m; - - DEBUG_CALL("tcp_close"); - DEBUG_ARG("tp = %p", tp); - - /* free the reassembly queue, if any */ - t = tcpfrag_list_first(tp); - while (!tcpfrag_list_end(t, tp)) { - t = tcpiphdr_next(t); - m = tcpiphdr_prev(t)->ti_mbuf; - slirp_remque(tcpiphdr2qlink(tcpiphdr_prev(t))); - m_free(m); - } - g_free(tp); - so->so_tcpcb = NULL; - /* clobber input socket cache if we're closing the cached connection */ - if (so == slirp->tcp_last_so) - slirp->tcp_last_so = &slirp->tcb; - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - sbfree(&so->so_rcv); - sbfree(&so->so_snd); - sofree(so); - return ((struct tcpcb *)0); -} - -/* - * TCP protocol interface to socket abstraction. - */ - -/* - * User issued close, and wish to trail through shutdown states: - * if never received SYN, just forget it. If got a SYN from peer, - * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. - * If already got a FIN from peer, then almost done; go to LAST_ACK - * state. In all other cases, have already sent FIN to peer (e.g. - * after PRU_SHUTDOWN), and just have to play tedious game waiting - * for peer to send FIN or not respond to keep-alives, etc. - * We can let the user exit from the close as soon as the FIN is acked. - */ -void tcp_sockclosed(struct tcpcb *tp) -{ - DEBUG_CALL("tcp_sockclosed"); - DEBUG_ARG("tp = %p", tp); - - if (!tp) { - return; - } - - switch (tp->t_state) { - case TCPS_CLOSED: - case TCPS_LISTEN: - case TCPS_SYN_SENT: - tp->t_state = TCPS_CLOSED; - tcp_close(tp); - return; - - case TCPS_SYN_RECEIVED: - case TCPS_ESTABLISHED: - tp->t_state = TCPS_FIN_WAIT_1; - break; - - case TCPS_CLOSE_WAIT: - tp->t_state = TCPS_LAST_ACK; - break; - } - tcp_output(tp); -} - -/* - * Connect to a host on the Internet - * Called by tcp_input - * Only do a connect, the tcp fields will be set in tcp_input - * return 0 if there's a result of the connect, - * else return -1 means we're still connecting - * The return value is almost always -1 since the socket is - * nonblocking. Connect returns after the SYN is sent, and does - * not wait for ACK+SYN. - */ -int tcp_fconnect(struct socket *so, unsigned short af) -{ - int ret = 0; - - DEBUG_CALL("tcp_fconnect"); - DEBUG_ARG("so = %p", so); - - ret = so->s = slirp_socket(af, SOCK_STREAM, 0); - if (ret >= 0) { - ret = slirp_bind_outbound(so, af); - if (ret < 0) { - // bind failed - close socket - closesocket(so->s); - so->s = -1; - return (ret); - } - } - - if (ret >= 0) { - int opt, s = so->s; - struct sockaddr_storage addr; - - slirp_set_nonblock(s); - so->slirp->cb->register_poll_fd(s, so->slirp->opaque); - slirp_socket_set_fast_reuse(s); - opt = 1; - setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt)); - opt = 1; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); - - addr = so->fhost.ss; - DEBUG_CALL(" connect()ing"); - if (sotranslate_out(so, &addr) < 0) { - return -1; - } - - /* We don't care what port we get */ - ret = connect(s, (struct sockaddr *)&addr, sockaddr_size(&addr)); - - /* - * If it's not in progress, it failed, so we just return 0, - * without clearing SS_NOFDREF - */ - soisfconnecting(so); - } - - return (ret); -} - -/* - * Accept the socket and connect to the local-host - * - * We have a problem. The correct thing to do would be - * to first connect to the local-host, and only if the - * connection is accepted, then do an accept() here. - * But, a) we need to know who's trying to connect - * to the socket to be able to SYN the local-host, and - * b) we are already connected to the foreign host by - * the time it gets to accept(), so... We simply accept - * here and SYN the local-host. - */ -void tcp_connect(struct socket *inso) -{ - Slirp *slirp = inso->slirp; - struct socket *so; - struct sockaddr_storage addr; - socklen_t addrlen; - struct tcpcb *tp; - int s, opt, ret; - /* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */ - char addrstr[INET6_ADDRSTRLEN]; - char portstr[6]; - - DEBUG_CALL("tcp_connect"); - DEBUG_ARG("inso = %p", inso); - switch (inso->lhost.ss.ss_family) { - case AF_INET: - addrlen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - addrlen = sizeof(struct sockaddr_in6); - break; - default: - g_assert_not_reached(); - } - ret = getnameinfo((const struct sockaddr *) &inso->lhost.ss, addrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); - g_assert(ret == 0); - DEBUG_ARG("ip = [%s]:%s", addrstr, portstr); - DEBUG_ARG("so_state = 0x%x", inso->so_state); - - /* Perform lazy guest IP address resolution if needed. */ - if (inso->so_state & SS_HOSTFWD) { - /* - * We can only reject the connection request by accepting it and - * then immediately closing it. Note that SS_FACCEPTONCE sockets can't - * get here. - */ - if (soassign_guest_addr_if_needed(inso) < 0) { - /* - * Guest address isn't available yet. We could either try to defer - * completing this connection request until the guest address is - * available, or punt. It's easier to punt. Otherwise we need to - * complicate the mechanism by which we're called to defer calling - * us again until the guest address is available. - */ - DEBUG_MISC(" guest address not available yet"); - addrlen = sizeof(addr); - s = accept(inso->s, (struct sockaddr *)&addr, &addrlen); - if (s >= 0) { - closesocket(s); - } - return; - } - } - - /* - * If it's an SS_ACCEPTONCE socket, no need to socreate() - * another socket, just use the accept() socket. - */ - if (inso->so_state & SS_FACCEPTONCE) { - /* FACCEPTONCE already have a tcpcb */ - so = inso; - } else { - so = socreate(slirp, IPPROTO_TCP); - tcp_attach(so); - so->lhost = inso->lhost; - so->so_ffamily = inso->so_ffamily; - } - - tcp_mss(sototcpcb(so), 0); - - addrlen = sizeof(addr); - s = accept(inso->s, (struct sockaddr *)&addr, &addrlen); - if (s < 0) { - tcp_close(sototcpcb(so)); /* This will sofree() as well */ - return; - } - slirp_set_nonblock(s); - so->slirp->cb->register_poll_fd(s, so->slirp->opaque); - slirp_socket_set_fast_reuse(s); - opt = 1; - setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int)); - slirp_socket_set_nodelay(s); - - so->fhost.ss = addr; - sotranslate_accept(so); - - /* Close the accept() socket, set right state */ - if (inso->so_state & SS_FACCEPTONCE) { - /* If we only accept once, close the accept() socket */ - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - - /* Don't select it yet, even though we have an FD */ - /* if it's not FACCEPTONCE, it's already NOFDREF */ - so->so_state = SS_NOFDREF; - } - so->s = s; - so->so_state |= SS_INCOMING; - - so->so_iptos = tcp_tos(so); - tp = sototcpcb(so); - - tcp_template(tp); - - tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = slirp->tcp_iss; - slirp->tcp_iss += TCP_ISSINCR / 2; - tcp_sendseqinit(tp); - tcp_output(tp); -} - -/* - * Attach a TCPCB to a socket. - */ -void tcp_attach(struct socket *so) -{ - so->so_tcpcb = tcp_newtcpcb(so); - slirp_insque(so, &so->slirp->tcb); -} - -/* - * Set the socket's type of service field - */ -static const struct tos_t tcptos[] = { - { 0, 20, IPTOS_THROUGHPUT, 0 }, /* ftp data */ - { 21, 21, IPTOS_LOWDELAY, EMU_FTP }, /* ftp control */ - { 0, 23, IPTOS_LOWDELAY, 0 }, /* telnet */ - { 0, 80, IPTOS_THROUGHPUT, 0 }, /* WWW */ - { 0, 513, IPTOS_LOWDELAY, EMU_RLOGIN | EMU_NOCONNECT }, /* rlogin */ - { 0, 544, IPTOS_LOWDELAY, EMU_KSH }, /* kshell */ - { 0, 543, IPTOS_LOWDELAY, 0 }, /* klogin */ - { 0, 6667, IPTOS_THROUGHPUT, EMU_IRC }, /* IRC */ - { 0, 6668, IPTOS_THROUGHPUT, EMU_IRC }, /* IRC undernet */ - { 0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ - { 0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ - { 0, 0, 0, 0 } -}; - -/* - * Return TOS according to the above table - */ -uint8_t tcp_tos(struct socket *so) -{ - int i = 0; - - while (tcptos[i].tos) { - if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || - (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { - if (so->slirp->enable_emu) - so->so_emu = tcptos[i].emu; - return tcptos[i].tos; - } - i++; - } - return 0; -} - -/* - * Emulate programs that try and connect to us - * This includes ftp (the data connection is - * initiated by the server) and IRC (DCC CHAT and - * DCC SEND) for now - * - * NOTE: It's possible to crash SLiRP by sending it - * unstandard strings to emulate... if this is a problem, - * more checks are needed here - * - * XXX Assumes the whole command came in one packet - * XXX If there is more than one command in the packet, the others may - * be truncated. - * XXX If the command is too long, it may be truncated. - * - * XXX Some ftp clients will have their TOS set to - * LOWDELAY and so Nagel will kick in. Because of this, - * we'll get the first letter, followed by the rest, so - * we simply scan for ORT instead of PORT... - * DCC doesn't have this problem because there's other stuff - * in the packet before the DCC command. - * - * Return 1 if the mbuf m is still valid and should be - * sbappend()ed - * - * NOTE: if you return 0 you MUST m_free() the mbuf! - */ -int tcp_emu(struct socket *so, struct mbuf *m) -{ - Slirp *slirp = so->slirp; - unsigned n1, n2, n3, n4, n5, n6; - char buff[257]; - uint32_t laddr; - unsigned lport; - char *bptr; - - DEBUG_CALL("tcp_emu"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - - switch (so->so_emu) { - int x, i; - - /* TODO: IPv6 */ - case EMU_IDENT: - /* - * Identification protocol as per rfc-1413 - */ - - { - struct socket *tmpso; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); - char *eol = g_strstr_len(m->m_data, m->m_len, "\r\n"); - - if (!eol) { - return 1; - } - - *eol = '\0'; - if (sscanf(m->m_data, "%u%*[ ,]%u", &n1, &n2) == 2) { - HTONS(n1); - HTONS(n2); - /* n2 is the one on our host */ - for (tmpso = slirp->tcb.so_next; tmpso != &slirp->tcb; - tmpso = tmpso->so_next) { - if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && - tmpso->so_lport == n2 && - tmpso->so_faddr.s_addr == so->so_faddr.s_addr && - tmpso->so_fport == n1) { - if (getsockname(tmpso->s, (struct sockaddr *)&addr, - &addrlen) == 0) - n2 = addr.sin_port; - break; - } - } - NTOHS(n1); - NTOHS(n2); - m_inc(m, g_snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1); - m->m_len = slirp_fmt(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); - } else { - *eol = '\r'; - } - - return 1; - } - - case EMU_FTP: /* ftp */ - m_inc(m, m->m_len + 1); - *(m->m_data + m->m_len) = 0; /* NUL terminate for strstr */ - if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { - /* - * Need to emulate the PORT command - */ - x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", &n1, &n2, - &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr, lport, - SS_FACCEPTONCE)) == NULL) { - return 1; - } - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += slirp_fmt(bptr, M_FREEROOM(m), - "ORT %d,%d,%d,%d,%d,%d\r\n%s", - n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); - return 1; - } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { - /* - * Need to emulate the PASV response - */ - x = sscanf( - bptr, - "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", - &n1, &n2, &n3, &n4, &n5, &n6, buff); - if (x < 6) - return 1; - - laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); - lport = htons((n5 << 8) | (n6)); - - if ((so = tcp_listen(slirp, INADDR_ANY, 0, laddr, lport, - SS_FACCEPTONCE)) == NULL) { - return 1; - } - n6 = ntohs(so->so_fport); - - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; - - laddr = ntohl(so->so_faddr.s_addr); - - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); - - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += slirp_fmt(bptr, M_FREEROOM(m), - "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", - n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); - return 1; - } - - return 1; - - case EMU_KSH: - /* - * The kshell (Kerberos rsh) and shell services both pass - * a local port port number to carry signals to the server - * and stderr to the client. It is passed at the beginning - * of the connection as a NUL-terminated decimal ASCII string. - */ - so->so_emu = 0; - for (lport = 0, i = 0; i < m->m_len - 1; ++i) { - if (m->m_data[i] < '0' || m->m_data[i] > '9') - return 1; /* invalid number */ - lport *= 10; - lport += m->m_data[i] - '0'; - } - if (m->m_data[m->m_len - 1] == '\0' && lport != 0 && - (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, - htons(lport), SS_FACCEPTONCE)) != NULL) - m->m_len = slirp_fmt0(m->m_data, M_ROOM(m), - "%d", ntohs(so->so_fport)); - return 1; - - case EMU_IRC: - /* - * Need to emulate DCC CHAT, DCC SEND and DCC MOVE - */ - m_inc(m, m->m_len + 1); - *(m->m_data + m->m_len) = 0; /* NULL terminate the string for strstr */ - if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) - return 1; - - /* The %256s is for the broken mIRC */ - if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { - if ((so = tcp_listen(slirp, INADDR_ANY, 0, htonl(laddr), - htons(lport), SS_FACCEPTONCE)) == NULL) { - return 1; - } - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += slirp_fmt(bptr, M_FREEROOM(m), - "DCC CHAT chat %lu %u%c\n", - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), 1); - } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, - &n1) == 4) { - if ((so = tcp_listen(slirp, INADDR_ANY, 0, htonl(laddr), - htons(lport), SS_FACCEPTONCE)) == NULL) { - return 1; - } - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += slirp_fmt(bptr, M_FREEROOM(m), - "DCC SEND %s %lu %u %u%c\n", buff, - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, - &n1) == 4) { - if ((so = tcp_listen(slirp, INADDR_ANY, 0, htonl(laddr), - htons(lport), SS_FACCEPTONCE)) == NULL) { - return 1; - } - m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += slirp_fmt(bptr, M_FREEROOM(m), - "DCC MOVE %s %lu %u %u%c\n", buff, - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); - } - return 1; - - case EMU_REALAUDIO: - /* - * RealAudio emulation - JP. We must try to parse the incoming - * data and try to find the two characters that contain the - * port number. Then we redirect an udp port and replace the - * number with the real port we got. - * - * The 1.0 beta versions of the player are not supported - * any more. - * - * A typical packet for player version 1.0 (release version): - * - * 0000:50 4E 41 00 05 - * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 ........g.l.c..P - * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH - * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v - * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB - * - * Now the port number 0x1BD7 is found at offset 0x04 of the - * Now the port number 0x1BD7 is found at offset 0x04 of the - * second packet. This time we received five bytes first and - * then the rest. You never know how many bytes you get. - * - * A typical packet for player version 2.0 (beta): - * - * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA............. - * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux.c..Win2.0.0 - * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ - * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas - * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B - * - * Port number 0x1BC1 is found at offset 0x0d. - * - * This is just a horrible switch statement. Variable ra tells - * us where we're going. - */ - - bptr = m->m_data; - while (bptr < m->m_data + m->m_len) { - uint16_t p; - static int ra = 0; - char ra_tbl[4]; - - ra_tbl[0] = 0x50; - ra_tbl[1] = 0x4e; - ra_tbl[2] = 0x41; - ra_tbl[3] = 0; - - switch (ra) { - case 0: - case 2: - case 3: - if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 1: - /* - * We may get 0x50 several times, ignore them - */ - if (*bptr == 0x50) { - ra = 1; - bptr++; - continue; - } else if (*bptr++ != ra_tbl[ra]) { - ra = 0; - continue; - } - break; - - case 4: - /* - * skip version number - */ - bptr++; - break; - - case 5: - if (bptr == m->m_data + m->m_len - 1) - return 1; /* We need two bytes */ - - /* - * The difference between versions 1.0 and - * 2.0 is here. For future versions of - * the player this may need to be modified. - */ - if (*(bptr + 1) == 0x02) - bptr += 8; - else - bptr += 4; - break; - - case 6: - /* This is the field containing the port - * number that RA-player is listening to. - */ - - if (bptr == m->m_data + m->m_len - 1) - return 1; /* We need two bytes */ - - lport = (((uint8_t *)bptr)[0] << 8) + ((uint8_t *)bptr)[1]; - if (lport < 6970) - lport += 256; /* don't know why */ - if (lport < 6970 || lport > 7170) - return 1; /* failed */ - - /* try to get udp port between 6970 - 7170 */ - for (p = 6970; p < 7071; p++) { - if (udp_listen(slirp, INADDR_ANY, htons(p), - so->so_laddr.s_addr, htons(lport), - SS_FACCEPTONCE)) { - break; - } - } - if (p == 7071) - p = 0; - *(uint8_t *)bptr++ = (p >> 8) & 0xff; - *(uint8_t *)bptr = p & 0xff; - ra = 0; - return 1; /* port redirected, we're done */ - break; - - default: - ra = 0; - } - ra++; - } - return 1; - - default: - /* Ooops, not emulated, won't call tcp_emu again */ - so->so_emu = 0; - return 1; - } -} - -/* - * Do misc. config of SLiRP while its running. - * Return 0 if this connections is to be closed, 1 otherwise, - * return 2 if this is a command-line connection - */ -int tcp_ctl(struct socket *so) -{ - Slirp *slirp = so->slirp; - struct sbuf *sb = &so->so_snd; - struct gfwd_list *ex_ptr; - - DEBUG_CALL("tcp_ctl"); - DEBUG_ARG("so = %p", so); - - /* TODO: IPv6 */ - if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) { - /* Check if it's pty_exec */ - for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) { - if (ex_ptr->write_cb) { - so->s = -1; - so->guestfwd = ex_ptr; - return 1; - } - DEBUG_MISC(" executing %s", ex_ptr->ex_exec); - if (ex_ptr->ex_unix) - return open_unix(so, ex_ptr->ex_unix); - else - return fork_exec(so, ex_ptr->ex_exec); - } - } - } - sb->sb_cc = slirp_fmt(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), - "Error: No application configured.\r\n"); - sb->sb_wptr += sb->sb_cc; - return 0; -} diff --git a/src/network/slirp/tcp_timer.c b/src/network/slirp/tcp_timer.c deleted file mode 100644 index bc4db2d15e..0000000000 --- a/src/network/slirp/tcp_timer.c +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93 - * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp - */ - -#include "slirp.h" - -static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer); - -/* - * Fast timeout routine for processing delayed acks - */ -void tcp_fasttimo(Slirp *slirp) -{ - register struct socket *so; - register struct tcpcb *tp; - - DEBUG_CALL("tcp_fasttimo"); - - so = slirp->tcb.so_next; - if (so) - for (; so != &slirp->tcb; so = so->so_next) - if ((tp = (struct tcpcb *)so->so_tcpcb) && - (tp->t_flags & TF_DELACK)) { - tp->t_flags &= ~TF_DELACK; - tp->t_flags |= TF_ACKNOW; - tcp_output(tp); - } -} - -/* - * Tcp protocol timeout routine called every 500 ms. - * Updates the timers in all active tcb's and - * causes finite state machine actions if timers expire. - */ -void tcp_slowtimo(Slirp *slirp) -{ - register struct socket *ip, *ipnxt; - register struct tcpcb *tp; - register int i; - - DEBUG_CALL("tcp_slowtimo"); - - /* - * Search through tcb's and update active timers. - */ - ip = slirp->tcb.so_next; - if (ip == NULL) { - return; - } - for (; ip != &slirp->tcb; ip = ipnxt) { - ipnxt = ip->so_next; - tp = sototcpcb(ip); - if (tp == NULL) { - continue; - } - for (i = 0; i < TCPT_NTIMERS; i++) { - if (tp->t_timer[i] && --tp->t_timer[i] == 0) { - tcp_timers(tp, i); - if (ipnxt->so_prev != ip) - goto tpgone; - } - } - tp->t_idle++; - if (tp->t_rtt) - tp->t_rtt++; - tpgone:; - } - slirp->tcp_iss += TCP_ISSINCR / PR_SLOWHZ; /* increment iss */ - slirp->tcp_now++; /* for timestamps */ -} - -/* - * Cancel all timers for TCP tp. - */ -void tcp_canceltimers(struct tcpcb *tp) -{ - register int i; - - for (i = 0; i < TCPT_NTIMERS; i++) - tp->t_timer[i] = 0; -} - -const int tcp_backoff[TCP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, - 64, 64, 64, 64, 64, 64 }; - -/* - * TCP timer processing. - */ -static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer) -{ - register int rexmt; - - DEBUG_CALL("tcp_timers"); - - switch (timer) { - /* - * 2 MSL timeout in shutdown went off. If we're closed but - * still waiting for peer to close and connection has been idle - * too long, or if 2MSL time is up from TIME_WAIT, delete connection - * control block. Otherwise, check again in a bit. - */ - case TCPT_2MSL: - if (tp->t_state != TCPS_TIME_WAIT && tp->t_idle <= TCP_MAXIDLE) - tp->t_timer[TCPT_2MSL] = TCPTV_KEEPINTVL; - else - tp = tcp_close(tp); - break; - - /* - * Retransmission timer went off. Message has not - * been acked within retransmit interval. Back off - * to a longer retransmit interval and retransmit one segment. - */ - case TCPT_REXMT: - - /* - * XXXXX If a packet has timed out, then remove all the queued - * packets for that session. - */ - - if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { - /* - * This is a hack to suit our terminal server here at the uni of - * canberra since they have trouble with zeroes... It usually lets - * them through unharmed, but under some conditions, it'll eat the - * zeros. If we keep retransmitting it, it'll keep eating the - * zeroes, so we keep retransmitting, and eventually the connection - * dies... (this only happens on incoming data) - * - * So, if we were gonna drop the connection from too many - * retransmits, don't... instead halve the t_maxseg, which might - * break up the NULLs and let them through - * - * *sigh* - */ - - tp->t_maxseg >>= 1; - if (tp->t_maxseg < 32) { - /* - * We tried our best, now the connection must die! - */ - tp->t_rxtshift = TCP_MAXRXTSHIFT; - tp = tcp_drop(tp, tp->t_softerror); - /* tp->t_softerror : ETIMEDOUT); */ /* XXX */ - return (tp); /* XXX */ - } - - /* - * Set rxtshift to 6, which is still at the maximum - * backoff time - */ - tp->t_rxtshift = 6; - } - rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; - TCPT_RANGESET(tp->t_rxtcur, rexmt, (short)tp->t_rttmin, - TCPTV_REXMTMAX); /* XXX */ - tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* - * If losing, let the lower level know and try for - * a better route. Also, if we backed off this far, - * our srtt estimate is probably bogus. Clobber it - * so we'll take the next rtt measurement as our srtt; - * move the current srtt into rttvar to keep the current - * retransmit times until then. - */ - if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { - tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); - tp->t_srtt = 0; - } - tp->snd_nxt = tp->snd_una; - /* - * If timing a segment in this window, stop the timer. - */ - tp->t_rtt = 0; - /* - * Close the congestion window down to one segment - * (we'll open it by one segment for each ack we get). - * Since we probably have a window's worth of unacked - * data accumulated, this "slow start" keeps us from - * dumping all that data as back-to-back packets (which - * might overwhelm an intermediate gateway). - * - * There are two phases to the opening: Initially we - * open by one mss on each ack. This makes the window - * size increase exponentially with time. If the - * window is larger than the path can handle, this - * exponential growth results in dropped packet(s) - * almost immediately. To get more time between - * drops but still "push" the network to take advantage - * of improving conditions, we switch from exponential - * to linear window opening at some threshold size. - * For a threshold, we use half the current window - * size, truncated to a multiple of the mss. - * - * (the minimum cwnd that will give us exponential - * growth is 2 mss. We don't allow the threshold - * to go below this.) - */ - { - unsigned win = MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; - if (win < 2) - win = 2; - tp->snd_cwnd = tp->t_maxseg; - tp->snd_ssthresh = win * tp->t_maxseg; - tp->t_dupacks = 0; - } - tcp_output(tp); - break; - - /* - * Persistence timer into zero window. - * Force a byte to be output, if possible. - */ - case TCPT_PERSIST: - tcp_setpersist(tp); - tp->t_force = 1; - tcp_output(tp); - tp->t_force = 0; - break; - - /* - * Keep-alive timer went off; send something - * or drop connection if idle for too long. - */ - case TCPT_KEEP: - if (tp->t_state < TCPS_ESTABLISHED) - goto dropit; - - if (slirp_do_keepalive && tp->t_state <= TCPS_CLOSE_WAIT) { - if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE) - goto dropit; - /* - * Send a packet designed to force a response - * if the peer is up and reachable: - * either an ACK if the connection is still alive, - * or an RST if the peer has closed the connection - * due to timeout or reboot. - * Using sequence number tp->snd_una-1 - * causes the transmitted zero-length segment - * to lie outside the receive window; - * by the protocol spec, this requires the - * correspondent TCP to respond. - */ - tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL, tp->rcv_nxt, - tp->snd_una - 1, 0, tp->t_socket->so_ffamily); - tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL; - } else - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE; - break; - - dropit: - tp = tcp_drop(tp, 0); - break; - } - - return (tp); -} diff --git a/src/network/slirp/tcp_timer.h b/src/network/slirp/tcp_timer.h deleted file mode 100644 index 584a5594e4..0000000000 --- a/src/network/slirp/tcp_timer.h +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93 - * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp - */ - -#ifndef TCP_TIMER_H -#define TCP_TIMER_H - -/* - * Definitions of the TCP timers. These timers are counted - * down PR_SLOWHZ times a second. - */ -#define TCPT_NTIMERS 4 - -#define TCPT_REXMT 0 /* retransmit */ -#define TCPT_PERSIST 1 /* retransmit persistence */ -#define TCPT_KEEP 2 /* keep alive */ -#define TCPT_2MSL 3 /* 2*msl quiet time timer */ - -/* - * The TCPT_REXMT timer is used to force retransmissions. - * The TCP has the TCPT_REXMT timer set whenever segments - * have been sent for which ACKs are expected but not yet - * received. If an ACK is received which advances tp->snd_una, - * then the retransmit timer is cleared (if there are no more - * outstanding segments) or reset to the base value (if there - * are more ACKs expected). Whenever the retransmit timer goes off, - * we retransmit one unacknowledged segment, and do a backoff - * on the retransmit timer. - * - * The TCPT_PERSIST timer is used to keep window size information - * flowing even if the window goes shut. If all previous transmissions - * have been acknowledged (so that there are no retransmissions in progress), - * and the window is too small to bother sending anything, then we start - * the TCPT_PERSIST timer. When it expires, if the window is nonzero, - * we go to transmit state. Otherwise, at intervals send a single byte - * into the peer's window to force him to update our window information. - * We do this at most as often as TCPT_PERSMIN time intervals, - * but no more frequently than the current estimate of round-trip - * packet time. The TCPT_PERSIST timer is cleared whenever we receive - * a window update from the peer. - * - * The TCPT_KEEP timer is used to keep connections alive. If an - * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time, - * but not yet established, then we drop the connection. Once the connection - * is established, if the connection is idle for TCPTV_KEEP_IDLE time - * (and keepalives have been enabled on the socket), we begin to probe - * the connection. We force the peer to send us a segment by sending: - * - * This segment is (deliberately) outside the window, and should elicit - * an ack segment in response from the peer. If, despite the TCPT_KEEP - * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE - * amount of time probing, then we drop the connection. - */ - -/* - * Time constants. - */ -#define TCPTV_MSL (5 * PR_SLOWHZ) /* max seg lifetime (hah!) */ - -#define TCPTV_SRTTBASE \ - 0 /* base roundtrip time; \ - if 0, no idea yet */ -#define TCPTV_SRTTDFLT (3 * PR_SLOWHZ) /* assumed RTT if no info */ - -#define TCPTV_PERSMIN (5 * PR_SLOWHZ) /* retransmit persistence */ -#define TCPTV_PERSMAX (60 * PR_SLOWHZ) /* maximum persist interval */ - -#define TCPTV_KEEP_INIT (75 * PR_SLOWHZ) /* initial connect keep alive */ -#define TCPTV_KEEP_IDLE (120 * 60 * PR_SLOWHZ) /* dflt time before probing */ -#define TCPTV_KEEPINTVL (75 * PR_SLOWHZ) /* default probe interval */ -#define TCPTV_KEEPCNT 8 /* max probes before drop */ - -#define TCPTV_MIN (1 * PR_SLOWHZ) /* minimum allowable value */ -#define TCPTV_REXMTMAX (12 * PR_SLOWHZ) /* max allowable REXMT value */ - -#define TCP_LINGERTIME 120 /* linger at most 2 minutes */ - -#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ - - -/* - * Force a time value to be in a certain range. - */ -#define TCPT_RANGESET(tv, value, tvmin, tvmax) \ - { \ - (tv) = (value); \ - if ((tv) < (tvmin)) \ - (tv) = (tvmin); \ - else if ((tv) > (tvmax)) \ - (tv) = (tvmax); \ - } - -extern const int tcp_backoff[]; - -struct tcpcb; - -void tcp_fasttimo(Slirp *); -void tcp_slowtimo(Slirp *); -void tcp_canceltimers(struct tcpcb *); - -#endif diff --git a/src/network/slirp/tcp_var.h b/src/network/slirp/tcp_var.h deleted file mode 100644 index c8da8cbd16..0000000000 --- a/src/network/slirp/tcp_var.h +++ /dev/null @@ -1,161 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94 - * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp - */ - -#ifndef TCP_VAR_H -#define TCP_VAR_H - -#include "tcpip.h" -#include "tcp_timer.h" - -/* - * Tcp control block, one per tcp; fields: - */ -struct tcpcb { - struct tcpiphdr *seg_next; /* sequencing queue */ - struct tcpiphdr *seg_prev; - short t_state; /* state of this connection */ - short t_timer[TCPT_NTIMERS]; /* tcp timers */ - short t_rxtshift; /* log(2) of rexmt exp. backoff */ - short t_rxtcur; /* current retransmit value */ - short t_dupacks; /* consecutive dup acks recd */ - uint16_t t_maxseg; /* maximum segment size */ - uint8_t t_force; /* 1 if forcing out a byte */ - uint16_t t_flags; -#define TF_ACKNOW 0x0001 /* ack peer immediately */ -#define TF_DELACK 0x0002 /* ack, but try to delay it */ -#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ -#define TF_NOOPT 0x0008 /* don't use tcp options */ -#define TF_SENTFIN 0x0010 /* have sent FIN */ -#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ -#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ -#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ -#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ -#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ - - struct tcpiphdr t_template; /* static skeletal packet for xmit */ - - struct socket *t_socket; /* back pointer to socket */ - /* - * The following fields are used as in the protocol specification. - * See RFC783, Dec. 1981, page 21. - */ - /* send sequence variables */ - tcp_seq snd_una; /* send unacknowledged */ - tcp_seq snd_nxt; /* send next */ - tcp_seq snd_up; /* send urgent pointer */ - tcp_seq snd_wl1; /* window update seg seq number */ - tcp_seq snd_wl2; /* window update seg ack number */ - tcp_seq iss; /* initial send sequence number */ - uint32_t snd_wnd; /* send window */ - /* receive sequence variables */ - uint32_t rcv_wnd; /* receive window */ - tcp_seq rcv_nxt; /* receive next */ - tcp_seq rcv_up; /* receive urgent pointer */ - tcp_seq irs; /* initial receive sequence number */ - /* - * Additional variables for this implementation. - */ - /* receive variables */ - tcp_seq rcv_adv; /* advertised window */ - /* retransmit variables */ - tcp_seq snd_max; /* highest sequence number sent; - * used to recognize retransmits - */ - /* congestion control (for slow start, source quench, retransmit after loss) - */ - uint32_t snd_cwnd; /* congestion-controlled window */ - uint32_t snd_ssthresh; /* snd_cwnd size threshold for - * for slow start exponential to - * linear switch - */ - /* - * transmit timing stuff. See below for scale of srtt and rttvar. - * "Variance" is actually smoothed difference. - */ - short t_idle; /* inactivity time */ - short t_rtt; /* round trip time */ - tcp_seq t_rtseq; /* sequence number being timed */ - short t_srtt; /* smoothed round-trip time */ - short t_rttvar; /* variance in round-trip time */ - uint16_t t_rttmin; /* minimum rtt allowed */ - uint32_t max_sndwnd; /* largest window peer has offered */ - - /* out-of-band data */ - uint8_t t_oobflags; /* have some */ - uint8_t t_iobc; /* input character */ -#define TCPOOB_HAVEDATA 0x01 -#define TCPOOB_HADDATA 0x02 - short t_softerror; /* possible error not yet reported */ - - /* RFC 1323 variables */ - uint8_t snd_scale; /* window scaling for send window */ - uint8_t rcv_scale; /* window scaling for recv window */ - uint8_t request_r_scale; /* pending window scaling */ - uint8_t requested_s_scale; - uint32_t ts_recent; /* timestamp echo data */ - uint32_t ts_recent_age; /* when last updated */ - tcp_seq last_ack_sent; -}; - -#define sototcpcb(so) ((so)->so_tcpcb) - -/* - * The smoothed round-trip time and estimated variance - * are stored as fixed point numbers scaled by the values below. - * For convenience, these scales are also used in smoothing the average - * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). - * With these scales, srtt has 3 bits to the right of the binary point, - * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the - * binary point, and is smoothed with an ALPHA of 0.75. - */ -#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ -#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ -#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ -#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ - -/* - * The initial retransmission should happen at rtt + 4 * rttvar. - * Because of the way we do the smoothing, srtt and rttvar - * will each average +1/2 tick of bias. When we compute - * the retransmit timer, we want 1/2 tick of rounding and - * 1 extra tick because of +-1/2 tick uncertainty in the - * firing of the timer. The bias will give us exactly the - * 1.5 tick we need. But, because the bias is - * statistical, we have to test that we don't drop below - * the minimum feasible timer (which is 2 ticks). - * This macro assumes that the value of TCP_RTTVAR_SCALE - * is the same as the multiplier for rttvar. - */ -#define TCP_REXMTVAL(tp) (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) - -#endif diff --git a/src/network/slirp/tcpip.h b/src/network/slirp/tcpip.h deleted file mode 100644 index a0fb2282f2..0000000000 --- a/src/network/slirp/tcpip.h +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 - * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp - */ - -#ifndef TCPIP_H -#define TCPIP_H - -/* - * Tcp+ip header, after ip options removed. - */ -struct tcpiphdr { - struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ - union { - struct { - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ - uint8_t ih_x1; /* (unused) */ - uint8_t ih_pr; /* protocol */ - } ti_i4; - struct { - struct in6_addr ih_src; - struct in6_addr ih_dst; - uint8_t ih_x1; - uint8_t ih_nh; - } ti_i6; - } ti; - uint16_t ti_x0; - uint16_t ti_len; /* protocol length */ - struct tcphdr ti_t; /* tcp header */ -}; -#define ti_mbuf ih_mbuf.mptr -#define ti_pr ti.ti_i4.ih_pr -#define ti_src ti.ti_i4.ih_src -#define ti_dst ti.ti_i4.ih_dst -#define ti_src6 ti.ti_i6.ih_src -#define ti_dst6 ti.ti_i6.ih_dst -#define ti_nh6 ti.ti_i6.ih_nh -#define ti_sport ti_t.th_sport -#define ti_dport ti_t.th_dport -#define ti_seq ti_t.th_seq -#define ti_ack ti_t.th_ack -#define ti_x2 ti_t.th_x2 -#define ti_off ti_t.th_off -#define ti_flags ti_t.th_flags -#define ti_win ti_t.th_win -#define ti_sum ti_t.th_sum -#define ti_urp ti_t.th_urp - -#define tcpiphdr2qlink(T) \ - ((struct qlink *)(((char *)(T)) - sizeof(struct qlink))) -#define qlink2tcpiphdr(Q) \ - ((struct tcpiphdr *)(((char *)(Q)) + sizeof(struct qlink))) -#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) -#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) -#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) -#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink *)(T)) -#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr *)(T)) - -/* This is the difference between the size of a tcpiphdr structure, and the - * size of actual ip+tcp headers, rounded up since we need to align data. */ -#define TCPIPHDR_DELTA \ - (MAX(0, ((int) sizeof(struct tcpiphdr) - (int) sizeof(struct ip) - \ - (int) sizeof(struct tcphdr) + 3) & \ - ~3)) - -/* - * Just a clean way to get to the first byte - * of the packet - */ -struct tcpiphdr_2 { - struct tcpiphdr dummy; - char first_char; -}; - -#endif diff --git a/src/network/slirp/tftp.c b/src/network/slirp/tftp.c deleted file mode 100644 index a19c889d34..0000000000 --- a/src/network/slirp/tftp.c +++ /dev/null @@ -1,470 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * tftp.c - a simple, read-only tftp server for qemu - * - * Copyright (c) 2004 Magnus Damm - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "slirp.h" - -#include -#include -#include - -static inline int tftp_session_in_use(struct tftp_session *spt) -{ - return (spt->slirp != NULL); -} - -static inline void tftp_session_update(struct tftp_session *spt) -{ - spt->timestamp = curtime; -} - -static void tftp_session_terminate(struct tftp_session *spt) -{ - if (spt->fd >= 0) { - close(spt->fd); - spt->fd = -1; - } - g_free(spt->filename); - spt->slirp = NULL; -} - -static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas, - struct tftphdr *hdr) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &slirp->tftp_sessions[k]; - - if (!tftp_session_in_use(spt)) - goto found; - - /* sessions time out after 5 inactive seconds */ - if ((int)(curtime - spt->timestamp) > 5000) { - tftp_session_terminate(spt); - goto found; - } - } - - return -1; - -found: - memset(spt, 0, sizeof(*spt)); - memcpy(&spt->client_addr, srcsas, sockaddr_size(srcsas)); - spt->fd = -1; - spt->block_size = 512; - spt->client_port = hdr->udp.uh_sport; - spt->slirp = slirp; - - tftp_session_update(spt); - - return k; -} - -static int tftp_session_find(Slirp *slirp, struct sockaddr_storage *srcsas, - struct tftphdr *hdr) -{ - struct tftp_session *spt; - int k; - - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &slirp->tftp_sessions[k]; - - if (tftp_session_in_use(spt)) { - if (sockaddr_equal(&spt->client_addr, srcsas)) { - if (spt->client_port == hdr->udp.uh_sport) { - return k; - } - } - } - } - - return -1; -} - -static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr, - uint8_t *buf, int len) -{ - int bytes_read = 0; - - if (spt->fd < 0) { - spt->fd = open(spt->filename, O_RDONLY | O_BINARY); - } - - if (spt->fd < 0) { - return -1; - } - - if (len) { - if (lseek(spt->fd, block_nr * spt->block_size, SEEK_SET) == (off_t)-1) { - return -1; - } - - bytes_read = read(spt->fd, buf, len); - } - - return bytes_read; -} - -static struct tftp_t *tftp_prep_mbuf_data(struct tftp_session *spt, - struct mbuf *m) -{ - struct tftp_t *tp; - - memset(m->m_data, 0, m->m_size); - - m->m_data += IF_MAXLINKHDR; - if (spt->client_addr.ss_family == AF_INET6) { - m->m_data += sizeof(struct ip6); - } else { - m->m_data += sizeof(struct ip); - } - tp = (void *)m->m_data; - m->m_data += sizeof(struct udphdr); - - return tp; -} - -static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m, - struct tftphdr *hdr) -{ - if (spt->client_addr.ss_family == AF_INET6) { - struct sockaddr_in6 sa6, da6; - - sa6.sin6_addr = spt->slirp->vhost_addr6; - sa6.sin6_port = hdr->udp.uh_dport; - da6.sin6_addr = ((struct sockaddr_in6 *)&spt->client_addr)->sin6_addr; - da6.sin6_port = spt->client_port; - - udp6_output(NULL, m, &sa6, &da6); - } else { - struct sockaddr_in sa4, da4; - - sa4.sin_addr = spt->slirp->vhost_addr; - sa4.sin_port = hdr->udp.uh_dport; - da4.sin_addr = ((struct sockaddr_in *)&spt->client_addr)->sin_addr; - da4.sin_port = spt->client_port; - - udp_output(NULL, m, &sa4, &da4, IPTOS_LOWDELAY); - } -} - -static int tftp_send_oack(struct tftp_session *spt, const char *keys[], - uint32_t values[], int nb, struct tftp_t *recv_tp) -{ - struct mbuf *m; - struct tftp_t *tp; - int i, n = 0; - - m = m_get(spt->slirp); - - if (!m) - return -1; - - tp = tftp_prep_mbuf_data(spt, m); - - tp->hdr.tp_op = htons(TFTP_OACK); - for (i = 0; i < nb; i++) { - n += slirp_fmt0(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", keys[i]); - n += slirp_fmt0(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", values[i]); - } - - m->m_len = G_SIZEOF_MEMBER(struct tftp_t, hdr.tp_op) + n; - tftp_udp_output(spt, m, &recv_tp->hdr); - - return 0; -} - -static void tftp_send_error(struct tftp_session *spt, uint16_t errorcode, - const char *msg, struct tftp_t *recv_tp) -{ - struct mbuf *m; - struct tftp_t *tp; - - DEBUG_TFTP("tftp error msg: %s", msg); - - m = m_get(spt->slirp); - - if (!m) { - goto out; - } - - tp = tftp_prep_mbuf_data(spt, m); - - tp->hdr.tp_op = htons(TFTP_ERROR); - tp->x.tp_error.tp_error_code = htons(errorcode); - slirp_pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), - msg); - - m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + - strlen(msg) - sizeof(struct udphdr); - tftp_udp_output(spt, m, &recv_tp->hdr); - -out: - tftp_session_terminate(spt); -} - -static void tftp_send_next_block(struct tftp_session *spt, - struct tftphdr *hdr) -{ - struct mbuf *m; - struct tftp_t *tp; - int nobytes; - - m = m_get(spt->slirp); - - if (!m) { - return; - } - - tp = tftp_prep_mbuf_data(spt, m); - - tp->hdr.tp_op = htons(TFTP_DATA); - tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff); - - nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, - spt->block_size); - - if (nobytes < 0) { - m_free(m); - - /* send "file not found" error back */ - - tftp_send_error(spt, 1, "File not found", tp); - - return; - } - - m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes) - - sizeof(struct udphdr); - tftp_udp_output(spt, m, hdr); - - if (nobytes == spt->block_size) { - tftp_session_update(spt); - } else { - tftp_session_terminate(spt); - } - - spt->block_nr++; -} - -static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas, - struct tftp_t *tp, int pktlen) -{ - struct tftp_session *spt; - int s, k; - size_t prefix_len; - char *req_fname; - const char *option_name[2]; - uint32_t option_value[2]; - int nb_options = 0; - - /* check if a session already exists and if so terminate it */ - s = tftp_session_find(slirp, srcsas, &tp->hdr); - if (s >= 0) { - tftp_session_terminate(&slirp->tftp_sessions[s]); - } - - s = tftp_session_allocate(slirp, srcsas, &tp->hdr); - - if (s < 0) { - return; - } - - spt = &slirp->tftp_sessions[s]; - - /* unspecified prefix means service disabled */ - if (!slirp->tftp_prefix) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - /* skip header fields */ - k = 0; - pktlen -= offsetof(struct tftp_t, x.tp_buf); - - /* prepend tftp_prefix */ - prefix_len = strlen(slirp->tftp_prefix); - spt->filename = g_malloc(prefix_len + TFTP_FILENAME_MAX + 2); - memcpy(spt->filename, slirp->tftp_prefix, prefix_len); - spt->filename[prefix_len] = '/'; - - /* get name */ - req_fname = spt->filename + prefix_len + 1; - - while (1) { - if (k >= TFTP_FILENAME_MAX || k >= pktlen) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - req_fname[k] = tp->x.tp_buf[k]; - if (req_fname[k++] == '\0') { - break; - } - } - - DEBUG_TFTP("tftp rrq file: %s", req_fname); - - /* check mode */ - if ((pktlen - k) < 6) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - if (strcasecmp(&tp->x.tp_buf[k], "octet") != 0) { - tftp_send_error(spt, 4, "Unsupported transfer mode", tp); - return; - } - - k += 6; /* skipping octet */ - - /* do sanity checks on the filename */ - if ( -#ifdef G_OS_WIN32 - strstr(req_fname, "..\\") || - req_fname[strlen(req_fname) - 1] == '\\' || -#endif - strstr(req_fname, "../") || - req_fname[strlen(req_fname) - 1] == '/') { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - /* check if the file exists */ - if (tftp_read_data(spt, 0, NULL, 0) < 0) { - tftp_send_error(spt, 1, "File not found", tp); - return; - } - - if (tp->x.tp_buf[pktlen - 1] != 0) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - while (k < pktlen && nb_options < G_N_ELEMENTS(option_name)) { - const char *key, *value; - - key = &tp->x.tp_buf[k]; - k += strlen(key) + 1; - - if (k >= pktlen) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - value = &tp->x.tp_buf[k]; - k += strlen(value) + 1; - - if (strcasecmp(key, "tsize") == 0) { - int tsize = atoi(value); - struct stat stat_p; - - if (tsize == 0) { - if (stat(spt->filename, &stat_p) == 0) - tsize = stat_p.st_size; - else { - tftp_send_error(spt, 1, "File not found", tp); - return; - } - } - - option_name[nb_options] = "tsize"; - option_value[nb_options] = tsize; - nb_options++; - } else if (strcasecmp(key, "blksize") == 0) { - int blksize = atoi(value); - - /* Accept blksize up to our maximum size */ - if (blksize > 0) { - spt->block_size = MIN(blksize, TFTP_BLOCKSIZE_MAX); - option_name[nb_options] = "blksize"; - option_value[nb_options] = spt->block_size; - nb_options++; - } - } - } - - if (nb_options > 0) { - assert(nb_options <= G_N_ELEMENTS(option_name)); - tftp_send_oack(spt, option_name, option_value, nb_options, tp); - return; - } - - spt->block_nr = 0; - tftp_send_next_block(spt, &tp->hdr); -} - -static void tftp_handle_ack(Slirp *slirp, struct sockaddr_storage *srcsas, - struct tftphdr *hdr) -{ - int s; - - s = tftp_session_find(slirp, srcsas, hdr); - - if (s < 0) { - return; - } - - tftp_send_next_block(&slirp->tftp_sessions[s], hdr); -} - -static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas, - struct tftphdr *hdr) -{ - int s; - - s = tftp_session_find(slirp, srcsas, hdr); - - if (s < 0) { - return; - } - - tftp_session_terminate(&slirp->tftp_sessions[s]); -} - -void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m) -{ - struct tftphdr *hdr = mtod_check(m, sizeof(struct tftphdr)); - - if (hdr == NULL) { - return; - } - - switch (ntohs(hdr->tp_op)) { - case TFTP_RRQ: - tftp_handle_rrq(m->slirp, srcsas, - mtod(m, struct tftp_t *), - m->m_len); - break; - - case TFTP_ACK: - tftp_handle_ack(m->slirp, srcsas, hdr); - break; - - case TFTP_ERROR: - tftp_handle_error(m->slirp, srcsas, hdr); - break; - } -} diff --git a/src/network/slirp/tftp.h b/src/network/slirp/tftp.h deleted file mode 100644 index a0784885ce..0000000000 --- a/src/network/slirp/tftp.h +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* tftp defines */ - -#ifndef SLIRP_TFTP_H -#define SLIRP_TFTP_H - -#include "util.h" - -#define TFTP_SESSIONS_MAX 20 - -#define TFTP_SERVER 69 - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 -#define TFTP_OACK 6 - -#define TFTP_FILENAME_MAX 512 -#define TFTP_BLOCKSIZE_MAX 1428 - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct tftphdr { - struct udphdr udp; - uint16_t tp_op; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(push, 1) -#endif -struct tftp_t { - struct tftphdr hdr; - union { - struct { - uint16_t tp_block_nr; - uint8_t tp_buf[TFTP_BLOCKSIZE_MAX]; - } tp_data; - struct { - uint16_t tp_error_code; - uint8_t tp_msg[TFTP_BLOCKSIZE_MAX]; - } tp_error; - char tp_buf[TFTP_BLOCKSIZE_MAX + 2]; - } x; -} SLIRP_PACKED; -#if defined(_MSC_VER) && !defined (__clang__) -#pragma pack(pop) -#endif - -struct tftp_session { - Slirp *slirp; - char *filename; - int fd; - uint16_t block_size; - - struct sockaddr_storage client_addr; - uint16_t client_port; - uint32_t block_nr; - - int timestamp; -}; - -void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m); - -#endif diff --git a/src/network/slirp/tinyglib.c b/src/network/slirp/tinyglib.c deleted file mode 100644 index 7b1e27bc52..0000000000 --- a/src/network/slirp/tinyglib.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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. - * - * Minimal reimplementation of GLib for libslirp. - * - * - * - * Author: RichardG, - * - * Copyright 2020 RichardG. - */ -#include -#include -#include - -/* Must be a function, as libslirp redefines it as a macro. */ -gboolean -g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, - gchar **envp, GSpawnFlags flags, - GSpawnChildSetupFunc child_setup, - gpointer user_data, GPid *child_pid, gint stdin_fd, - gint stdout_fd, gint stderr_fd, GError **error) -{ - return 0; -} - -/* Implementation borrowed from GLib itself. */ -gboolean -g_str_has_prefix (const gchar *str, - const gchar *prefix) -{ - g_return_val_if_fail (str != NULL, false); - g_return_val_if_fail (prefix != NULL, false); - - return strncmp (str, prefix, strlen (prefix)) == 0; -} - -/* Needs bounds checking, but not really used by libslirp. */ -GString * -g_string_new(gchar *base) -{ - char *ret = malloc(4096); - if (base) - strcpy(ret, base); - return ret; -} - -/* Unimplemented, as with anything related to GString. */ -gchar * -g_string_free(GString *string, gboolean free_segment) -{ - return (free_segment ? NULL : string); -} - -/* Implementation borrowed from GLib itself. */ -gchar * -g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle) -{ - if (haystack_len < 0) - return strstr(haystack, needle); - else { - const gchar *p = haystack; - gsize needle_len = strlen(needle); - gsize haystack_len_unsigned = haystack_len; - const gchar *end; - gsize i; - - if (needle_len == 0) - return (gchar *) haystack; - - if (haystack_len_unsigned < needle_len) - return NULL; - - end = haystack + haystack_len - needle_len; - - while (p <= end && *p) { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; - - return (gchar *) p; - -next: - p++; - } - - return NULL; - } -} - -/* Implementation borrowed from GLib itself. */ -guint -g_strv_length(gchar **str_array) -{ - guint i = 0; - while (str_array[i] != NULL) - ++i; - return i; -} - -/* Implementation borrowed from GLib itself. */ -gsize -g_strlcpy(gchar *dest, - const gchar *src, - gsize dest_size) -{ - gchar *d = dest; - const gchar *s = src; - gsize n = dest_size; - - if (dest == NULL) - return 0; - if (src == NULL) - return 0; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) - do { - gchar c = *s++; - - *d++ = c; - if (c == 0) - break; - } while (--n != 0); - - /* If not enough room in dest, add NUL and traverse rest of src */ - if (n == 0) { - if (dest_size != 0) - *d = 0; - while (*s++) - ; - } - - return s - src - 1; /* count does not include NUL */ -} diff --git a/src/network/slirp/udp.c b/src/network/slirp/udp.c deleted file mode 100644 index bd4dbebded..0000000000 --- a/src/network/slirp/udp.c +++ /dev/null @@ -1,429 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 - * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp - */ - -/* - * Changes and additions relating to SLiRP - * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the - * terms and conditions of the copyright. - */ - -#include "slirp.h" -#include "ip_icmp.h" - -static uint8_t udp_tos(struct socket *so); - -void udp_init(Slirp *slirp) -{ - slirp->udb.so_next = slirp->udb.so_prev = &slirp->udb; - slirp->udp_last_so = &slirp->udb; -} - -void udp_cleanup(Slirp *slirp) -{ - struct socket *so, *so_next; - - for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) { - so_next = so->so_next; - udp_detach(slirp->udb.so_next); - } -} - -/* m->m_data points at ip packet header - * m->m_len length ip packet - * ip->ip_len length data (IPDU) - */ -void udp_input(register struct mbuf *m, int iphlen) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, 0); - - register struct ip *ip; - register struct udphdr *uh; - int len; - struct ip save_ip; - struct socket *so; - struct sockaddr_storage lhost; - struct sockaddr_in *lhost4; - int ttl; - - DEBUG_CALL("udp_input"); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("iphlen = %d", iphlen); - - /* - * Strip IP options, if any; should skip this, - * make available to user, and use on returned packets, - * but we don't yet have a way to check the checksum - * with options still present. - */ - if (iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen = sizeof(struct ip); - } - - /* - * Get IP and UDP header together in first mbuf. - */ - ip = mtod_check(m, iphlen + sizeof(struct udphdr)); - if (ip == NULL) { - goto bad; - } - uh = (struct udphdr *)((char *)ip + iphlen); - - /* - * Make mbuf data length reflect UDP length. - * If not enough data to reflect UDP length, drop. - */ - len = ntohs((uint16_t)uh->uh_ulen); - - if (ip->ip_len != len) { - if (len > ip->ip_len) { - goto bad; - } - m_adj(m, len - ip->ip_len); - ip->ip_len = len; - } - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip = *ip; - save_ip.ip_len += iphlen; /* tcp_input subtracts this */ - - /* - * Checksum extended UDP header and data. - */ - if (uh->uh_sum) { - memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); - ((struct ipovly *)ip)->ih_x1 = 0; - ((struct ipovly *)ip)->ih_len = uh->uh_ulen; - if (cksum(m, len + sizeof(struct ip))) { - goto bad; - } - } - - lhost.ss_family = AF_INET; - lhost4 = (struct sockaddr_in *)&lhost; - lhost4->sin_addr = ip->ip_src; - lhost4->sin_port = uh->uh_sport; - - /* - * handle DHCP/BOOTP - */ - if (ntohs(uh->uh_dport) == BOOTP_SERVER && - (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr || - ip->ip_dst.s_addr == 0xffffffff)) { - bootp_input(m); - goto bad; - } - - /* - * handle TFTP - */ - if (ntohs(uh->uh_dport) == TFTP_SERVER && - ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) { - m->m_data += iphlen; - m->m_len -= iphlen; - tftp_input(&lhost, m); - m->m_data -= iphlen; - m->m_len += iphlen; - goto bad; - } - - if (slirp->restricted) { - goto bad; - } - - /* - * Locate pcb for datagram. - */ - so = solookup(&slirp->udp_last_so, &slirp->udb, &lhost, NULL); - - if (so == NULL) { - /* - * If there's no socket for this packet, - * create one - */ - so = socreate(slirp, IPPROTO_UDP); - if (udp_attach(so, AF_INET) == -1) { - DEBUG_MISC(" udp_attach errno = %d-%s", errno, strerror(errno)); - sofree(so); - goto bad; - } - - /* - * Setup fields - */ - so->so_lfamily = AF_INET; - so->so_laddr = ip->ip_src; - so->so_lport = uh->uh_sport; - - if ((so->so_iptos = udp_tos(so)) == 0) - so->so_iptos = ip->ip_tos; - - /* - * XXXXX Here, check if it's in udpexec_list, - * and if it is, do the fork_exec() etc. - */ - } - - so->so_ffamily = AF_INET; - so->so_faddr = ip->ip_dst; /* XXX */ - so->so_fport = uh->uh_dport; /* XXX */ - - iphlen += sizeof(struct udphdr); - m->m_len -= iphlen; - m->m_data += iphlen; - - /* - * Check for TTL - */ - ttl = save_ip.ip_ttl-1; - if (ttl <= 0) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - DEBUG_MISC("udp ttl exceeded"); - icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, NULL); - goto bad; - } - setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); - - /* - * Now we sendto() the packet. - */ - if (sosendto(so, m) == -1) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - DEBUG_MISC("udp tx errno = %d-%s", errno, strerror(errno)); - icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); - goto bad; - } - - m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ - - /* restore the orig mbuf packet */ - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - so->so_m = m; /* ICMP backup */ - - return; -bad: - m_free(m); -} - -int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, - struct sockaddr_in *daddr, int iptos) -{ - Slirp *slirp = m->slirp; -// char addr[INET_ADDRSTRLEN]; - - M_DUP_DEBUG(slirp, m, 0, sizeof(struct udpiphdr)); - - register struct udpiphdr *ui; - int error = 0; - -/* - DEBUG_CALL("udp_output"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - DEBUG_ARG("saddr = %s", inet_ntop(AF_INET, &saddr->sin_addr, addr, sizeof(addr))); - DEBUG_ARG("daddr = %s", inet_ntop(AF_INET, &daddr->sin_addr, addr, sizeof(addr))); -*/ - - /* - * Adjust for header - */ - m->m_data -= sizeof(struct udpiphdr); - m->m_len += sizeof(struct udpiphdr); - - /* - * Fill in mbuf with extended UDP header - * and addresses and length put into network format. - */ - ui = mtod(m, struct udpiphdr *); - memset(&ui->ui_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); - ui->ui_x1 = 0; - ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons(m->m_len - sizeof(struct ip)); - /* XXXXX Check for from-one-location sockets, or from-any-location sockets - */ - ui->ui_src = saddr->sin_addr; - ui->ui_dst = daddr->sin_addr; - ui->ui_sport = saddr->sin_port; - ui->ui_dport = daddr->sin_port; - ui->ui_ulen = ui->ui_len; - - /* - * Stuff checksum and output datagram. - */ - ui->ui_sum = 0; - if ((ui->ui_sum = cksum(m, m->m_len)) == 0) - ui->ui_sum = 0xffff; - ((struct ip *)ui)->ip_len = m->m_len; - - ((struct ip *)ui)->ip_ttl = IPDEFTTL; - ((struct ip *)ui)->ip_tos = iptos; - - error = ip_output(so, m); - - return (error); -} - -int udp_attach(struct socket *so, unsigned short af) -{ - so->s = slirp_socket(af, SOCK_DGRAM, 0); - if (so->s != -1) { - if (slirp_bind_outbound(so, af) != 0) { - // bind failed - close socket - closesocket(so->s); - so->s = -1; - return -1; - } - -#ifdef __linux__ - { - int opt = 1; - switch (af) { - case AF_INET: - setsockopt(so->s, IPPROTO_IP, IP_RECVERR, &opt, sizeof(opt)); - break; - case AF_INET6: - setsockopt(so->s, IPPROTO_IPV6, IPV6_RECVERR, &opt, sizeof(opt)); - break; - default: - g_assert_not_reached(); - } - } -#endif - - so->so_expire = curtime + SO_EXPIRE; - slirp_insque(so, &so->slirp->udb); - } - so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); - return (so->s); -} - -void udp_detach(struct socket *so) -{ - so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque); - closesocket(so->s); - sofree(so); -} - -static const struct tos_t udptos[] = { { 0, 53, IPTOS_LOWDELAY, 0 }, /* DNS */ - { 0, 0, 0, 0 } }; - -static uint8_t udp_tos(struct socket *so) -{ - int i = 0; - - while (udptos[i].tos) { - if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || - (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { - if (so->slirp->enable_emu) - so->so_emu = udptos[i].emu; - return udptos[i].tos; - } - i++; - } - - return 0; -} - -struct socket *udpx_listen(Slirp *slirp, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *laddr, socklen_t laddrlen, - int flags) -{ - struct socket *so; - socklen_t addrlen; - int save_errno; - - so = socreate(slirp, IPPROTO_UDP); - so->s = slirp_socket(haddr->sa_family, SOCK_DGRAM, 0); - if (so->s < 0) { - save_errno = errno; - sofree(so); - errno = save_errno; - return NULL; - } - if (haddr->sa_family == AF_INET6) - slirp_socket_set_v6only(so->s, (flags & SS_HOSTFWD_V6ONLY) != 0); - so->so_expire = curtime + SO_EXPIRE; - slirp_insque(so, &slirp->udb); - - if (bind(so->s, haddr, haddrlen) < 0) { - save_errno = errno; - udp_detach(so); - errno = save_errno; - return NULL; - } - slirp_socket_set_fast_reuse(so->s); - - addrlen = sizeof(so->fhost); - getsockname(so->s, &so->fhost.sa, &addrlen); - sotranslate_accept(so); - - sockaddr_copy(&so->lhost.sa, sizeof(so->lhost), laddr, laddrlen); - - if (flags != SS_FACCEPTONCE) - so->so_expire = 0; - so->so_state &= SS_PERSISTENT_MASK; - so->so_state |= SS_ISFCONNECTED | flags; - - return so; -} - -struct socket *udp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, - uint32_t laddr, unsigned lport, int flags) -{ - struct sockaddr_in hsa, lsa; - - memset(&hsa, 0, sizeof(hsa)); - hsa.sin_family = AF_INET; - hsa.sin_addr.s_addr = haddr; - hsa.sin_port = hport; - - memset(&lsa, 0, sizeof(lsa)); - lsa.sin_family = AF_INET; - lsa.sin_addr.s_addr = laddr; - lsa.sin_port = lport; - - return udpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags); -} diff --git a/src/network/slirp/udp.h b/src/network/slirp/udp.h deleted file mode 100644 index 47f4ed34d8..0000000000 --- a/src/network/slirp/udp.h +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)udp.h 8.1 (Berkeley) 6/10/93 - * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp - */ - -#ifndef UDP_H -#define UDP_H - -#include "socket.h" - -#define UDP_TTL 0x60 -#define UDP_UDPDATALEN 16192 - -/* - * Udp protocol header. - * Per RFC 768, September, 1981. - */ -struct udphdr { - uint16_t uh_sport; /* source port */ - uint16_t uh_dport; /* destination port */ - int16_t uh_ulen; /* udp length */ - uint16_t uh_sum; /* udp checksum */ -}; - -/* - * UDP kernel structures and variables. - */ -struct udpiphdr { - struct ipovly ui_i; /* overlaid ip structure */ - struct udphdr ui_u; /* udp header */ -}; -#define ui_mbuf ui_i.ih_mbuf.mptr -#define ui_x1 ui_i.ih_x1 -#define ui_pr ui_i.ih_pr -#define ui_len ui_i.ih_len -#define ui_src ui_i.ih_src -#define ui_dst ui_i.ih_dst -#define ui_sport ui_u.uh_sport -#define ui_dport ui_u.uh_dport -#define ui_ulen ui_u.uh_ulen -#define ui_sum ui_u.uh_sum - -/* - * Names for UDP sysctl objects - */ -#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ -#define UDPCTL_MAXID 2 - -struct mbuf; - -void udp_init(Slirp *); -void udp_cleanup(Slirp *); -void udp_input(register struct mbuf *, int); -int udp_attach(struct socket *, unsigned short af); -void udp_detach(struct socket *); -struct socket *udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int); -struct socket *udpx_listen(Slirp *, - const struct sockaddr *haddr, socklen_t haddrlen, - const struct sockaddr *laddr, socklen_t laddrlen, - int flags); -int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, - struct sockaddr_in *daddr, int iptos); - -void udp6_input(register struct mbuf *); -int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr, - struct sockaddr_in6 *daddr); - -#endif diff --git a/src/network/slirp/udp6.c b/src/network/slirp/udp6.c deleted file mode 100644 index effdf77d02..0000000000 --- a/src/network/slirp/udp6.c +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2013 - * Guillaume Subiron - */ - -#include "slirp.h" -#include "udp.h" -#include "dhcpv6.h" - -void udp6_input(struct mbuf *m) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, 0); - - struct ip6 *ip, save_ip; - struct udphdr *uh; - int iphlen = sizeof(struct ip6); - int len; - struct socket *so; - struct sockaddr_in6 lhost; - int hop_limit; - - DEBUG_CALL("udp6_input"); - DEBUG_ARG("m = %p", m); - - if (slirp->restricted) { - goto bad; - } - - ip = mtod(m, struct ip6 *); - m->m_len -= iphlen; - m->m_data += iphlen; - uh = mtod_check(m, sizeof(struct udphdr)); - if (uh == NULL) { - goto bad; - } - m->m_len += iphlen; - m->m_data -= iphlen; - - if (ip6_cksum(m)) { - goto bad; - } - - len = ntohs((uint16_t)uh->uh_ulen); - - /* - * Make mbuf data length reflect UDP length. - * If not enough data to reflect UDP length, drop. - */ - if (ntohs(ip->ip_pl) != len) { - if (len > ntohs(ip->ip_pl)) { - goto bad; - } - m_adj(m, len - ntohs(ip->ip_pl)); - ip->ip_pl = htons(len); - } - - /* - * Save a copy of the IP header in case we want restore it - * for sending an ICMP error message in response. - */ - save_ip = *ip; - - /* Locate pcb for datagram. */ - lhost.sin6_family = AF_INET6; - lhost.sin6_addr = ip->ip_src; - lhost.sin6_port = uh->uh_sport; - - /* handle DHCPv6 */ - if (ntohs(uh->uh_dport) == DHCPV6_SERVER_PORT && - (in6_equal(&ip->ip_dst, &slirp->vhost_addr6) || - in6_dhcp_multicast(&ip->ip_dst))) { - m->m_data += iphlen; - m->m_len -= iphlen; - dhcpv6_input(&lhost, m); - m->m_data -= iphlen; - m->m_len += iphlen; - goto bad; - } - - /* handle TFTP */ - if (ntohs(uh->uh_dport) == TFTP_SERVER && - !memcmp(ip->ip_dst.s6_addr, slirp->vhost_addr6.s6_addr, 16)) { - m->m_data += iphlen; - m->m_len -= iphlen; - tftp_input((struct sockaddr_storage *)&lhost, m); - m->m_data -= iphlen; - m->m_len += iphlen; - goto bad; - } - - so = solookup(&slirp->udp_last_so, &slirp->udb, - (struct sockaddr_storage *)&lhost, NULL); - - if (so == NULL) { - /* If there's no socket for this packet, create one. */ - so = socreate(slirp, IPPROTO_UDP); - if (udp_attach(so, AF_INET6) == -1) { - DEBUG_MISC(" udp6_attach errno = %d-%s", errno, strerror(errno)); - sofree(so); - goto bad; - } - - /* Setup fields */ - so->so_lfamily = AF_INET6; - so->so_laddr6 = ip->ip_src; - so->so_lport6 = uh->uh_sport; - } - - so->so_ffamily = AF_INET6; - so->so_faddr6 = ip->ip_dst; /* XXX */ - so->so_fport6 = uh->uh_dport; /* XXX */ - - iphlen += sizeof(struct udphdr); - m->m_len -= iphlen; - m->m_data += iphlen; - - /* - * Check for TTL - */ - hop_limit = save_ip.ip_hl-1; - if (hop_limit <= 0) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - DEBUG_MISC("udp ttl exceeded"); - icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS); - goto bad; - } - setsockopt(so->s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, sizeof(hop_limit)); - - /* - * Now we sendto() the packet. - */ - if (sosendto(so, m) == -1) { - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - DEBUG_MISC("udp tx errno = %d-%s", errno, strerror(errno)); - icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE); - goto bad; - } - - m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ - - /* restore the orig mbuf packet */ - m->m_len += iphlen; - m->m_data -= iphlen; - *ip = save_ip; - so->so_m = m; - - return; -bad: - m_free(m); -} - -int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr, - struct sockaddr_in6 *daddr) -{ - Slirp *slirp = m->slirp; - M_DUP_DEBUG(slirp, m, 0, sizeof(struct ip6) + sizeof(struct udphdr)); - - struct ip6 *ip; - struct udphdr *uh; - - DEBUG_CALL("udp6_output"); - DEBUG_ARG("so = %p", so); - DEBUG_ARG("m = %p", m); - - /* adjust for header */ - m->m_data -= sizeof(struct udphdr); - m->m_len += sizeof(struct udphdr); - uh = mtod(m, struct udphdr *); - m->m_data -= sizeof(struct ip6); - m->m_len += sizeof(struct ip6); - ip = mtod(m, struct ip6 *); - - /* Build IP header */ - ip->ip_pl = htons(m->m_len - sizeof(struct ip6)); - ip->ip_nh = IPPROTO_UDP; - ip->ip_src = saddr->sin6_addr; - ip->ip_dst = daddr->sin6_addr; - - /* Build UDP header */ - uh->uh_sport = saddr->sin6_port; - uh->uh_dport = daddr->sin6_port; - uh->uh_ulen = ip->ip_pl; - uh->uh_sum = 0; - uh->uh_sum = ip6_cksum(m); - if (uh->uh_sum == 0) { - uh->uh_sum = 0xffff; - } - - return ip6_output(so, m, 0); -} diff --git a/src/network/slirp/util.c b/src/network/slirp/util.c deleted file mode 100644 index 7297e5022b..0000000000 --- a/src/network/slirp/util.c +++ /dev/null @@ -1,442 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * util.c (mostly based on QEMU os-win32.c) - * - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2010-2016 Red Hat, Inc. - * - * QEMU library functions for win32 which are shared between QEMU and - * the QEMU tools. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "util.h" - -#include -#include -#include -#include - -#if defined(_WIN32) -int slirp_inet_aton(const char *cp, struct in_addr *ia) -{ - uint32_t addr = inet_addr(cp); - if (addr == 0xffffffff) { - return 0; - } - ia->s_addr = addr; - return 1; -} -#endif - -void slirp_set_nonblock(int fd) -{ -#ifndef _WIN32 - int f; - f = fcntl(fd, F_GETFL); - assert(f != -1); - f = fcntl(fd, F_SETFL, f | O_NONBLOCK); - assert(f != -1); -#else - unsigned long opt = 1; - ioctlsocket(fd, FIONBIO, &opt); -#endif -} - -static void slirp_set_cloexec(int fd) -{ -#ifndef _WIN32 - int f; - f = fcntl(fd, F_GETFD); - assert(f != -1); - f = fcntl(fd, F_SETFD, f | FD_CLOEXEC); - assert(f != -1); -#endif -} - -/* - * Opens a socket with FD_CLOEXEC set - * On failure errno contains the reason. - */ -int slirp_socket(int domain, int type, int protocol) -{ - int ret; - -#ifdef SOCK_CLOEXEC - ret = socket(domain, type | SOCK_CLOEXEC, protocol); - if (ret != -1 || errno != EINVAL) { - return ret; - } -#endif - ret = socket(domain, type, protocol); - if (ret >= 0) { - slirp_set_cloexec(ret); - } - - return ret; -} - -#ifdef _WIN32 -static int socket_error(void) -{ - switch (WSAGetLastError()) { - case 0: - return 0; - case WSAEINTR: - return EINTR; - case WSAEINVAL: - return EINVAL; - case WSA_INVALID_HANDLE: - return EBADF; - case WSA_NOT_ENOUGH_MEMORY: - return ENOMEM; - case WSA_INVALID_PARAMETER: - return EINVAL; - case WSAENAMETOOLONG: - return ENAMETOOLONG; - case WSAENOTEMPTY: - return ENOTEMPTY; - case WSAEWOULDBLOCK: - /* not using EWOULDBLOCK as we don't want code to have - * to check both EWOULDBLOCK and EAGAIN */ - return EAGAIN; - case WSAEINPROGRESS: - return EINPROGRESS; - case WSAEALREADY: - return EALREADY; - case WSAENOTSOCK: - return ENOTSOCK; - case WSAEDESTADDRREQ: - return EDESTADDRREQ; - case WSAEMSGSIZE: - return EMSGSIZE; - case WSAEPROTOTYPE: - return EPROTOTYPE; - case WSAENOPROTOOPT: - return ENOPROTOOPT; - case WSAEPROTONOSUPPORT: - return EPROTONOSUPPORT; - case WSAEOPNOTSUPP: - return EOPNOTSUPP; - case WSAEAFNOSUPPORT: - return EAFNOSUPPORT; - case WSAEADDRINUSE: - return EADDRINUSE; - case WSAEADDRNOTAVAIL: - return EADDRNOTAVAIL; - case WSAENETDOWN: - return ENETDOWN; - case WSAENETUNREACH: - return ENETUNREACH; - case WSAENETRESET: - return ENETRESET; - case WSAECONNABORTED: - return ECONNABORTED; - case WSAECONNRESET: - return ECONNRESET; - case WSAENOBUFS: - return ENOBUFS; - case WSAEISCONN: - return EISCONN; - case WSAENOTCONN: - return ENOTCONN; - case WSAETIMEDOUT: - return ETIMEDOUT; - case WSAECONNREFUSED: - return ECONNREFUSED; - case WSAELOOP: - return ELOOP; - case WSAEHOSTUNREACH: - return EHOSTUNREACH; - default: - return EIO; - } -} - -#undef ioctlsocket -int slirp_ioctlsocket_wrap(int fd, int req, void *val) -{ - int ret; - ret = ioctlsocket(fd, req, val); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef closesocket -int slirp_closesocket_wrap(int fd) -{ - int ret; - ret = closesocket(fd); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef connect -int slirp_connect_wrap(int sockfd, const struct sockaddr *addr, int addrlen) -{ - int ret; - ret = connect(sockfd, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef listen -int slirp_listen_wrap(int sockfd, int backlog) -{ - int ret; - ret = listen(sockfd, backlog); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef bind -int slirp_bind_wrap(int sockfd, const struct sockaddr *addr, int addrlen) -{ - int ret; - ret = bind(sockfd, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef socket -int slirp_socket_wrap(int domain, int type, int protocol) -{ - int ret; - ret = socket(domain, type, protocol); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef accept -int slirp_accept_wrap(int sockfd, struct sockaddr *addr, int *addrlen) -{ - int ret; - ret = accept(sockfd, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef shutdown -int slirp_shutdown_wrap(int sockfd, int how) -{ - int ret; - ret = shutdown(sockfd, how); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef getsockopt -int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval, - int *optlen) -{ - int ret; - ret = getsockopt(sockfd, level, optname, optval, optlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef setsockopt -int slirp_setsockopt_wrap(int sockfd, int level, int optname, - const void *optval, int optlen) -{ - int ret; - ret = setsockopt(sockfd, level, optname, optval, optlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef getpeername -int slirp_getpeername_wrap(int sockfd, struct sockaddr *addr, int *addrlen) -{ - int ret; - ret = getpeername(sockfd, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef getsockname -int slirp_getsockname_wrap(int sockfd, struct sockaddr *addr, int *addrlen) -{ - int ret; - ret = getsockname(sockfd, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef send -ssize_t slirp_send_wrap(int sockfd, const void *buf, size_t len, int flags) -{ - int ret; - ret = send(sockfd, buf, len, flags); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef sendto -ssize_t slirp_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *addr, int addrlen) -{ - int ret; - ret = sendto(sockfd, buf, len, flags, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef recv -ssize_t slirp_recv_wrap(int sockfd, void *buf, size_t len, int flags) -{ - int ret; - ret = recv(sockfd, buf, len, flags); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} - -#undef recvfrom -ssize_t slirp_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, - struct sockaddr *addr, int *addrlen) -{ - int ret; - ret = recvfrom(sockfd, buf, len, flags, addr, addrlen); - if (ret < 0) { - errno = socket_error(); - } - return ret; -} -#endif /* WIN32 */ - -void slirp_pstrcpy(char *buf, int buf_size, const char *str) -{ - int c; - char *q = buf; - - if (buf_size <= 0) - return; - - for (;;) { - c = *str++; - if (c == 0 || q >= buf + buf_size - 1) - break; - *q++ = c; - } - *q = '\0'; -} - -G_GNUC_PRINTF(3, 0) -static int slirp_vsnprintf(char *str, size_t size, - const char *format, va_list args) -{ - int rv = g_vsnprintf(str, size, format, args); - - if (rv < 0) { - g_error("g_vsnprintf() failed: %s", g_strerror(errno)); - } - - return rv; -} - -/* - * A snprintf()-like function that: - * - returns the number of bytes written (excluding optional \0-ending) - * - dies on error - * - warn on truncation - */ -int slirp_fmt(char *str, size_t size, const char *format, ...) -{ - va_list args; - int rv; - - va_start(args, format); - rv = slirp_vsnprintf(str, size, format, args); - va_end(args); - - if (rv >= size) { - g_critical("slirp_fmt() truncation"); - } - - return MIN(rv, size); -} - -/* - * A snprintf()-like function that: - * - always \0-end (unless size == 0) - * - returns the number of bytes actually written, including \0 ending - * - dies on error - * - warn on truncation - */ -int slirp_fmt0(char *str, size_t size, const char *format, ...) -{ - va_list args; - int rv; - - va_start(args, format); - rv = slirp_vsnprintf(str, size, format, args); - va_end(args); - - if (rv >= size) { - g_critical("slirp_fmt0() truncation"); - if (size > 0) - str[size - 1] = '\0'; - rv = size; - } else { - rv += 1; /* include \0 */ - } - - return rv; -} - -const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str, - size_t out_str_size) -{ - assert(out_str_size >= ETH_ADDRSTRLEN); - - slirp_fmt0(out_str, out_str_size, "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - return out_str; -} diff --git a/src/network/slirp/util.h b/src/network/slirp/util.h deleted file mode 100644 index 0f0123a34a..0000000000 --- a/src/network/slirp/util.h +++ /dev/null @@ -1,201 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright (c) 2003-2008 Fabrice Bellard - * Copyright (c) 2010-2019 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef UTIL_H_ -#define UTIL_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#include -#endif - -#if defined(_MSC_VER) && !defined(__clang__) -#define SLIRP_PACKED -#elif defined(_WIN32) && (defined(__x86_64__) || defined(__i386__)) && !defined(__clang__) -#define SLIRP_PACKED __attribute__((gcc_struct, packed)) -#else -#define SLIRP_PACKED __attribute__((packed)) -#endif - -#ifndef DIV_ROUND_UP -#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) -#endif - -#ifndef container_of -#define container_of(ptr, type, member) \ - ((type *) (((char *)(ptr)) - offsetof(type, member))); -#endif - -#ifndef G_SIZEOF_MEMBER -#define G_SIZEOF_MEMBER(type, member) sizeof(((type *)0)->member) -#endif - -#if defined(_WIN32) /* CONFIG_IOVEC */ -#if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */ -struct iovec { - void *iov_base; - size_t iov_len; -}; -#endif -#else -#include -#endif - -#define stringify(s) tostring(s) -#define tostring(s) #s - -#define SCALE_MS 1000000 - -#define ETH_ALEN 6 -#define ETH_ADDRSTRLEN 18 /* "xx:xx:xx:xx:xx:xx", with trailing NUL */ -#define ETH_HLEN 14 -#define ETH_P_IP (0x0800) /* Internet Protocol packet */ -#define ETH_P_ARP (0x0806) /* Address Resolution packet */ -#define ETH_P_IPV6 (0x86dd) -#define ETH_P_VLAN (0x8100) -#define ETH_P_DVLAN (0x88a8) -#define ETH_P_NCSI (0x88f8) -#define ETH_P_UNKNOWN (0xffff) - -/* FIXME: remove me when made standalone */ -#ifdef _WIN32 -#undef accept -#undef bind -#undef closesocket -#undef connect -#undef getpeername -#undef getsockname -#undef getsockopt -#undef ioctlsocket -#undef listen -#undef recv -#undef recvfrom -#undef send -#undef sendto -#undef setsockopt -#undef shutdown -#undef socket -#endif - -#ifdef _WIN32 -#define connect slirp_connect_wrap -int slirp_connect_wrap(int fd, const struct sockaddr *addr, int addrlen); -#define listen slirp_listen_wrap -int slirp_listen_wrap(int fd, int backlog); -#define bind slirp_bind_wrap -int slirp_bind_wrap(int fd, const struct sockaddr *addr, int addrlen); -#define socket slirp_socket_wrap -int slirp_socket_wrap(int domain, int type, int protocol); -#define accept slirp_accept_wrap -int slirp_accept_wrap(int fd, struct sockaddr *addr, int *addrlen); -#define shutdown slirp_shutdown_wrap -int slirp_shutdown_wrap(int fd, int how); -#define getpeername slirp_getpeername_wrap -int slirp_getpeername_wrap(int fd, struct sockaddr *addr, int *addrlen); -#define getsockname slirp_getsockname_wrap -int slirp_getsockname_wrap(int fd, struct sockaddr *addr, int *addrlen); -#define send slirp_send_wrap -ssize_t slirp_send_wrap(int fd, const void *buf, size_t len, int flags); -#define sendto slirp_sendto_wrap -ssize_t slirp_sendto_wrap(int fd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, int addrlen); -#define recv slirp_recv_wrap -ssize_t slirp_recv_wrap(int fd, void *buf, size_t len, int flags); -#define recvfrom slirp_recvfrom_wrap -ssize_t slirp_recvfrom_wrap(int fd, void *buf, size_t len, int flags, - struct sockaddr *src_addr, int *addrlen); -#define closesocket slirp_closesocket_wrap -int slirp_closesocket_wrap(int fd); -#define ioctlsocket slirp_ioctlsocket_wrap -int slirp_ioctlsocket_wrap(int fd, int req, void *val); -#define getsockopt slirp_getsockopt_wrap -int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval, - int *optlen); -#define setsockopt slirp_setsockopt_wrap -int slirp_setsockopt_wrap(int sockfd, int level, int optname, - const void *optval, int optlen); -#define inet_aton slirp_inet_aton -int slirp_inet_aton(const char *cp, struct in_addr *ia); -#else -#define closesocket(s) close(s) -#define ioctlsocket(s, r, v) ioctl(s, r, v) -#endif - -int slirp_socket(int domain, int type, int protocol); -void slirp_set_nonblock(int fd); - -static inline int slirp_socket_set_v6only(int fd, int v) -{ - return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v)); -} - -static inline int slirp_socket_set_nodelay(int fd) -{ - int v = 1; - return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); -} - -static inline int slirp_socket_set_fast_reuse(int fd) -{ -#ifndef _WIN32 - int v = 1; - return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)); -#else - /* Enabling the reuse of an endpoint that was used by a socket still in - * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows - * fast reuse is the default and SO_REUSEADDR does strange things. So we - * don't have to do anything here. More info can be found at: - * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ - return 0; -#endif -} - -void slirp_pstrcpy(char *buf, int buf_size, const char *str); - -int slirp_fmt(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); -int slirp_fmt0(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); - -/* - * Pretty print a MAC address into out_str. - * As a convenience returns out_str. - */ -const char *slirp_ether_ntoa(const uint8_t *addr, char *out_str, - size_t out_str_len); - -#endif diff --git a/src/network/slirp/version.c b/src/network/slirp/version.c deleted file mode 100644 index 93e0be9c24..0000000000 --- a/src/network/slirp/version.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -#include "libslirp.h" - -const char * -slirp_version_string(void) -{ - return SLIRP_VERSION_STRING; -} diff --git a/src/network/slirp/vmstate.c b/src/network/slirp/vmstate.c deleted file mode 100644 index b9926ea41e..0000000000 --- a/src/network/slirp/vmstate.c +++ /dev/null @@ -1,444 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * VMState interpreter - * - * Copyright (c) 2009-2018 Red Hat Inc - * - * Authors: - * Juan Quintela - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include - -#include "stream.h" -#include "vmstate.h" - -static int get_nullptr(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - if (slirp_istream_read_u8(f) == VMS_NULLPTR_MARKER) { - return 0; - } - g_warning("vmstate: get_nullptr expected VMS_NULLPTR_MARKER"); - return -EINVAL; -} - -static int put_nullptr(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) - -{ - if (pv == NULL) { - slirp_ostream_write_u8(f, VMS_NULLPTR_MARKER); - return 0; - } - g_warning("vmstate: put_nullptr must be called with pv == NULL"); - return -EINVAL; -} - -const VMStateInfo slirp_vmstate_info_nullptr = { - .name = "uint64", - .get = get_nullptr, - .put = put_nullptr, -}; - -/* 8 bit unsigned int */ - -static int get_uint8(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint8_t *v = pv; - *v = slirp_istream_read_u8(f); - return 0; -} - -static int put_uint8(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint8_t *v = pv; - slirp_ostream_write_u8(f, *v); - return 0; -} - -const VMStateInfo slirp_vmstate_info_uint8 = { - .name = "uint8", - .get = get_uint8, - .put = put_uint8, -}; - -/* 16 bit unsigned int */ - -static int get_uint16(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint16_t *v = pv; - *v = slirp_istream_read_u16(f); - return 0; -} - -static int put_uint16(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint16_t *v = pv; - slirp_ostream_write_u16(f, *v); - return 0; -} - -const VMStateInfo slirp_vmstate_info_uint16 = { - .name = "uint16", - .get = get_uint16, - .put = put_uint16, -}; - -/* 32 bit unsigned int */ - -static int get_uint32(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint32_t *v = pv; - *v = slirp_istream_read_u32(f); - return 0; -} - -static int put_uint32(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - uint32_t *v = pv; - slirp_ostream_write_u32(f, *v); - return 0; -} - -const VMStateInfo slirp_vmstate_info_uint32 = { - .name = "uint32", - .get = get_uint32, - .put = put_uint32, -}; - -/* 16 bit int */ - -static int get_int16(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - int16_t *v = pv; - *v = slirp_istream_read_i16(f); - return 0; -} - -static int put_int16(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - int16_t *v = pv; - slirp_ostream_write_i16(f, *v); - return 0; -} - -const VMStateInfo slirp_vmstate_info_int16 = { - .name = "int16", - .get = get_int16, - .put = put_int16, -}; - -/* 32 bit int */ - -static int get_int32(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - int32_t *v = pv; - *v = slirp_istream_read_i32(f); - return 0; -} - -static int put_int32(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - int32_t *v = pv; - slirp_ostream_write_i32(f, *v); - return 0; -} - -const VMStateInfo slirp_vmstate_info_int32 = { - .name = "int32", - .get = get_int32, - .put = put_int32, -}; - -/* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate - * a temporary buffer and the pre_load/pre_save methods in the child vmsd - * copy stuff from the parent into the child and do calculations to fill - * in fields that don't really exist in the parent but need to be in the - * stream. - */ -static int get_tmp(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - int ret; - const VMStateDescription *vmsd = field->vmsd; - int version_id = field->version_id; - void *tmp = g_malloc(size); - - /* Writes the parent field which is at the start of the tmp */ - *(void **)tmp = pv; - ret = slirp_vmstate_load_state(f, vmsd, tmp, version_id); - g_free(tmp); - return ret; -} - -static int put_tmp(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - const VMStateDescription *vmsd = field->vmsd; - void *tmp = g_malloc(size); - int ret; - - /* Writes the parent field which is at the start of the tmp */ - *(void **)tmp = pv; - ret = slirp_vmstate_save_state(f, vmsd, tmp); - g_free(tmp); - - return ret; -} - -const VMStateInfo slirp_vmstate_info_tmp = { - .name = "tmp", - .get = get_tmp, - .put = put_tmp, -}; - -/* uint8_t buffers */ - -static int get_buffer(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field) -{ - slirp_istream_read(f, pv, size); - return 0; -} - -static int put_buffer(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field) -{ - slirp_ostream_write(f, pv, size); - return 0; -} - -const VMStateInfo slirp_vmstate_info_buffer = { - .name = "buffer", - .get = get_buffer, - .put = put_buffer, -}; - -static int vmstate_n_elems(void *opaque, const VMStateField *field) -{ - int n_elems = 1; - - if (field->flags & VMS_ARRAY) { - n_elems = field->num; - } else if (field->flags & VMS_VARRAY_INT32) { - n_elems = *(int32_t *)(opaque + field->num_offset); - } else if (field->flags & VMS_VARRAY_UINT32) { - n_elems = *(uint32_t *)(opaque + field->num_offset); - } else if (field->flags & VMS_VARRAY_UINT16) { - n_elems = *(uint16_t *)(opaque + field->num_offset); - } else if (field->flags & VMS_VARRAY_UINT8) { - n_elems = *(uint8_t *)(opaque + field->num_offset); - } - - if (field->flags & VMS_MULTIPLY_ELEMENTS) { - n_elems *= field->num; - } - - return n_elems; -} - -static int vmstate_size(void *opaque, const VMStateField *field) -{ - int size = field->size; - - if (field->flags & VMS_VBUFFER) { - size = *(int32_t *)(opaque + field->size_offset); - if (field->flags & VMS_MULTIPLY) { - size *= field->size; - } - } - - return size; -} - -static int vmstate_save_state_v(SlirpOStream *f, const VMStateDescription *vmsd, - void *opaque, int version_id) -{ - int ret = 0; - const VMStateField *field = vmsd->fields; - - if (vmsd->pre_save) { - ret = vmsd->pre_save(opaque); - if (ret) { - g_warning("pre-save failed: %s", vmsd->name); - return ret; - } - } - - while (field->name) { - if ((field->field_exists && field->field_exists(opaque, version_id)) || - (!field->field_exists && field->version_id <= version_id)) { - void *first_elem = opaque + field->offset; - int i, n_elems = vmstate_n_elems(opaque, field); - int size = vmstate_size(opaque, field); - - if (field->flags & VMS_POINTER) { - first_elem = *(void **)first_elem; - assert(first_elem || !n_elems || !size); - } - for (i = 0; i < n_elems; i++) { - void *curr_elem = first_elem + size * i; - - if (field->flags & VMS_ARRAY_OF_POINTER) { - assert(curr_elem); - curr_elem = *(void **)curr_elem; - } - if (!curr_elem && size) { - /* if null pointer write placeholder and do not follow */ - assert(field->flags & VMS_ARRAY_OF_POINTER); - ret = slirp_vmstate_info_nullptr.put(f, curr_elem, size, - NULL); - } else if (field->flags & VMS_STRUCT) { - ret = slirp_vmstate_save_state(f, field->vmsd, curr_elem); - } else if (field->flags & VMS_VSTRUCT) { - ret = vmstate_save_state_v(f, field->vmsd, curr_elem, - field->struct_version_id); - } else { - ret = field->info->put(f, curr_elem, size, field); - } - if (ret) { - g_warning("Save of field %s/%s failed", vmsd->name, - field->name); - return ret; - } - } - } else { - if (field->flags & VMS_MUST_EXIST) { - g_warning("Output state validation failed: %s/%s", vmsd->name, - field->name); - assert(!(field->flags & VMS_MUST_EXIST)); - } - } - field++; - } - - return 0; -} - -int slirp_vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd, - void *opaque) -{ - return vmstate_save_state_v(f, vmsd, opaque, vmsd->version_id); -} - -static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque) -{ - if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) { - size_t size = vmstate_size(opaque, field); - size *= vmstate_n_elems(opaque, field); - if (size) { - *(void **)ptr = g_malloc(size); - } - } -} - -int slirp_vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd, - void *opaque, int version_id) -{ - VMStateField *field = vmsd->fields; - int ret = 0; - - if (version_id > vmsd->version_id) { - g_warning("%s: incoming version_id %d is too new " - "for local version_id %d", - vmsd->name, version_id, vmsd->version_id); - return -EINVAL; - } - if (vmsd->pre_load) { - int ret = vmsd->pre_load(opaque); - if (ret) { - return ret; - } - } - while (field->name) { - if ((field->field_exists && field->field_exists(opaque, version_id)) || - (!field->field_exists && field->version_id <= version_id)) { - void *first_elem = opaque + field->offset; - int i, n_elems = vmstate_n_elems(opaque, field); - int size = vmstate_size(opaque, field); - - vmstate_handle_alloc(first_elem, field, opaque); - if (field->flags & VMS_POINTER) { - first_elem = *(void **)first_elem; - assert(first_elem || !n_elems || !size); - } - for (i = 0; i < n_elems; i++) { - void *curr_elem = first_elem + size * i; - - if (field->flags & VMS_ARRAY_OF_POINTER) { - curr_elem = *(void **)curr_elem; - } - if (!curr_elem && size) { - /* if null pointer check placeholder and do not follow */ - assert(field->flags & VMS_ARRAY_OF_POINTER); - ret = slirp_vmstate_info_nullptr.get(f, curr_elem, size, - NULL); - } else if (field->flags & VMS_STRUCT) { - ret = slirp_vmstate_load_state(f, field->vmsd, curr_elem, - field->vmsd->version_id); - } else if (field->flags & VMS_VSTRUCT) { - ret = slirp_vmstate_load_state(f, field->vmsd, curr_elem, - field->struct_version_id); - } else { - ret = field->info->get(f, curr_elem, size, field); - } - if (ret < 0) { - g_warning("Failed to load %s:%s", vmsd->name, field->name); - return ret; - } - } - } else if (field->flags & VMS_MUST_EXIST) { - g_warning("Input validation failed: %s/%s", vmsd->name, - field->name); - return -1; - } - field++; - } - if (vmsd->post_load) { - ret = vmsd->post_load(opaque, version_id); - } - return ret; -} diff --git a/src/network/slirp/vmstate.h b/src/network/slirp/vmstate.h deleted file mode 100644 index b1d40e8929..0000000000 --- a/src/network/slirp/vmstate.h +++ /dev/null @@ -1,404 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * QEMU migration/snapshot declarations - * - * Copyright (c) 2009-2011 Red Hat, Inc. - * - * Original author: Juan Quintela - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef VMSTATE_H_ -#define VMSTATE_H_ - -#ifndef _WIN32 -#include -#endif -#include -#include -#include "slirp.h" -#include "stream.h" - -#define stringify(s) tostring(s) -#define tostring(s) #s - -typedef struct VMStateInfo VMStateInfo; -typedef struct VMStateDescription VMStateDescription; -typedef struct VMStateField VMStateField; - -int slirp_vmstate_save_state(SlirpOStream *f, const VMStateDescription *vmsd, - void *opaque); -int slirp_vmstate_load_state(SlirpIStream *f, const VMStateDescription *vmsd, - void *opaque, int version_id); - -/* VMStateInfo allows customized migration of objects that don't fit in - * any category in VMStateFlags. Additional information is always passed - * into get and put in terms of field and vmdesc parameters. However - * these two parameters should only be used in cases when customized - * handling is needed, such as QTAILQ. For primitive data types such as - * integer, field and vmdesc parameters should be ignored inside get/put. - */ -struct VMStateInfo { - const char *name; - int (*get)(SlirpIStream *f, void *pv, size_t size, - const VMStateField *field); - int (*put)(SlirpOStream *f, void *pv, size_t size, - const VMStateField *field); -}; - -enum VMStateFlags { - /* Ignored */ - VMS_SINGLE = 0x001, - - /* The struct member at opaque + VMStateField.offset is a pointer - * to the actual field (e.g. struct a { uint8_t *b; - * }). Dereference the pointer before using it as basis for - * further pointer arithmetic (see e.g. VMS_ARRAY). Does not - * affect the meaning of VMStateField.num_offset or - * VMStateField.size_offset; see VMS_VARRAY* and VMS_VBUFFER for - * those. */ - VMS_POINTER = 0x002, - - /* The field is an array of fixed size. VMStateField.num contains - * the number of entries in the array. The size of each entry is - * given by VMStateField.size and / or opaque + - * VMStateField.size_offset; see VMS_VBUFFER and - * VMS_MULTIPLY. Each array entry will be processed individually - * (VMStateField.info.get()/put() if VMS_STRUCT is not set, - * recursion into VMStateField.vmsd if VMS_STRUCT is set). May not - * be combined with VMS_VARRAY*. */ - VMS_ARRAY = 0x004, - - /* The field is itself a struct, containing one or more - * fields. Recurse into VMStateField.vmsd. Most useful in - * combination with VMS_ARRAY / VMS_VARRAY*, recursing into each - * array entry. */ - VMS_STRUCT = 0x008, - - /* The field is an array of variable size. The int32_t at opaque + - * VMStateField.num_offset contains the number of entries in the - * array. See the VMS_ARRAY description regarding array handling - * in general. May not be combined with VMS_ARRAY or any other - * VMS_VARRAY*. */ - VMS_VARRAY_INT32 = 0x010, - - /* Ignored */ - VMS_BUFFER = 0x020, - - /* The field is a (fixed-size or variable-size) array of pointers - * (e.g. struct a { uint8_t *b[]; }). Dereference each array entry - * before using it. Note: Does not imply any one of VMS_ARRAY / - * VMS_VARRAY*; these need to be set explicitly. */ - VMS_ARRAY_OF_POINTER = 0x040, - - /* The field is an array of variable size. The uint16_t at opaque - * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) - * contains the number of entries in the array. See the VMS_ARRAY - * description regarding array handling in general. May not be - * combined with VMS_ARRAY or any other VMS_VARRAY*. */ - VMS_VARRAY_UINT16 = 0x080, - - /* The size of the individual entries (a single array entry if - * VMS_ARRAY or any of VMS_VARRAY* are set, or the field itself if - * neither is set) is variable (i.e. not known at compile-time), - * but the same for all entries. Use the int32_t at opaque + - * VMStateField.size_offset (subject to VMS_MULTIPLY) to determine - * the size of each (and every) entry. */ - VMS_VBUFFER = 0x100, - - /* Multiply the entry size given by the int32_t at opaque + - * VMStateField.size_offset (see VMS_VBUFFER description) with - * VMStateField.size to determine the number of bytes to be - * allocated. Only valid in combination with VMS_VBUFFER. */ - VMS_MULTIPLY = 0x200, - - /* The field is an array of variable size. The uint8_t at opaque + - * VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) - * contains the number of entries in the array. See the VMS_ARRAY - * description regarding array handling in general. May not be - * combined with VMS_ARRAY or any other VMS_VARRAY*. */ - VMS_VARRAY_UINT8 = 0x400, - - /* The field is an array of variable size. The uint32_t at opaque - * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) - * contains the number of entries in the array. See the VMS_ARRAY - * description regarding array handling in general. May not be - * combined with VMS_ARRAY or any other VMS_VARRAY*. */ - VMS_VARRAY_UINT32 = 0x800, - - /* Fail loading the serialised VM state if this field is missing - * from the input. */ - VMS_MUST_EXIST = 0x1000, - - /* When loading serialised VM state, allocate memory for the - * (entire) field. Only valid in combination with - * VMS_POINTER. Note: Not all combinations with other flags are - * currently supported, e.g. VMS_ALLOC|VMS_ARRAY_OF_POINTER won't - * cause the individual entries to be allocated. */ - VMS_ALLOC = 0x2000, - - /* Multiply the number of entries given by the integer at opaque + - * VMStateField.num_offset (see VMS_VARRAY*) with VMStateField.num - * to determine the number of entries in the array. Only valid in - * combination with one of VMS_VARRAY*. */ - VMS_MULTIPLY_ELEMENTS = 0x4000, - - /* A structure field that is like VMS_STRUCT, but uses - * VMStateField.struct_version_id to tell which version of the - * structure we are referencing to use. */ - VMS_VSTRUCT = 0x8000, - - /* Marker for end of list */ - VMS_END = 0x10000 -}; - -struct VMStateField { - const char *name; - size_t offset; - size_t size; - size_t start; - int num; - size_t num_offset; - size_t size_offset; - const VMStateInfo *info; - enum VMStateFlags flags; - const VMStateDescription *vmsd; - int version_id; - int struct_version_id; - bool (*field_exists)(void *opaque, int version_id); -}; - -struct VMStateDescription { - const char *name; - int version_id; - int (*pre_load)(void *opaque); - int (*post_load)(void *opaque, int version_id); - int (*pre_save)(void *opaque); - VMStateField *fields; -}; - - -extern const VMStateInfo slirp_vmstate_info_int16; -extern const VMStateInfo slirp_vmstate_info_int32; -extern const VMStateInfo slirp_vmstate_info_uint8; -extern const VMStateInfo slirp_vmstate_info_uint16; -extern const VMStateInfo slirp_vmstate_info_uint32; - -/** Put this in the stream when migrating a null pointer.*/ -#define VMS_NULLPTR_MARKER (0x30U) /* '0' */ -extern const VMStateInfo slirp_vmstate_info_nullptr; - -extern const VMStateInfo slirp_vmstate_info_buffer; -extern const VMStateInfo slirp_vmstate_info_tmp; - -#ifdef __GNUC__ -#define type_check_array(t1, t2, n) ((t1(*)[n])0 - (t2 *)0) -#define type_check_pointer(t1, t2) ((t1 **)0 - (t2 *)0) -#define typeof_field(type, field) typeof(((type *)0)->field) -#define type_check(t1, t2) ((t1 *)0 - (t2 *)0) -#else -#define type_check_array(t1, t2, n) 0 -#define type_check_pointer(t1, t2) 0 -#define typeof_field(type, field) (((type *)0)->field) -#define type_check(t1, t2) 0 -#endif - -#define vmstate_offset_value(_state, _field, _type) \ - (offsetof(_state, _field) + type_check(_type, typeof_field(_state, _field))) - -#define vmstate_offset_pointer(_state, _field, _type) \ - (offsetof(_state, _field) + \ - type_check_pointer(_type, typeof_field(_state, _field))) - -#define vmstate_offset_array(_state, _field, _type, _num) \ - (offsetof(_state, _field) + \ - type_check_array(_type, typeof_field(_state, _field), _num)) - -#define vmstate_offset_buffer(_state, _field) \ - vmstate_offset_array(_state, _field, uint8_t, \ - sizeof(typeof_field(_state, _field))) - -/* In the macros below, if there is a _version, that means the macro's - * field will be processed only if the version being received is >= - * the _version specified. In general, if you add a new field, you - * would increment the structure's version and put that version - * number into the new field so it would only be processed with the - * new version. - * - * In particular, for VMSTATE_STRUCT() and friends the _version does - * *NOT* pick the version of the sub-structure. It works just as - * specified above. The version of the top-level structure received - * is passed down to all sub-structures. This means that the - * sub-structures must have version that are compatible with all the - * structures that use them. - * - * If you want to specify the version of the sub-structure, use - * VMSTATE_VSTRUCT(), which allows the specific sub-structure version - * to be directly specified. - */ - -#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) \ - { \ - .name = (stringify(_field)), .version_id = (_version), \ - .field_exists = (_test), .size = sizeof(_type), .info = &(_info), \ - .flags = VMS_SINGLE, \ - .offset = vmstate_offset_value(_state, _field, _type), \ - } - -#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) \ - { \ - .name = (stringify(_field)), .version_id = (_version), .num = (_num), \ - .info = &(_info), .size = sizeof(_type), .flags = VMS_ARRAY, \ - .offset = vmstate_offset_array(_state, _field, _type, _num), \ - } - -#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) \ - { \ - .name = (stringify(_field)), .version_id = (_version), \ - .field_exists = (_test), .vmsd = &(_vmsd), .size = sizeof(_type), \ - .flags = VMS_STRUCT, \ - .offset = vmstate_offset_value(_state, _field, _type), \ - } - -#define VMSTATE_STRUCT_POINTER_V(_field, _state, _version, _vmsd, _type) \ - { \ - .name = (stringify(_field)), .version_id = (_version), \ - .vmsd = &(_vmsd), .size = sizeof(_type *), \ - .flags = VMS_STRUCT | VMS_POINTER, \ - .offset = vmstate_offset_pointer(_state, _field, _type), \ - } - -#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, \ - _vmsd, _type) \ - { \ - .name = (stringify(_field)), .num = (_num), .field_exists = (_test), \ - .version_id = (_version), .vmsd = &(_vmsd), .size = sizeof(_type), \ - .flags = VMS_STRUCT | VMS_ARRAY, \ - .offset = vmstate_offset_array(_state, _field, _type, _num), \ - } - -#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) \ - { \ - .name = (stringify(_field)), .version_id = (_version), \ - .field_exists = (_test), .size = (_size - _start), \ - .info = &slirp_vmstate_info_buffer, .flags = VMS_BUFFER, \ - .offset = vmstate_offset_buffer(_state, _field) + _start, \ - } - -#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _field_size) \ - { \ - .name = (stringify(_field)), .version_id = (_version), \ - .field_exists = (_test), \ - .size_offset = vmstate_offset_value(_state, _field_size, uint32_t), \ - .info = &slirp_vmstate_info_buffer, \ - .flags = VMS_VBUFFER | VMS_POINTER, \ - .offset = offsetof(_state, _field), \ - } - -#define QEMU_BUILD_BUG_ON_STRUCT(x) \ - struct { \ - int : (x) ? -1 : 1; \ - } - -#define QEMU_BUILD_BUG_ON_ZERO(x) \ - (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - sizeof(QEMU_BUILD_BUG_ON_STRUCT(x))) - -/* Allocate a temporary of type 'tmp_type', set tmp->parent to _state - * and execute the vmsd on the temporary. Note that we're working with - * the whole of _state here, not a field within it. - * We compile time check that: - * That _tmp_type contains a 'parent' member that's a pointer to the - * '_state' type - * That the pointer is right at the start of _tmp_type. - */ -#define VMSTATE_WITH_TMP(_state, _tmp_type, _vmsd) \ - { \ - .name = "tmp", \ - .size = sizeof(_tmp_type) + \ - QEMU_BUILD_BUG_ON_ZERO(offsetof(_tmp_type, parent) != 0) + \ - type_check_pointer(_state, typeof_field(_tmp_type, parent)), \ - .vmsd = &(_vmsd), .info = &slirp_vmstate_info_tmp, \ - } - -#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \ - VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type) - -#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) \ - VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type) - -#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \ - VMSTATE_STRUCT_POINTER_V(_field, _state, 0, _vmsd, _type) - -#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \ - VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, _vmsd, \ - _type) - -#define VMSTATE_INT16_V(_f, _s, _v) \ - VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_int16, int16_t) -#define VMSTATE_INT32_V(_f, _s, _v) \ - VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_int32, int32_t) - -#define VMSTATE_UINT8_V(_f, _s, _v) \ - VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint8, uint8_t) -#define VMSTATE_UINT16_V(_f, _s, _v) \ - VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint16, uint16_t) -#define VMSTATE_UINT32_V(_f, _s, _v) \ - VMSTATE_SINGLE(_f, _s, _v, slirp_vmstate_info_uint32, uint32_t) - -#define VMSTATE_INT16(_f, _s) VMSTATE_INT16_V(_f, _s, 0) -#define VMSTATE_INT32(_f, _s) VMSTATE_INT32_V(_f, _s, 0) - -#define VMSTATE_UINT8(_f, _s) VMSTATE_UINT8_V(_f, _s, 0) -#define VMSTATE_UINT16(_f, _s) VMSTATE_UINT16_V(_f, _s, 0) -#define VMSTATE_UINT32(_f, _s) VMSTATE_UINT32_V(_f, _s, 0) - -#define VMSTATE_UINT16_TEST(_f, _s, _t) \ - VMSTATE_SINGLE_TEST(_f, _s, _t, 0, slirp_vmstate_info_uint16, uint16_t) - -#define VMSTATE_UINT32_TEST(_f, _s, _t) \ - VMSTATE_SINGLE_TEST(_f, _s, _t, 0, slirp_vmstate_info_uint32, uint32_t) - -#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \ - VMSTATE_ARRAY(_f, _s, _n, _v, slirp_vmstate_info_int16, int16_t) - -#define VMSTATE_INT16_ARRAY(_f, _s, _n) VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0) - -#define VMSTATE_BUFFER_V(_f, _s, _v) \ - VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) - -#define VMSTATE_BUFFER(_f, _s) VMSTATE_BUFFER_V(_f, _s, 0) - -#define VMSTATE_END_OF_LIST() \ - { \ - .flags = VMS_END, \ - } - -#endif /* VMSTATE_H_ */ diff --git a/src/nmi.c b/src/nmi.c index 4fde007652..fbe3bee19c 100644 --- a/src/nmi.c +++ b/src/nmi.c @@ -7,11 +7,12 @@ #include #include <86box/io.h> #include <86box/nmi.h> +#include <86box/plat_unused.h> int nmi_mask; void -nmi_write(uint16_t port, uint8_t val, void *p) +nmi_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { nmi_mask = val & 0x80; } diff --git a/src/nvr.c b/src/nvr.c index aefee99a8a..d833618d02 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -224,9 +224,9 @@ nvr_path(char *str) int nvr_load(void) { - char *path; - FILE *fp; - uint8_t regs[NVR_MAXSIZE] = { 0 }; + const char *path; + FILE *fp; + uint8_t regs[NVR_MAXSIZE] = { 0 }; /* Make sure we have been initialized. */ if (saved_nvr == NULL) @@ -274,8 +274,8 @@ nvr_set_ven_save(void (*ven_save)(void)) int nvr_save(void) { - char *path; - FILE *fp; + const char *path; + FILE *fp; /* Make sure we have been initialized. */ if (saved_nvr == NULL) diff --git a/src/nvr_at.c b/src/nvr_at.c index 52bc7c9b57..4ddec729ff 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -194,11 +194,10 @@ * Authors: Fred N. van Kempen, * Miran Grca, * Mahod, - * Sarah Walker, * * Copyright 2017-2020 Fred N. van Kempen. * Copyright 2016-2020 Miran Grca. - * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Mahod. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -296,24 +295,34 @@ #define FLAG_AMI_1995_HACK 0x08 #define FLAG_P6RP4_HACK 0x10 #define FLAG_PIIX4 0x20 +#define FLAG_MULTI_BANK 0x40 -typedef struct { +typedef struct local_t { int8_t stat; - uint8_t cent, def, - flags, read_addr, - wp_0d, wp_32, - pad, pad0; - - uint8_t addr[8], wp[2], - bank[8], *lock; - - int16_t count, state; - - uint64_t ecount, - rtc_time; - pc_timer_t update_timer, - rtc_timer; + uint8_t cent; + uint8_t def; + uint8_t flags; + uint8_t read_addr; + uint8_t wp_0d; + uint8_t wp_32; + uint8_t irq_state; + uint8_t smi_status; + + uint8_t addr[8]; + uint8_t wp[2]; + uint8_t bank[8]; + uint8_t *lock; + + int16_t count; + int16_t state; + + int32_t smi_enable; + + uint64_t ecount; + uint64_t rtc_time; + pc_timer_t update_timer; + pc_timer_t rtc_timer; } local_t; static uint8_t nvr_at_inited = 0; @@ -322,8 +331,8 @@ static uint8_t nvr_at_inited = 0; static void time_get(nvr_t *nvr, struct tm *tm) { - local_t *local = (local_t *) nvr->data; - int8_t temp; + const local_t *local = (local_t *) nvr->data; + int8_t temp; if (nvr->regs[RTC_REGB] & REGB_DM) { /* NVR is in Binary data mode. */ @@ -360,8 +369,8 @@ time_get(nvr_t *nvr, struct tm *tm) static void time_set(nvr_t *nvr, struct tm *tm) { - local_t *local = (local_t *) nvr->data; - int year = (tm->tm_year + 1900); + const local_t *local = (local_t *) nvr->data; + int year = (tm->tm_year + 1900); if (nvr->regs[RTC_REGB] & REGB_DM) { /* NVR is in Binary data mode. */ @@ -419,7 +428,7 @@ check_alarm(nvr_t *nvr, int8_t addr) static int8_t check_alarm_via(nvr_t *nvr, int8_t addr, int8_t addr_2) { - local_t *local = (local_t *) nvr->data; + const local_t *local = (local_t *) nvr->data; if (local->cent == RTC_CENTURY_VIA) { return ((nvr->regs[addr_2] == nvr->regs[addr]) || ((nvr->regs[addr_2] & AL_DONTCARE) == AL_DONTCARE)); @@ -427,6 +436,27 @@ check_alarm_via(nvr_t *nvr, int8_t addr, int8_t addr_2) return 1; } +static void +timer_update_irq(nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + uint8_t irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & (REGB_UIE | REGB_AIE | REGB_PIE); + + if (irq || (local->irq_state != !!irq)) { + if (irq) { + nvr->regs[RTC_REGC] |= REGC_IRQF; + picintlevel(1 << nvr->irq, &local->irq_state); + if (local->smi_enable) { + smi_raise(); + local->smi_status = 1; + } + } else { + nvr->regs[RTC_REGC] &= ~REGC_IRQF; + picintclevel(1 << nvr->irq, &local->irq_state); + } + } +} + /* Update the NVR registers from the internal clock. */ static void timer_update(void *priv) @@ -435,45 +465,38 @@ timer_update(void *priv) local_t *local = (local_t *) nvr->data; struct tm tm; - local->ecount = 0LL; + if (local->ecount == (244ULL * TIMER_USEC)) { + rtc_tick(); - if (!(nvr->regs[RTC_REGB] & REGB_SET)) { /* Get the current time from the internal clock. */ nvr_time_get(&tm); /* Update registers with current time. */ time_set(nvr, &tm); - /* Clear update status. */ - local->stat = 0x00; - /* Check for any alarms we need to handle. */ - if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) && check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* && - check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) && - check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS)*/ - ) { + if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) && + check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* && + check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS) */) { nvr->regs[RTC_REGC] |= REGC_AF; - if (nvr->regs[RTC_REGB] & REGB_AIE) { - /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { - picintlevel(1 << nvr->irq); - nvr->regs[RTC_REGC] |= REGC_IRQF; - } - } + timer_update_irq(nvr); } + /* Schedule the end of the update. */ + local->ecount = 1984ULL * TIMER_USEC; + timer_set_delay_u64(&local->update_timer, local->ecount); + } else { /* * The flag and interrupt should be issued * on update ended, not started. */ nvr->regs[RTC_REGC] |= REGC_UF; - if (nvr->regs[RTC_REGB] & REGB_UIE) { - /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { - picintlevel(1 << nvr->irq); - nvr->regs[RTC_REGC] |= REGC_IRQF; - } - } + timer_update_irq(nvr); + + /* Clear update status. */ + local->stat = 0x00; + + local->ecount = 0LL; } } @@ -511,20 +534,14 @@ timer_load_count(nvr_t *nvr) static void timer_intr(void *priv) { - nvr_t *nvr = (nvr_t *) priv; - local_t *local = (local_t *) nvr->data; + nvr_t *nvr = (nvr_t *) priv; + const local_t *local = (local_t *) nvr->data; if (local->state == 1) { timer_load_count(nvr); nvr->regs[RTC_REGC] |= REGC_PF; - if (nvr->regs[RTC_REGB] & REGB_PIE) { - /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { - picintlevel(1 << nvr->irq); - nvr->regs[RTC_REGC] |= REGC_IRQF; - } - } + timer_update_irq(nvr); } } @@ -534,15 +551,14 @@ timer_tick(nvr_t *nvr) { local_t *local = (local_t *) nvr->data; - /* Only update it there is no SET in progress. */ - if (!(nvr->regs[RTC_REGB] & REGB_SET)) { + /* Only update it there is no SET in progress. + Also avoid updating it is DV2-DV0 are not set to 0, 1, 0. */ + if (((nvr->regs[RTC_REGA] & 0x70) == 0x20) && !(nvr->regs[RTC_REGB] & REGB_SET)) { /* Set the UIP bit, announcing the update. */ local->stat = REGA_UIP; - rtc_tick(); - /* Schedule the actual update. */ - local->ecount = (244ULL + 1984ULL) * TIMER_USEC; + local->ecount = 244ULL * TIMER_USEC; timer_set_delay_u64(&local->update_timer, local->ecount); } } @@ -550,6 +566,8 @@ timer_tick(nvr_t *nvr) static void nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) { + if (local->lock[reg]) + return; if ((reg == 0x2c) && (local->flags & FLAG_AMI_1994_HACK)) nvr->is_new = 0; if ((reg == 0x2d) && (local->flags & FLAG_AMI_1992_HACK)) @@ -560,11 +578,10 @@ nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) return; if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) return; - if (local->lock[reg]) - return; if (nvr->regs[reg] != val) { nvr->regs[reg] = val; - nvr_dosave = 1; + if ((reg >= 0x0d) && ((local->cent == 0xff) || (reg != local->cent))) + nvr_dosave = 1; } } @@ -576,32 +593,29 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) local_t *local = (local_t *) nvr->data; struct tm tm; uint8_t old; - uint8_t irq = 0; - uint8_t old_irq = 0; old = nvr->regs[reg]; switch (reg) { + case RTC_SECONDS: /* bit 7 of seconds is read-only */ + nvr_reg_common_write(reg, val & 0x7f, nvr, local); + break; + case RTC_REGA: - nvr->regs[RTC_REGA] = val; - timer_load_count(nvr); + if ((val & nvr->regs[RTC_REGA]) & ~REGA_UIP) { + nvr->regs[RTC_REGA] = (nvr->regs[RTC_REGA] & REGA_UIP) | (val & ~REGA_UIP); + timer_load_count(nvr); + } break; case RTC_REGB: - old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; - nvr->regs[RTC_REGB] = val; if (((old ^ val) & REGB_SET) && (val & REGB_SET)) { /* According to the datasheet... */ - nvr->regs[RTC_REGA] &= ~REGA_UIP; - nvr->regs[RTC_REGB] &= ~REGB_UIE; - } - irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; - if (old_irq && !irq) { - picintc(1 << nvr->irq); - nvr->regs[RTC_REGC] &= ~REGC_IRQF; - } else if (!old_irq && irq) { - picintlevel(1 << nvr->irq); - nvr->regs[RTC_REGC] |= REGC_IRQF; + val &= ~REGB_UIE; + local->stat &= ~REGA_UIP; } + + nvr->regs[RTC_REGB] = val; + timer_update_irq(nvr); break; case RTC_REGC: /* R/O */ @@ -630,7 +644,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) /* Update internal clock. */ time_get(nvr, &tm); nvr_time_set(&tm); - nvr_dosave = 1; + // nvr_dosave = 1; } } } @@ -650,15 +664,20 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) return; if (addr & 1) { - // if (local->bank[addr_id] == 0xff) - // return; +#if 0 + if (local->bank[addr_id] == 0xff) + return; +#endif nvr_reg_write(local->addr[addr_id], val, priv); } else { local->addr[addr_id] = (val & (nvr->size - 1)); /* Some chipsets use a 256 byte NVRAM but ports 70h and 71h always access only 128 bytes. */ - if (addr_id == 0x0) + if (addr_id == 0x0) { local->addr[addr_id] &= 0x7f; - else if ((addr_id == 0x1) && (local->flags & FLAG_PIIX4)) + /* Needed for OPTi 82C601/82C602 and NSC PC87306. */ + if (local->flags & FLAG_MULTI_BANK) + local->addr[addr_id] |= (0x80 * local->bank[addr_id]); + } else if ((addr_id == 0x1) && (local->flags & FLAG_PIIX4)) local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | 0x80; if (local->bank[addr_id] > 0) local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | (0x80 * local->bank[addr_id]); @@ -667,16 +686,29 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) } } +/* Get the NVR register index (used for APC). */ +uint8_t +nvr_get_index(void *priv, uint8_t addr_id) +{ + nvr_t *nvr = (nvr_t *) priv; + local_t *local = (local_t *) nvr->data; + uint8_t ret; + + ret = local->addr[addr_id]; + + return ret; +} + /* Read from one of the NVR registers. */ static uint8_t nvr_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; - local_t *local = (local_t *) nvr->data; - uint8_t ret; - uint8_t addr_id = (addr & 0x0e) >> 1; - uint16_t i; - uint16_t checksum = 0x0000; + nvr_t *nvr = (nvr_t *) priv; + const local_t *local = (local_t *) nvr->data; + uint8_t ret = 0xff; + uint8_t addr_id = (addr & 0x0e) >> 1; + uint16_t i; + uint16_t checksum = 0x0000; cycles -= ISA_CYCLES(8); @@ -689,9 +721,9 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGC: - ret = nvr->regs[RTC_REGC]; - picintc(1 << nvr->irq); - nvr->regs[RTC_REGC] = 0x00; + ret = nvr->regs[RTC_REGC] & (REGC_IRQF | REGC_PF | REGC_AF | REGC_UF); + nvr->regs[RTC_REGC] &= ~(REGC_IRQF | REGC_PF | REGC_AF | REGC_UF); + timer_update_irq(nvr); break; case RTC_REGD: @@ -791,7 +823,8 @@ nvr_read(uint16_t addr, void *priv) break; default: - ret = nvr->regs[local->addr[addr_id]]; + if (!(local->lock[local->addr[addr_id]] & 0x02)) + ret = nvr->regs[local->addr[addr_id]]; break; } else { @@ -823,9 +856,11 @@ nvr_sec_read(uint16_t addr, void *priv) static void nvr_reset(nvr_t *nvr) { - local_t *local = (local_t *) nvr->data; + const local_t *local = (local_t *) nvr->data; - /* memset(nvr->regs, local->def, RTC_REGS); */ +#if 0 + memset(nvr->regs, local->def, RTC_REGS); +#endif memset(nvr->regs, local->def, nvr->size); nvr->regs[RTC_DOM] = 1; nvr->regs[RTC_MONTH] = 1; @@ -840,7 +875,7 @@ nvr_reset(nvr_t *nvr) static void nvr_start(nvr_t *nvr) { - local_t *local = (local_t *) nvr->data; + const local_t *local = (local_t *) nvr->data; struct tm tm; int default_found = 0; @@ -910,6 +945,17 @@ nvr_at_index_read_handler(int set, uint16_t base, nvr_t *nvr) } } +void +nvr_at_data_port(int set, nvr_t *nvr) +{ + io_handler(0, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); + + if (set) + io_handler(1, 0x71, 1, + nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr); +} + void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr) { @@ -967,6 +1013,33 @@ nvr_irq_set(int irq, nvr_t *nvr) nvr->irq = irq; } +void +nvr_smi_enable(int enable, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->smi_enable = enable; + + if (!enable) + local->smi_status = 0; +} + +uint8_t +nvr_smi_status(nvr_t *nvr) +{ + const local_t *local = (local_t *) nvr->data; + + return local->smi_status; +} + +void +nvr_smi_status_clear(nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->smi_status = 0; +} + static void nvr_at_reset(void *priv) { @@ -1065,8 +1138,17 @@ nvr_at_init(const device_t *info) nvr->irq = -1; local->cent = RTC_CENTURY_ELT; break; + + default: + break; } + if (info->local & 0x20) + local->def = 0x00; + + if (info->local & 0x40) + local->flags |= FLAG_MULTI_BANK; + local->read_addr = 1; /* Set up any local handlers here. */ @@ -1161,6 +1243,20 @@ const device_t at_nvr_device = { .config = NULL }; +const device_t at_mb_nvr_device = { + .name = "PC/AT NVRAM", + .internal_name = "at_nvr", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0x40 | 0x20 | 1, + .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 ps_nvr_device = { .name = "PS/1 or PS/2 NVRAM", .internal_name = "ps_nvr", diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index dd87cbb80b..67eaccc386 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -49,7 +49,7 @@ #include <86box/nvr_ps2.h> #include <86box/rom.h> -typedef struct { +typedef struct ps2_nvr_t { int addr; uint8_t *ram; @@ -61,8 +61,8 @@ typedef struct { static uint8_t ps2_nvr_read(uint16_t port, void *priv) { - ps2_nvr_t *nvr = (ps2_nvr_t *) priv; - uint8_t ret = 0xff; + const ps2_nvr_t *nvr = (ps2_nvr_t *) priv; + uint8_t ret = 0xff; switch (port) { case 0x74: @@ -76,6 +76,9 @@ ps2_nvr_read(uint16_t port, void *priv) case 0x76: ret = nvr->ram[nvr->addr]; break; + + default: + break; } return ret; @@ -98,6 +101,9 @@ ps2_nvr_write(uint16_t port, uint8_t val, void *priv) case 0x76: nvr->ram[nvr->addr] = val; break; + + default: + break; } } @@ -105,7 +111,7 @@ static void * ps2_nvr_init(const device_t *info) { ps2_nvr_t *nvr; - FILE *f = NULL; + FILE *fp = NULL; int c; nvr = (ps2_nvr_t *) malloc(sizeof(ps2_nvr_t)); @@ -124,14 +130,14 @@ ps2_nvr_init(const device_t *info) io_sethandler(0x0074, 3, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); - f = nvr_fopen(nvr->fn, "rb"); + fp = nvr_fopen(nvr->fn, "rb"); nvr->ram = (uint8_t *) malloc(nvr->size); memset(nvr->ram, 0xff, nvr->size); - if (f != NULL) { - if (fread(nvr->ram, 1, nvr->size, f) != nvr->size) + if (fp != NULL) { + if (fread(nvr->ram, 1, nvr->size, fp) != nvr->size) fatal("ps2_nvr_init(): Error reading EEPROM data\n"); - fclose(f); + fclose(fp); } return nvr; @@ -141,13 +147,13 @@ static void ps2_nvr_close(void *priv) { ps2_nvr_t *nvr = (ps2_nvr_t *) priv; - FILE *f = NULL; + FILE *fp = NULL; - f = nvr_fopen(nvr->fn, "wb"); + fp = nvr_fopen(nvr->fn, "wb"); - if (f != NULL) { - (void) fwrite(nvr->ram, nvr->size, 1, f); - fclose(f); + if (fp != NULL) { + (void) fwrite(nvr->ram, nvr->size, 1, fp); + fclose(fp); } if (nvr->ram != NULL) diff --git a/src/pci.c b/src/pci.c index 5b6a401381..15a119cb7f 100644 --- a/src/pci.c +++ b/src/pci.c @@ -11,12 +11,8 @@ * * * Authors: Miran Grca, - * Fred N. van Kempen, - * Sarah Walker, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2008-2020 Sarah Walker. + * Copyright 2023 Miran Grca. */ #include #include @@ -34,50 +30,71 @@ #include <86box/dma.h> #include <86box/pci.h> #include <86box/keyboard.h> +#include <86box/plat_unused.h> -typedef struct { - uint8_t bus, id, type; - uint8_t irq_routing[4]; +#define PCI_ENABLED 0x80000000 - void *priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); +typedef struct pci_card_t { + uint8_t bus; + uint8_t id; + uint8_t type; + 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); } pci_card_t; -typedef struct { - uint8_t enabled; - uint8_t irq_line; +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); + uint8_t *slot; +} pci_card_desc_t; + +typedef struct pci_mirq_t { + uint8_t enabled; + uint8_t irq_line; + uint8_t irq_level; + uint8_t pad; } pci_mirq_t; -int pci_burst_time; -int agp_burst_time; -int pci_nonburst_time; -int agp_nonburst_time; - -static pci_card_t pci_cards[32]; -static uint8_t pci_pmc = 0; -static uint8_t last_pci_card = 0; -static uint8_t last_normal_pci_card = 0; -static uint8_t last_pci_bus = 1; -static uint8_t pci_card_to_slot_mapping[256][32]; -static uint8_t pci_bus_number_to_index_mapping[256]; -static uint8_t pci_irqs[16]; -static uint8_t pci_irq_level[16]; -static uint64_t pci_irq_hold[16]; -static pci_mirq_t pci_mirqs[8]; -static int pci_type; -static int pci_switch; -static int pci_index; -static int pci_func; -static int pci_card; -static int pci_bus; -static int pci_enable; -static int pci_key; -static int trc_reg = 0; -static uint32_t pci_base = 0xc000; -static uint32_t pci_size = 0x1000; - -static void pci_reset_regs(void); +int pci_burst_time; +int agp_burst_time; +int pci_nonburst_time; +int agp_nonburst_time; + +int pci_flags; + +uint32_t pci_base = 0xc000; +uint32_t pci_size = 0x1000; + +static pci_card_t pci_cards[PCI_CARDS_NUM]; +static pci_card_desc_t pci_card_descs[PCI_CARDS_NUM]; +static uint8_t pci_pmc = 0; +static uint8_t last_pci_card = 0; +static uint8_t last_normal_pci_card = 0; +static uint8_t last_normal_pci_card_id = 0; +static uint8_t last_pci_bus = 1; +static uint8_t next_pci_card = 0; +static uint8_t normal_pci_cards = 0; +static uint8_t next_normal_pci_card = 0; +static uint8_t pci_card_to_slot_mapping[256][PCI_CARDS_NUM]; +static uint8_t pci_bus_number_to_index_mapping[256]; +static uint8_t pci_irqs[PCI_IRQS_NUM]; +static uint8_t pci_irq_level[PCI_IRQS_NUM]; +static uint64_t pci_irq_hold[PCI_IRQS_NUM]; +static pci_mirq_t pci_mirqs[PCI_MIRQS_NUM]; +static int pci_index; +static int pci_func; +static int pci_card; +static int pci_bus; +static int pci_key; +static int pci_trc_reg = 0; +static uint32 pci_enable = 0x00000000; + +static void pci_reset_regs(void); #ifdef ENABLE_PCI_LOG int pci_do_log = ENABLE_PCI_LOG; @@ -97,738 +114,242 @@ pci_log(const char *fmt, ...) # define pci_log(fmt, ...) #endif -static void -pci_clear_slot(int card) +void +pci_set_irq_routing(int pci_int, int irq) { - pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = 0xff; - - pci_cards[card].id = 0xff; - pci_cards[card].type = 0xff; - - for (uint8_t i = 0; i < 4; i++) - pci_cards[card].irq_routing[i] = 0; - - pci_cards[card].read = NULL; - pci_cards[card].write = NULL; - pci_cards[card].priv = NULL; + pci_irqs[pci_int - 1] = irq; } void -pci_relocate_slot(int type, int new_slot) +pci_set_irq_level(int pci_int, int level) { - int card = -1; - int old_slot; - uint8_t mapping; - - if ((new_slot < 0) || (new_slot > 31)) - return; - - for (uint8_t i = 0; i < 32; i++) { - if ((pci_cards[i].bus == 0) && (pci_cards[i].type == type)) { - card = i; - break; - } - } - - if (card == -1) - return; - - old_slot = pci_cards[card].id; - pci_cards[card].id = new_slot; - mapping = pci_card_to_slot_mapping[0][old_slot]; - pci_card_to_slot_mapping[0][old_slot] = 0xff; - pci_card_to_slot_mapping[0][new_slot] = mapping; + pci_irq_level[pci_int - 1] = !!level; } -static void -pci_cf8_write(uint16_t port, uint32_t val, void *priv) +void +pci_enable_mirq(int mirq) { - pci_log("cf8 write: %08X\n", val); - pci_index = val & 0xff; - pci_func = (val >> 8) & 7; - pci_card = (val >> 11) & 31; - pci_bus = (val >> 16) & 0xff; - pci_enable = (val >> 31) & 1; + pci_mirqs[mirq].enabled = 1; } -static uint32_t -pci_cf8_read(uint16_t port, void *priv) +void +pci_set_mirq_routing(int mirq, uint8_t irq) { - return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); + pci_mirqs[mirq].irq_line = irq; } -static void -pci_write(uint16_t port, uint8_t val, void *priv) +uint8_t +pci_get_mirq_level(int mirq) { - uint8_t slot = 0; - - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; - - pci_log("Writing %02X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - - break; - } + return pci_mirqs[mirq].irq_level; } -static void -pci_writew(uint16_t port, uint16_t val, void *priv) +void +pci_set_mirq_level(int mirq, uint8_t level) { - uint8_t slot = 0; - - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; - - pci_log("Writing %04X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 1), val >> 8, pci_cards[slot].priv); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - - break; - } + pci_mirqs[mirq].irq_level = level; } -static void -pci_writel(uint16_t port, uint32_t val, void *priv) +/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE + and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's + hack that may no longer be needed). */ +void +pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) { - uint8_t slot = 0; + uint8_t irq_routing = 0; + uint8_t pci_int_index = pci_int - PCI_INTA; + uint8_t irq_line = 0; + uint8_t is_vfio = 0; - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + /* The fast path out an invalid PCI card. */ + if (slot == PCI_CARD_INVALID) + return; - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) + switch (slot) { + default: + return; + + case 0x00 ... PCI_CARD_MAX: + /* PCI card. */ + if (!last_pci_card) return; - pci_log("Writing %08X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 1), (val >> 8) & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 2), (val >> 16) & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 3), (val >> 24) & 0xff, pci_cards[slot].priv); + if (pci_flags & FLAG_NO_IRQ_STEERING) + irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); + else { + irq_routing = pci_cards[slot].irq_routing[pci_int_index]; + + switch (irq_routing) { + default: + case 0x00: + return; + + case 0x01 ... PCI_IRQS_NUM: + is_vfio = pci_cards[slot].type & PCI_CARD_VFIO; + irq_routing = (irq_routing - PCI_INTA) & PCI_IRQ_MAX; + + irq_line = pci_irqs[irq_routing]; + /* Ignore what was provided to us as a parameter and override it with whatever + the chipset is set to. */ + level = !!pci_irq_level[irq_routing]; + if (level && is_vfio) + level--; + break; + + /* Sometimes, PCI devices are mapped to direct IRQ's. */ + case (PCI_DIRQ_BASE | 0x00) ... (PCI_DIRQ_BASE | PCI_DIRQ_MAX): + /* Direct IRQ line, always edge-triggered. */ + irq_line = slot & PCI_IRQ_MAX; + break; } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - break; - } -} + case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): + /* MIRQ */ + slot &= PCI_MIRQ_MAX; -static uint8_t -pci_read(uint16_t port, void *priv) -{ - uint8_t slot = 0; - uint8_t ret = 0xff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } - - pci_log("Reading %02X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -static uint16_t -pci_readw(uint16_t port, void *priv) -{ - uint8_t slot = 0; - uint16_t ret = 0xffff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) { - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 1, pci_cards[slot].priv) << 8); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } - - pci_log("Reading %04X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -static uint32_t -pci_readl(uint16_t port, void *priv) -{ - uint8_t slot = 0; - uint32_t ret = 0xffffffff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); + if (!pci_mirqs[slot].enabled) + return; - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) { - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 1, pci_cards[slot].priv) << 8); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 2, pci_cards[slot].priv) << 16); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 3, pci_cards[slot].priv) << 24); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif + irq_line = pci_mirqs[slot].irq_line; + break; + case (PCI_DIRQ_BASE | 0x00) ... (PCI_DIRQ_BASE | PCI_DIRQ_MAX): + /* Direct IRQ line (RichardG's ACPI workaround, may no longer be needed). */ + irq_line = slot & PCI_IRQ_MAX; + break; } - pci_log("Reading %08X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -static void pci_type2_write(uint16_t port, uint8_t val, void *priv); -static uint8_t pci_type2_read(uint16_t port, void *priv); - -void -pci_set_pmc(uint8_t pmc) -{ - pci_log("pci_set_pmc(%02X)\n", pmc); - // pci_reset_regs(); - - if (!pci_pmc && (pmc & 0x01)) { - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - - io_removehandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - } else if (pci_pmc && !(pmc & 0x01)) { - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - if (pci_key) { - io_sethandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - } - - io_removehandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - } + if (irq_line > PCI_IRQ_MAX) + return; - pci_pmc = (pmc & 0x01); + picint_common(1 << irq_line, level, set, irq_state); } -static void -pci_type2_write(uint16_t port, uint8_t val, void *priv) +uint8_t +pci_get_int(uint8_t slot, uint8_t pci_int) { - uint8_t slot = 0; - - if (port == 0xcf8) { - pci_func = (val >> 1) & 7; - - if (!pci_key && (val & 0xf0)) { - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - io_sethandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - } else if (pci_key && !(val & 0xf0)) - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - - pci_key = val & 0xf0; - } else if (port == 0xcfa) { - pci_bus = val; - - pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - - /* Evidently, writing here, we should also enable the - configuration space. */ - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - io_sethandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); - - /* Mark as enabled. */ - pci_key |= 0x100; - } else if (port == 0xcfb) { - pci_log("Write %02X to port 0CFB\n", val); - pci_set_pmc(val); - } else { - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } + return pci_cards[slot].irq_routing[pci_int - PCI_INTA]; } static void -pci_type2_writel(uint16_t port, uint32_t val, void *priv) -{ - for (uint8_t i = 0; i < 4; i++) { - /* Make sure to have the DWORD write not pass through to PMC if mechanism 1 is in use, - as otherwise, the PCI enable bits clobber it. */ - if (!pci_pmc || ((port + i) != 0x0cfb)) - pci_type2_write(port + i, val >> 8, priv); - } -} - -static uint8_t -pci_type2_read(uint16_t port, void *priv) -{ - uint8_t slot = 0; - uint8_t ret = 0xff; - - if (port == 0xcf8) - ret = pci_key | (pci_func << 1); - else if (port == 0xcfa) - ret = pci_bus; - else if (port == 0xcfb) - ret = pci_pmc; - else { - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - - pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func); - } - - return ret; -} - -void -pci_set_irq_routing(int pci_int, int irq) +pci_clear_slot(int card) { - pci_irqs[pci_int - 1] = irq; -} + pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = PCI_CARD_INVALID; -void -pci_set_irq_level(int pci_int, int level) -{ - pci_irq_level[pci_int - 1] = !!level; -} + pci_cards[card].id = 0xff; + pci_cards[card].type = 0xff; -void -pci_enable_mirq(int mirq) -{ - pci_mirqs[mirq].enabled = 1; -} + for (uint8_t i = 0; i < 4; i++) + pci_cards[card].irq_routing[i] = 0; -void -pci_set_mirq_routing(int mirq, int irq) -{ - pci_mirqs[mirq].irq_line = irq; + pci_cards[card].read = NULL; + pci_cards[card].write = NULL; + pci_cards[card].priv = NULL; } +/* Relocate a PCI device to a new slot, required for the configurable + IDSEL's of ALi M1543(c). */ void -pci_set_mirq(uint8_t mirq, int level) +pci_relocate_slot(int type, int new_slot) { - uint8_t irq_line = 0; - uint8_t irq_bit; + int card = -1; + int old_slot; - if (mirq >= 0xf0) { - irq_line = mirq & 0x0f; - irq_bit = 0x1D; - } else { - if (!pci_mirqs[mirq].enabled) { - pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } + if ((new_slot < 0) || (new_slot > 31)) + return; - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); - return; + for (uint8_t i = 0; i < PCI_CARDS_NUM; i++) { + if ((pci_cards[i].bus == 0) && (pci_cards[i].type == type)) { + card = i; + break; } - - irq_line = pci_mirqs[mirq].irq_line; - irq_bit = (0x1E + mirq); } - pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - if (level && (pci_irq_hold[irq_line] & (1ULL << irq_bit))) { - /* IRQ already held, do nothing. */ - pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq); - picintlevel(1 << irq_line); + if (card == -1) return; - } - pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq); - - if (!level || !pci_irq_hold[irq_line]) { - pci_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - if (level) - picintlevel(1 << irq_line); - else - picint(1 << irq_line); - } else if (level && pci_irq_hold[irq_line]) { - pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq); - picintlevel(1 << irq_line); - } + old_slot = pci_cards[card].id; + pci_cards[card].id = new_slot; - /* If the IRQ is level-triggered, mark that this MIRQ is holding it. */ - if (level) { - pci_log("pci_set_mirq(%02X): Marking that this card is holding the IRQ\n", mirq); - pci_irq_hold[irq_line] |= (1ULL << irq_bit); - } + if (pci_card_to_slot_mapping[0][old_slot] == card) + pci_card_to_slot_mapping[0][old_slot] = PCI_CARD_INVALID; - pci_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq); + if (pci_card_to_slot_mapping[0][new_slot] == PCI_CARD_INVALID) + pci_card_to_slot_mapping[0][new_slot] = card; } +/* Write PCI enable/disable key, split for the ALi M1435. */ void -pci_set_irq(uint8_t card, uint8_t pci_int) +pci_key_write(uint8_t val) { - uint8_t slot = 0; - uint8_t irq_routing = 0; - uint8_t pci_int_index = pci_int - PCI_INTA; - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!last_pci_card) { - pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); - return; - } - pci_log("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - - slot = card; - if (slot == 0xff) { - pci_log("pci_set_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - pci_log("pci_set_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - - if (!pci_cards[slot].irq_routing[pci_int_index]) { - pci_log("pci_set_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - - if (pci_type & PCI_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); - else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; - pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - - irq_line = pci_irqs[irq_routing]; - level = pci_irq_level[irq_routing]; - } - - if (irq_line > 0x0f) { - pci_log("pci_set_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } else - pci_log("pci_set_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); + pci_key = val & 0xf0; - if (level && (pci_irq_hold[irq_line] & (1ULL << slot))) { - /* IRQ already held, do nothing. */ - pci_log("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int); - picintlevel(1 << irq_line); - return; - } - pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int); - - if (!level || !pci_irq_hold[irq_line]) { - pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - if (level) - picintlevel(1 << irq_line); - else - picint(1 << irq_line); - } else if (level && pci_irq_hold[irq_line]) { - pci_log("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int); - picintlevel(1 << irq_line); - } - - /* If the IRQ is level-triggered, mark that this card is holding it. */ - if (level) { - pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] |= (1ULL << slot); - } else { - pci_log("pci_set_irq(%02X, %02X): Edge-triggered interrupt, not marking\n", card, pci_int); - } + if (pci_key) + pci_flags |= FLAG_CONFIG_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_IO_ON; } -void -pci_clear_mirq(uint8_t mirq, int level) +static void +pci_io_handlers(int set) { - uint8_t irq_line = 0; - uint8_t irq_bit; + io_handler(set, 0x0cf8, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - if (mirq >= 0xf0) { - irq_line = mirq & 0x0f; - irq_bit = 0x1D; - } else { - if (mirq > 1) { - pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); - return; - } + if (pci_flags & FLAG_MECHANISM_1) + io_handler(set, 0x0cfc, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - if (!pci_mirqs[mirq].enabled) { - pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } - - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - - irq_line = pci_mirqs[mirq].irq_line; - irq_bit = (0x1E + mirq); - } - pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - - if (level && !(pci_irq_hold[irq_line] & (1ULL << irq_bit))) { - /* IRQ not held, do nothing. */ - pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq); - return; - } - - if (level) { - pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq); - pci_irq_hold[irq_line] &= ~(1 << irq_bit); - - if (!pci_irq_hold[irq_line]) { - pci_log("pci_clear_mirq(%02X): IRQ no longer held by any card, clearing it\n", mirq); - picintc(1 << irq_line); - } else { - pci_log("pci_clear_mirq(%02X): IRQ is still being held\n", mirq); - } - } else { - pci_log("pci_clear_mirq(%02X): Clearing edge-triggered interrupt\n", mirq); - picintc(1 << irq_line); + if (pci_flags & FLAG_MECHANISM_2) { + if (set && pci_key) + pci_flags |= FLAG_CONFIG_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_IO_ON; } } +/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */ void -pci_clear_irq(uint8_t card, uint8_t pci_int) +pci_set_pmc(uint8_t pmc) { - uint8_t slot = 0; - uint8_t irq_routing = 0; - uint8_t pci_int_index = pci_int - PCI_INTA; - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!last_pci_card) { - // pci_log("pci_clear_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); - return; - } - // pci_log("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - - slot = card; - if (slot == 0xff) { - // pci_log("pci_clear_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - // pci_log("pci_clear_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - - if (!pci_cards[slot].irq_routing[pci_int_index]) { - // pci_log("pci_clear_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - - if (pci_type & PCI_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); - else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; - // pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - - irq_line = pci_irqs[irq_routing]; - level = pci_irq_level[irq_routing]; - } - - if (irq_line > 0x0f) { - // pci_log("pci_clear_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } + pci_log("pci_set_pmc(%02X)\n", pmc); - // pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); + pci_io_handlers(0); - if (level && !(pci_irq_hold[irq_line] & (1ULL << slot))) { - /* IRQ not held, do nothing. */ - // pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int); - return; - } + pci_flags &= ~FLAG_MECHANISM_MASK; + pci_flags |= (FLAG_MECHANISM_1 + !(pmc & 0x01)); - if (level) { - // pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] &= ~(1 << slot); + pci_io_handlers(1); - if (!pci_irq_hold[irq_line]) { - // pci_log("pci_clear_irq(%02X, %02X): IRQ no longer held by any card, clearing it\n", card, pci_int); - picintc(1 << irq_line); - } // else { - // pci_log("pci_clear_irq(%02X, %02X): IRQ is still being held\n", card, pci_int); - // } - } else { - // pci_log("pci_clear_irq(%02X, %02X): Clearing edge-triggered interrupt\n", card, pci_int); - picintc(1 << irq_line); - } + pci_pmc = (pmc & 0x01); } -uint8_t -pci_get_int(uint8_t slot, uint8_t pci_int) +static void +pci_reg_write(uint16_t port, uint8_t val) { - return pci_cards[slot].irq_routing[pci_int - PCI_INTA]; + uint8_t slot = 0; + + if (port >= 0xc000) { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xfc; + } + + 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_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %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); } static void pci_reset_regs(void) { pci_index = pci_card = pci_func = pci_bus = pci_key = 0; + pci_enable = 0x00000000; - io_removehandler(pci_base, pci_size, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); + pci_flags &= ~(FLAG_CONFIG_IO_ON | FLAG_CONFIG_M1_IO_ON); } void @@ -843,7 +364,7 @@ pci_reset_hard(void) { pci_reset_regs(); - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < PCI_IRQS_NUM; i++) { if (pci_irq_hold[i]) { pci_irq_hold[i] = 0; @@ -857,67 +378,16 @@ pci_reset_hard(void) void pci_reset(void) { - if (pci_switch) { + if (pci_flags & FLAG_MECHANISM_SWITCH) { pci_log("pci_reset(): Switchable configuration mechanism\n"); - pci_pmc = 0x00; - - io_removehandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_removehandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - io_removehandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); + pci_set_pmc(0x00); } pci_reset_hard(); } static void -pci_slots_clear(void) -{ - uint8_t i; - last_pci_card = last_normal_pci_card = 0; - last_pci_bus = 1; - - for (i = 0; i < 32; i++) - pci_clear_slot(i); - - i = 0; - do { - for (uint8_t j = 0; j < 32; j++) - pci_card_to_slot_mapping[i][j] = 0xff; - pci_bus_number_to_index_mapping[i] = 0xff; - } while (i++ < 0xff); - - pci_bus_number_to_index_mapping[0] = 0; /* always map bus 0 to index 0 */ -} - -uint32_t -trc_readl(uint16_t port, void *priv) -{ - return 0xffffffff; -} - -uint16_t -trc_readw(uint16_t port, void *priv) -{ - return 0xffff; -} - -uint8_t -trc_read(uint16_t port, void *priv) -{ - return trc_reg & 0xfb; -} - -static void -trc_reset(uint8_t val) +pci_trc_reset(uint8_t val) { if (val & 2) { dma_reset(); @@ -939,108 +409,262 @@ trc_reset(uint8_t val) } void -trc_writel(uint16_t port, uint32_t val, void *priv) +pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { + pci_log("PCI: [WB] Mechanism #%i port %04X = %02X\n", ((port >= 0xcfc) && (port <= 0xcff)) ? 1 : 2, port, val); + + switch (port) { + case 0xcf8: + if (pci_flags & FLAG_MECHANISM_2) { + pci_func = (val >> 1) & 7; + pci_key_write(val); + + pci_log("PCI: Mechanism #2 CF8: %sllocating ports %04X-%04X...\n", (pci_flags & FLAG_CONFIG_IO_ON) ? "A" : "Dea", + pci_base, pci_base + pci_size - 1); + } + break; + case 0xcf9: + if (pci_flags & FLAG_TRC_CONTROLS_CPURST) + cpu_cpurst_on_sr = !(val & 0x10); + + if (!(pci_trc_reg & 4) && (val & 4)) + pci_trc_reset(val); + + pci_trc_reg = val & 0xfd; + + if (val & 2) + pci_trc_reg &= 0xfb; + break; + case 0xcfa: + if (pci_flags & FLAG_MECHANISM_2) + pci_bus = val; + break; + case 0xcfb: + if (pci_flags & FLAG_MECHANISM_SWITCH) + pci_set_pmc(val); + break; + + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if ((pci_flags & FLAG_MECHANISM_1) && (pci_flags & FLAG_CONFIG_M1_IO_ON)) + pci_reg_write(port, val); + break; + + case 0xc000 ... 0xc0ff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & (FLAG_CONFIG_IO_ON | FLAG_CONFIG_DEV0_IO_ON))) + pci_reg_write(port, val); + break; + + case 0xc100 ... 0xcfff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_IO_ON)) + pci_reg_write(port, val); + break; + + default: + break; + } } void -trc_writew(uint16_t port, uint16_t val, void *priv) +pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) { + if (port & 0x0001) { + /* Non-aligned access, split into two byte accesses. */ + pci_write(port, val & 0xff, priv); + pci_write(port + 1, val >> 8, priv); + } else { + /* Aligned access, still split because we cheat. */ + switch (port) { + case 0xcfc: + case 0xcfe: + case 0xc000 ... 0xcffe: + pci_write(port, val & 0xff, priv); + pci_write(port + 1, val >> 8, priv); + break; + + default: + break; + } + } } void -trc_write(uint16_t port, uint8_t val, void *priv) +pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) { - pci_log("TRC Write: %02X\n", val); - - if (!(trc_reg & 4) && (val & 4)) - trc_reset(val); - - trc_reg = val & 0xfd; - - if (val & 2) - trc_reg &= 0xfb; + if (port & 0x0003) { + /* Non-aligned access, split into two word accesses. */ + pci_writew(port, val & 0xffff, priv); + pci_writew(port + 2, val >> 16, priv); + } else { + /* Aligned access. */ + switch (port) { + case 0xcf8: + /* No split here, actual 32-bit access. */ + if (pci_flags & FLAG_MECHANISM_1) { + pci_log("PCI: [WL] Mechanism #1 port 0CF8 = %08X\n", val); + + pci_index = val & 0xff; + pci_func = (val >> 8) & 7; + pci_card = (val >> 11) & 31; + pci_bus = (val >> 16) & 0xff; + pci_enable = (val & PCI_ENABLED); + + if (pci_enable) + pci_flags |= FLAG_CONFIG_M1_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_M1_IO_ON; + break; + } + break; + case 0xcfc: + case 0xc000 ... 0xcffc: + /* Still split because we cheat. */ + pci_writew(port, val & 0xffff, priv); + pci_writew(port + 2, val >> 16, priv); + break; + + default: + break; + } + } } -void -trc_init(void) +static uint8_t +pci_reg_read(uint16_t port) { - trc_reg = 0; + uint8_t slot = 0; + uint8_t ret = 0xff; + + if (port >= 0xc000) { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xfc; + } + + 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); + } + pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %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); - io_sethandler(0x0cf9, 0x0001, - trc_read, trc_readw, trc_readl, trc_write, trc_writew, trc_writel, NULL); + return ret; } -void -pci_init(int type) +uint8_t +pci_read(uint16_t port, UNUSED(void *priv)) { - int c; + uint8_t ret = 0xff; - pci_base = 0xc000; - pci_size = 0x1000; + switch (port) { + case 0xcf8: + if (pci_flags & FLAG_MECHANISM_2) + ret = pci_key | (pci_func << 1); + break; + case 0xcf9: + ret = pci_trc_reg & 0xfb; + break; + case 0xcfa: + if (pci_flags & FLAG_MECHANISM_2) + ret = pci_bus; + break; + case 0xcfb: + if (pci_flags & FLAG_MECHANISM_SWITCH) + ret = pci_pmc; + break; - pci_slots_clear(); + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if ((pci_flags & FLAG_MECHANISM_1) && (pci_flags & FLAG_CONFIG_M1_IO_ON)) + ret = pci_reg_read(port); + break; - pci_reset_hard(); + case 0xc000 ... 0xc0ff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & (FLAG_CONFIG_IO_ON | FLAG_CONFIG_DEV0_IO_ON))) + ret = pci_reg_read(port); + break; - trc_init(); + case 0xc100 ... 0xcfff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_IO_ON)) + ret = pci_reg_read(port); + break; - pci_type = type; - pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); + default: + break; + } - if (pci_switch) { - pci_log("PCI: Switchable configuration mechanism\n"); - pci_pmc = 0x00; + pci_log("PCI: [RB] Mechanism #%i port %04X = %02X\n", ((port >= 0xcfc) && (port <= 0xcff)) ? 1 : 2, port, ret); - io_sethandler(0x0cfb, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, pci_type2_writel, NULL); - } + return ret; +} - if (type & PCI_NO_IRQ_STEERING) { - pic_elcr_io_handler(0); - pic_elcr_set_enabled(0); - } else { - pic_elcr_io_handler(1); - pic_elcr_set_enabled(1); - } +uint16_t +pci_readw(uint16_t port, UNUSED(void *priv)) +{ + uint16_t ret = 0xffff; - if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) { - pci_log("PCI: Configuration mechanism #1\n"); - io_sethandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_sethandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - pci_pmc = 1; + if (port & 0x0001) { + /* Non-aligned access, split into two byte accesses. */ + ret = pci_read(port, priv); + ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; } else { - pci_log("PCI: Configuration mechanism #2\n"); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - pci_pmc = 0; - - if (type & PCI_ALWAYS_EXPOSE_DEV0) { - pci_log("PCI: Always expose device 0\n"); - pci_base = 0xc100; - pci_size = 0x0f00; - - io_sethandler(0xc000, 0x0100, - pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, NULL); + /* Aligned access, still split because we cheat. */ + switch (port) { + case 0xcfc: + case 0xcfe: + case 0xc000 ... 0xcffe: + ret = pci_read(port, priv); + ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; + break; + + default: + break; } } - for (c = 0; c < 4; c++) { - pci_irqs[c] = PCI_IRQ_DISABLED; - pci_irq_level[c] = (type & PCI_NO_IRQ_STEERING) ? 0 : 1; - } + return ret; +} - for (c = 0; c < 3; c++) { - pci_mirqs[c].enabled = 0; - pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; +uint32_t +pci_readl(uint16_t port, UNUSED(void *priv)) +{ + uint32_t ret = 0xffffffff; + + if (port & 0x0003) { + /* Non-aligned access, split into two word accesses. */ + ret = pci_readw(port, priv); + ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + } else { + /* Aligned access. */ + switch (port) { + case 0xcf8: + /* No split here, actual 32-bit access. */ + if (pci_flags & FLAG_MECHANISM_1) { + ret = pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16); + if (pci_flags & FLAG_CONFIG_M1_IO_ON) + ret |= PCI_ENABLED; + + pci_log("PCI: [RL] Mechanism #1 port 0CF8 = %08X\n", ret); + + return ret; + } + break; + case 0xcfc: + case 0xc000 ... 0xcffc: + /* Still split because we cheat. */ + ret = pci_readw(port, priv); + ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + break; + } } - pic_set_pci_flag(1); + return ret; } uint8_t @@ -1055,19 +679,13 @@ pci_remap_bus(uint8_t bus_index, uint8_t bus_number) uint8_t i = 1; do { if (pci_bus_number_to_index_mapping[i] == bus_index) - pci_bus_number_to_index_mapping[i] = 0xff; + pci_bus_number_to_index_mapping[i] = PCI_BUS_INVALID; } while (i++ < 0xff); if ((bus_number > 0) && (bus_number < 0xff)) pci_bus_number_to_index_mapping[bus_number] = bus_index; } -void -pci_register_slot(int card, int type, int inta, int intb, int intc, int intd) -{ - pci_register_bus_slot(0, card, type, inta, intb, intc, intd); -} - void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd) { @@ -1087,73 +705,260 @@ pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, pci_log("pci_register_slot(): pci_cards[%i].bus = %02X; .id = %02X\n", last_pci_card, bus, card); - if (type == PCI_CARD_NORMAL) - last_normal_pci_card = last_pci_card; + if (type == PCI_CARD_NORMAL) { + last_normal_pci_card++; + /* This is needed to know at what position to add the bridge. */ + last_normal_pci_card_id = last_pci_card; + } + last_pci_card++; } -uint8_t +static uint8_t pci_find_slot(uint8_t add_type, uint8_t ignore_slot) { - pci_card_t *dev; - uint8_t ret = 0xff; - - for (uint8_t i = 0; i < last_pci_card; i++) { + const pci_card_t *dev; + /* Is the device being added with a strict slot type matching requirement? */ + uint8_t strict = (add_type & PCI_ADD_STRICT); + /* The actual type of the device being added, with the strip flag, if any, + masked. */ + uint8_t masked_add_type = (add_type & PCI_ADD_MASK); + /* Is the device being added normal, ie. without the possibility of ever + being used as an on-board device? */ + uint8_t normal_add_type = (masked_add_type >= PCI_CARD_NORMAL); + uint8_t match; + uint8_t normal; + uint8_t empty; + uint8_t process; + uint8_t ret = PCI_CARD_INVALID; + + /* Iterate i until we have either exhausted all the slot or the value of + ret has changed to something other than PCI_CARD_INVALID. */ + for (uint8_t i = 0; (ret == PCI_CARD_INVALID) && (i < last_pci_card); i++) { dev = &pci_cards[i]; - if (!dev->read && !dev->write && ((ignore_slot == 0xff) || (i != ignore_slot))) { - if (add_type & PCI_ADD_STRICT) { - if (dev->type == (add_type & 0x7f)) { - ret = i; - break; - } - } else { - if (((dev->type == PCI_CARD_NORMAL) && ((add_type & 0x7f) >= PCI_ADD_NORMAL)) || (dev->type == (add_type & 0x7f))) { - ret = i; - break; - } - } - } + /* Is the slot we are looking at of the exact same type as the device being + added? */ + match = (dev->type == masked_add_type); + /* Is the slot we are looking at a normal slot (ie. not an on-board chip)? */ + normal = (dev->type == PCI_CARD_NORMAL); + /* Is the slot we are looking at empty? */ + empty = !dev->read && !dev->write; + /* Should we process this slot, ie. were we told to ignore it, if any at all? */ + process = (ignore_slot == PCI_IGNORE_NO_SLOT) || (i != ignore_slot); + + /* This condition is now refactored and made to be easily human-readable. */ + if (empty && process && (match || (!strict && normal && normal_add_type))) + ret = i; } return ret; } -uint8_t -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) +/* 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_card_desc_t *dev; + + pci_log("pci_add_card(): PCI card #%02i: type = %i\n", next_pci_card, add_type); + + if (next_pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[next_pci_card]; + + dev->type = add_type; + dev->read = read; + dev->write = write; + dev->priv = priv; + dev->slot = slot; + + *(dev->slot) = PCI_CARD_INVALID; + + next_pci_card++; + if (add_type == PCI_ADD_NORMAL) + normal_pci_cards++; + } +} + +static void +pci_clear_card(UNUSED(int pci_card)) +{ + pci_card_desc_t *dev; + + if (next_pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[next_pci_card]; + + memset(dev, 0x00, sizeof(pci_card_desc_t)); + } +} + +static uint8_t +pci_register_card(int pci_card) { - pci_card_t *dev; + pci_card_desc_t *dev; + pci_card_t *card; uint8_t i; - uint8_t j; + uint8_t ret = PCI_CARD_INVALID; + + if (pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[pci_card]; + + if (last_pci_card) { + /* First, find the next available slot. */ + i = pci_find_slot(dev->type, 0xff); + + if (i != PCI_CARD_INVALID) { + card = &pci_cards[i]; + card->read = dev->read; + card->write = dev->write; + card->priv = dev->priv; + card->type |= (dev->type & PCI_CARD_VFIO); - if (add_type < PCI_ADD_AGP) - pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); + *(dev->slot) = i; - if (!last_pci_card) { - pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); - return 0xff; + ret = i; + } + } + + pci_clear_card(pci_card); } - /* First, find the next available slot. */ - i = pci_find_slot(add_type, 0xff); + return ret; +} - if (i != 0xff) { - dev = &pci_cards[i]; - j = pci_find_slot(add_type, i); +/* Add an instance of the PCI bridge. */ +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, uint8_t *slot) +{ + pci_card_t *card; + uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id; + + if (bridge_slot != PCI_CARD_INVALID) { + card = &pci_cards[bridge_slot]; + card->read = read; + card->write = write; + card->priv = priv; + } + + *slot = bridge_slot; +} + +/* Register the cards that have been added into slots. */ +void +pci_register_cards(void) +{ + uint8_t normal; +#ifdef ENABLE_PCI_LOG + uint8_t type; + uint8_t *slot; +#endif + + next_normal_pci_card = 0; + + if (next_pci_card > 0) { + for (uint8_t i = 0; i < next_pci_card; i++) { +#ifdef ENABLE_PCI_LOG + type = pci_card_descs[i].type; + slot = pci_card_descs[i].slot; +#endif + normal = (pci_card_descs[i].type == PCI_CARD_NORMAL); + + /* If this is a normal card, increase the next normal card index. */ + if (normal) + next_normal_pci_card++; - if (!(pci_type & PCI_NO_BRIDGES) && (dev->type == PCI_CARD_NORMAL) && (add_type != PCI_ADD_BRIDGE) && (j == 0xff)) { - pci_log("pci_add_card(): Reached last NORMAL slot, adding bridge to pci_cards[%i]\n", i); - device_add_inst(&dec21150_device, last_pci_bus); - i = pci_find_slot(add_type, 0xff); - dev = &pci_cards[i]; + /* If this is a normal card and the next one is going to be beyond the last slot, + add the bridge. */ + if (normal && (next_normal_pci_card >= last_normal_pci_card) && + (normal_pci_cards > last_normal_pci_card) && !(pci_flags & FLAG_NO_BRIDGES)) + device_add_inst(&dec21150_device, last_pci_bus); + + pci_register_card(i); + pci_log("pci_register_cards(): PCI card #%02i: type = %02X, pci device = %02X:%02X\n", + i, type, pci_cards[*slot].bus, pci_cards[*slot].id); } + } - dev->read = read; - dev->write = write; - dev->priv = priv; - pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (bus %02X slot %02X) [%s]\n", i, dev->bus, dev->id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); - return i; + next_pci_card = 0; + normal_pci_cards = 0; + + next_normal_pci_card = 0; +} + +static void +pci_slots_clear(void) +{ + uint8_t i; + + last_pci_card = last_normal_pci_card = 0; + last_normal_pci_card = 0; + last_pci_bus = 1; + + next_pci_card = 0; + normal_pci_cards = 0; + + next_normal_pci_card = 0; + + for (i = 0; i < PCI_CARDS_NUM; i++) + pci_clear_slot(i); + + i = 0; + do { + for (uint8_t j = 0; j < PCI_CARDS_NUM; j++) + pci_card_to_slot_mapping[i][j] = PCI_CARD_INVALID; + pci_bus_number_to_index_mapping[i] = PCI_BUS_INVALID; + } while (i++ < 0xff); + + pci_bus_number_to_index_mapping[0] = 0; /* always map bus 0 to index 0 */ +} + +void +pci_init(int flags) +{ + int c; + + pci_base = 0xc000; + pci_size = 0x1000; + + pci_slots_clear(); + + pci_reset_hard(); + + pci_trc_reg = 0; + pci_flags = flags; + + if (pci_flags & FLAG_NO_IRQ_STEERING) { + pic_elcr_io_handler(0); + pic_elcr_set_enabled(0); + } else { + pic_elcr_io_handler(1); + pic_elcr_set_enabled(1); + } + + pci_pmc = (pci_flags & FLAG_MECHANISM_1) ? 0x01 : 0x00; + + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_DEV0_IO_ON)) { + pci_log("PCI: Always expose device 0\n"); + pci_base = 0xc100; + pci_size = 0x0f00; + } + + if (pci_flags & FLAG_MECHANISM_SWITCH) { + pci_log("PCI: Switchable configuration mechanism\n"); + pci_set_pmc(pci_pmc); + } else + pci_io_handlers(1); + + for (c = 0; c < PCI_IRQS_NUM; c++) { + pci_irqs[c] = PCI_IRQ_DISABLED; + pci_irq_level[c] = (pci_flags & FLAG_NO_IRQ_STEERING) ? 0 : 1; + } + + for (c = 0; c < PCI_MIRQS_NUM; c++) { + pci_mirqs[c].enabled = 0; + pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; } - return 0xff; + pic_set_pci_flag(1); } diff --git a/src/pci_dummy.c b/src/pci_dummy.c index b85df7ab9f..704f85d8c1 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -9,32 +9,41 @@ #include <86box/io.h> #include <86box/pci.h> #include <86box/pci_dummy.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct pci_dummy_t { uint8_t pci_regs[256]; bar_t pci_bar[2]; - uint8_t card, interrupt_on; + uint8_t pci_slot; + uint8_t irq_state; + uint8_t interrupt_on; + + uint8_t irq_level; } pci_dummy_t; static void pci_dummy_interrupt(int set, pci_dummy_t *dev) { - if (set) - pci_set_irq(dev->card, PCI_INTA); - else - pci_clear_irq(dev->card, PCI_INTA); + if (set != dev->irq_level) { + if (set) + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); + else + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); + } + + dev->irq_level = set; } static uint8_t -pci_dummy_read(uint16_t Port, void *p) +pci_dummy_read(uint16_t port, void *priv) { - pci_dummy_t *dev = (pci_dummy_t *) p; + pci_dummy_t *dev = (pci_dummy_t *) priv; uint8_t ret = 0xff; - switch (Port & 0x20) { + switch (port & 0x20) { case 0x00: ret = 0x1a; break; @@ -60,48 +69,54 @@ pci_dummy_read(uint16_t Port, void *p) dev->interrupt_on = 0; } break; + + default: + break; } return ret; } static uint16_t -pci_dummy_readw(uint16_t Port, void *p) +pci_dummy_readw(uint16_t port, void *priv) { - return pci_dummy_read(Port, p); + return pci_dummy_read(port, priv); } static uint32_t -pci_dummy_readl(uint16_t Port, void *p) +pci_dummy_readl(uint16_t port, void *priv) { - return pci_dummy_read(Port, p); + return pci_dummy_read(port, priv); } static void -pci_dummy_write(uint16_t Port, uint8_t Val, void *p) +pci_dummy_write(uint16_t port, UNUSED(uint8_t val), void *priv) { - pci_dummy_t *dev = (pci_dummy_t *) p; + pci_dummy_t *dev = (pci_dummy_t *) priv; - switch (Port & 0x20) { + switch (port & 0x20) { case 0x06: if (!dev->interrupt_on) { dev->interrupt_on = 1; pci_dummy_interrupt(1, dev); } break; + + default: + break; } } static void -pci_dummy_writew(uint16_t Port, uint16_t Val, void *p) +pci_dummy_writew(uint16_t port, uint16_t val, void *priv) { - pci_dummy_write(Port, Val & 0xFF, p); + pci_dummy_write(port, val & 0xFF, priv); } static void -pci_dummy_writel(uint16_t Port, uint32_t Val, void *p) +pci_dummy_writel(uint16_t port, uint32_t val, void *priv) { - pci_dummy_write(Port, Val & 0xFF, p); + pci_dummy_write(port, val & 0xFF, priv); } static void @@ -119,8 +134,8 @@ pci_dummy_io_set(pci_dummy_t *dev) static uint8_t pci_dummy_pci_read(int func, int addr, void *priv) { - pci_dummy_t *dev = (pci_dummy_t *) priv; - uint8_t ret = 0xff; + const pci_dummy_t *dev = (pci_dummy_t *) priv; + uint8_t ret = 0xff; if (func == 0x00) switch (addr) { @@ -152,8 +167,8 @@ pci_dummy_pci_read(int func, int addr, void *priv) ret = dev->pci_regs[addr]; break; - case 0x08: /* Techncially, revision, but we return the card (slot) here. */ - ret = dev->card; + case 0x08: /* Techncially, revision, but we return the slot here. */ + ret = dev->pci_slot; break; case 0x10: /* PCI_BAR 7:5 */ @@ -172,7 +187,9 @@ pci_dummy_pci_read(int func, int addr, void *priv) break; } - // pclog("AB0B:071A: PCI_Read(%d, %04X) = %02X\n", func, addr, ret); +#if 0 + pclog("AB0B:071A: PCI_Read(%d, %04X) = %02X\n", func, addr, ret); +#endif return ret; } @@ -183,7 +200,9 @@ pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) pci_dummy_t *dev = (pci_dummy_t *) priv; uint8_t valxor; - // pclog("AB0B:071A: PCI_Write(%d, %04X, %02X)\n", func, addr, val); +#if 0 + pclog("AB0B:071A: PCI_Write(%d, %04X, %02X)\n", func, addr, val); +#endif if (func == 0x00) switch (addr) { @@ -199,7 +218,7 @@ pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) case 0x10: /* PCI_BAR */ val &= 0xe0; /* 0xe0 acc to RTL DS */ - /*FALLTHROUGH*/ + fallthrough; case 0x11: /* PCI_BAR */ /* Remove old I/O. */ @@ -222,9 +241,12 @@ pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x3c: /* PCI_ILR */ - pclog("AB0B:071A Device %02X: IRQ now: %i\n", dev->card, val); + pclog("AB0B:071A Device %02X: IRQ now: %i\n", dev->pci_slot, val); dev->pci_regs[addr] = val; return; + + default: + break; } } @@ -252,11 +274,11 @@ pci_dummy_close(void *priv) } static void * -pci_dummy_card_init(const device_t *info) +pci_dummy_card_init(UNUSED(const device_t *info)) { pci_dummy_t *dev = (pci_dummy_t *) calloc(1, sizeof(pci_dummy_t)); - dev->card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev, &dev->pci_slot); return dev; } diff --git a/src/pic.c b/src/pic.c index ffb370ce28..82905261a7 100644 --- a/src/pic.c +++ b/src/pic.c @@ -37,6 +37,7 @@ #include <86box/apm.h> #include <86box/nvr.h> #include <86box/acpi.h> +#include <86box/plat_unused.h> enum { STATE_NONE = 0, @@ -53,7 +54,6 @@ static pc_timer_t pic_timer; static int shadow = 0; static int elcr_enabled = 0; static int tmr_inited = 0; -static int latched = 0; static int pic_pci = 0; static int kbd_latch = 0; static int mouse_latch = 0; @@ -140,9 +140,9 @@ pic_elcr_write(uint16_t port, uint8_t val, void *priv) } uint8_t -pic_elcr_read(uint16_t port, void *priv) +pic_elcr_read(UNUSED(uint16_t port), void *priv) { - pic_t *dev = (pic_t *) priv; + const pic_t *dev = (pic_t *) priv; pic_log("ELCR%i: READ %02X\n", port & 1, dev->elcr); @@ -191,8 +191,8 @@ find_best_interrupt(pic_t *dev) { uint8_t b; uint8_t intr; - int j; - int ret = -1; + uint8_t j; + int8_t ret = -1; for (uint8_t i = 0; i < 8; i++) { j = (i + dev->priority) & 7; @@ -222,37 +222,31 @@ find_best_interrupt(pic_t *dev) static __inline void pic_update_pending_xt(void) { - if (find_best_interrupt(&pic) != -1) { - latched++; - if (latched == 1) - timer_on_auto(&pic_timer, 0.35); - } else if (latched == 0) - pic.int_pending = 0; + if (!(pic.interrupt & 0x20)) + pic.int_pending = (find_best_interrupt(&pic) != -1); } +/* Only check if PIC 1 frozen, because it should not happen + that one is frozen but the other is not. */ static __inline void pic_update_pending_at(void) { - pic2.int_pending = (find_best_interrupt(&pic2) != -1); - - if (pic2.int_pending) - pic.irr |= (1 << pic2.icw3); - else - pic.irr &= ~(1 << pic2.icw3); + if (!(pic.interrupt & 0x20)) { + pic2.int_pending = (find_best_interrupt(&pic2) != -1); + + if (pic2.int_pending) + pic.irr |= (1 << pic2.icw3); + else + pic.irr &= ~(1 << pic2.icw3); - pic.int_pending = (find_best_interrupt(&pic) != -1); + pic.int_pending = (find_best_interrupt(&pic) != -1); + } } static void pic_callback(void *priv) { - pic_t *dev = (pic_t *) priv; - - dev->int_pending = 1; - - latched--; - if (latched > 0) - timer_on_auto(&pic_timer, 0.35); + update_pending(); } void @@ -325,7 +319,7 @@ pic_acknowledge(pic_t *dev) int pic_int_num = 1 << pic_int; dev->isr |= pic_int_num; - if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num)) + if (!pic_level_triggered(dev, pic_int) || (dev->lines[pic_int] == 0)) dev->irr &= ~pic_int_num; } @@ -334,7 +328,7 @@ pic_acknowledge(pic_t *dev) static uint8_t pic_non_specific_find(pic_t *dev) { - int j; + uint8_t j; uint8_t b; uint8_t irq = 0xff; @@ -398,11 +392,11 @@ pic_command(pic_t *dev) } uint8_t -pic_latch_read(uint16_t addr, void *priv) +pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv)) { uint8_t ret = 0xff; - pic_log("pic_latch_read(%i, %i): %02X%02X\n", kbd_latch, mouse_latch, pic2.lines & 0x10, pic.lines & 0x02); + pic_log("pic_latch_read(%i, %i)\n", kbd_latch, mouse_latch); if (kbd_latch && (latched_irqs & 0x0002)) picintc(0x0002); @@ -414,6 +408,48 @@ pic_latch_read(uint16_t addr, void *priv) return ret; } +uint8_t +pic_read_icw(uint8_t pic_id, uint8_t icw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (icw) { + case 0x00: + ret = dev->icw1; + break; + case 0x01: + ret = dev->icw2; + break; + case 0x02: + ret = dev->icw3; + break; + case 0x03: + ret = dev->icw4; + break; + } + + return ret; +} + +uint8_t +pic_read_ocw(uint8_t pic_id, uint8_t ocw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (ocw) { + case 0x00: + ret = dev->ocw2; + break; + case 0x01: + ret = dev->ocw3; + break; + } + + return ret; +} + uint8_t pic_read(uint16_t addr, void *priv) { @@ -493,7 +529,13 @@ pic_write(uint16_t addr, uint8_t val, void *priv) break; case STATE_NONE: dev->imr = val; - update_pending(); + if (is286) + update_pending(); + else + timer_on_auto(&pic_timer, .0 * ((10000000.0 * (double) xt_cpu_multi) / (double) cpu_s->rspeed)); + break; + + default: break; } } else { @@ -507,7 +549,11 @@ pic_write(uint16_t addr, uint8_t val, void *priv) if (!(dev->icw1 & 1)) dev->icw4 = 0x00; dev->ocw2 = dev->ocw3 = 0x00; - dev->irr = dev->lines; + dev->irr = 0x00; + for (uint8_t i = 0; i <= 7; i++) { + if (dev->lines[i] > 0) + dev->irr |= (1 << i); + } dev->imr = dev->isr = 0x00; dev->ack_bytes = dev->priority = 0x00; dev->auto_eoi_rotate = dev->special_mask_mode = 0x00; @@ -531,14 +577,12 @@ pic_write(uint16_t addr, uint8_t val, void *priv) void pic_set_pci(void) { - int i; - - for (i = 0x0024; i < 0x0040; i += 4) { + for (uint8_t i = 0x0024; i < 0x0040; i += 4) { io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); } - for (i = 0x1120; i < 0x1140; i += 4) { + for (uint16_t i = 0x1120; i < 0x1140; i += 4) { io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); } @@ -584,7 +628,7 @@ pic_reset_hard(void) /* The situation is as follows: There is a giant mess when it comes to these latches on real hardware, to the point that there's even boards with board-level latched that get used in place of the latches on the chipset, therefore, I'm just doing this here for the sake of simplicity. */ - if (machine_has_bus(machine, MACHINE_BUS_PS2)) { + if (machine_has_bus(machine, MACHINE_BUS_PS2_LATCH)) { pic_kbd_latch(0x01); pic_mouse_latch(0x01); } else { @@ -619,16 +663,20 @@ pic2_init(void) } void -picint_common(uint16_t num, int level, int set) +picint_common(uint16_t num, int level, int set, uint8_t *irq_state) { int raise; + int max = 16; uint8_t b; uint8_t slaves = 0; + uint16_t w; + uint16_t lines = level ? 0x0000 : num; + pic_t *dev; /* Make sure to ignore all slave IRQ's, and in case of AT+, translate IRQ 2 to IRQ 9. */ for (uint8_t i = 0; i < 8; i++) { - b = (1 << i); + b = (uint8_t) (1 << i); raise = num & b; if (pic.icw3 & b) { @@ -643,87 +691,89 @@ picint_common(uint16_t num, int level, int set) } if (!slaves) - num &= 0x00ff; + max = 8; if (!num) { pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower"); return; } - if (num & 0x0100) - acpi_rtc_status = !!set; + if (level) { + dev = &pic; - if (set) { - if (smi_irq_mask & num) { - smi_raise(); - smi_irq_status |= num; - } + for (uint16_t i = 0; i < max; i++) { + if (i == 8) + dev = &pic2; - if (num & 0xff00) { - if (level) - pic2.lines |= (num >> 8); + b = i & 7; + w = 1 << i; - /* Latch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs |= 0x1000; + if (num & w) { + if ((!!*irq_state) != !!set) + set ? dev->lines[b]++ : dev->lines[b]--; - pic2.irr |= (num >> 8); + if (!pic_level_triggered(dev, b) || + (((!!*irq_state) != !!set) && (dev->lines[b] == (!!set)))) + lines |= w; + } } - if (num & 0x00ff) { - if (level) - pic.lines |= (num & 0x00ff); + if ((!!*irq_state) != !!set) + *irq_state = set; - /* Latch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs |= 0x0002; + num = lines; + } - pic.irr |= (num & 0x00ff); - } - } else { - smi_irq_status &= ~num; + if (!slaves) + num &= 0x00ff; - if (num & 0xff00) { - pic2.lines &= ~(num >> 8); + if (num & 0x0100) + acpi_rtc_status = !!set; - /* Unlatch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs &= 0xefff; + if (num) { + if (set) { + if (smi_irq_mask & num) { + smi_raise(); + smi_irq_status |= num; + } - pic2.irr &= ~(num >> 8); - } + if (num & 0xff00) { + /* Latch IRQ 12 if the mouse latch is enabled. */ + if ((num & 0x1000) && mouse_latch) + latched_irqs |= 0x1000; - if (num & 0x00ff) { - pic.lines &= ~(num & 0x00ff); + pic2.irr |= (num >> 8); + } - /* Unlatch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs &= 0xfffd; + if (num & 0x00ff) { + /* Latch IRQ 1 if the keyboard latch is enabled. */ + if (kbd_latch && (num & 0x0002)) + latched_irqs |= 0x0002; - pic.irr &= ~(num & 0x00ff); - } - } + pic.irr |= (num & 0x00ff); + } + } else { + smi_irq_status &= ~num; - if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20)) - update_pending(); -} + if (num & 0xff00) { + /* Unlatch IRQ 12 if the mouse latch is enabled. */ + if ((num & 0x1000) && mouse_latch) + latched_irqs &= 0xefff; -void -picint(uint16_t num) -{ - picint_common(num, 0, 1); -} + pic2.irr &= ~(num >> 8); + } -void -picintlevel(uint16_t num) -{ - picint_common(num, 1, 1); -} + if (num & 0x00ff) { + /* Unlatch IRQ 1 if the keyboard latch is enabled. */ + if (kbd_latch && (num & 0x0002)) + latched_irqs &= 0xfffd; -void -picintc(uint16_t num) -{ - picint_common(num, 0, 0); + pic.irr &= ~(num & 0x00ff); + } + } + + update_pending(); + } } static uint8_t @@ -779,7 +829,7 @@ pic_irq_ack_read(pic_t *dev, int phase) uint8_t pic_irq_ack(void) { - int ret; + uint8_t ret; /* Needed for Xi8088. */ if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) { @@ -815,27 +865,34 @@ picinterrupt(void) if (pic_slave_on(&pic, pic.interrupt)) { if (!pic.slaves[pic.interrupt]->int_pending) { /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ - fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); - exit(-1); - } - - pic.interrupt |= 0x40; /* Mark slave pending. */ + // fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); + // exit(-1); + /* Error correction mechanism: Do a supurious IRQ 15 (spurious IRQ 7 on PIC 2). */ + pic.slaves[pic.interrupt]->int_pending = 1; + pic.slaves[pic.interrupt]->interrupt = 0x07; + } else + pic.interrupt |= 0x40; /* Mark slave pending. */ } + } else { + /* pic.int_pending was somehow cleared despite the fact we made it here, + do a spurious IRQ 7. */ + pic.int_pending = 1; + pic.interrupt = 0x07; + } - if ((pic.interrupt == 0) && (pit_devs[1].data != NULL)) - pit_devs[1].set_gate(pit_devs[1].data, 0, 0); + if ((pic.interrupt == 0) && (pit_devs[1].data != NULL)) + pit_devs[1].set_gate(pit_devs[1].data, 0, 0); - /* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */ - for (uint8_t i = 0; i < 2; i++) { - ret = pic_irq_ack_read(&pic, pic.ack_bytes); - pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); + /* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */ + for (uint8_t i = 0; i < 2; i++) { + ret = pic_irq_ack_read(&pic, pic.ack_bytes); + pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); - if (pic.ack_bytes == 0) { - if (pic.interrupt & 0x40) - pic2.interrupt = 0x17; - pic.interrupt = 0x17; - update_pending(); - } + if (pic.ack_bytes == 0) { + if (pic.interrupt & 0x40) + pic2.interrupt = 0x17; + pic.interrupt = 0x17; + update_pending(); } } diff --git a/src/pit.c b/src/pit.c index cf339607da..6045fd842d 100644 --- a/src/pit.c +++ b/src/pit.c @@ -41,6 +41,7 @@ #include <86box/sound.h> #include <86box/snd_speaker.h> #include <86box/video.h> +#include <86box/plat_unused.h> pit_intf_t pit_devs[2]; @@ -171,6 +172,9 @@ ctr_tick(ctr_t *ctr) case 3: ctr_decrease_count(ctr); break; + + default: + break; } break; case 1: @@ -189,6 +193,9 @@ ctr_tick(ctr_t *ctr) case 6: ctr_decrease_count(ctr); break; + + default: + break; } break; case 2: @@ -211,6 +218,9 @@ ctr_tick(ctr_t *ctr) } } break; + + default: + break; } break; case 3: @@ -254,6 +264,9 @@ ctr_tick(ctr_t *ctr) ctr->newcount = 0; } break; + + default: + break; } break; case 4: @@ -279,6 +292,9 @@ ctr_tick(ctr_t *ctr) ctr->state = 0; ctr_set_out(ctr, 1); break; + + default: + break; } } break; @@ -369,6 +385,9 @@ ctr_latch_count(ctr_t *ctr) ctr->rl = count; ctr->latched = 2; break; + + default: + break; } pit_log("latched counter = %04X\n", ctr->rl & 0xffff); @@ -377,8 +396,8 @@ ctr_latch_count(ctr_t *ctr) uint16_t pit_ctr_get_count(void *data, int counter_id) { - pit_t *pit = (pit_t *) data; - ctr_t *ctr = &pit->counters[counter_id]; + const pit_t *pit = (pit_t *) data; + const ctr_t *ctr = &pit->counters[counter_id]; return (uint16_t) ctr->l; } @@ -439,6 +458,9 @@ pit_ctr_set_gate(void *data, int counter_id, int gate) ctr_set_out(ctr, 1); } break; + + default: + break; } } @@ -487,9 +509,9 @@ pit_ctr_set_using_timer(void *data, int counter_id, int using_timer) } static void -pit_timer_over(void *p) +pit_timer_over(void *priv) { - pit_t *dev = (pit_t *) p; + pit_t *dev = (pit_t *) priv; dev->clock ^= 1; @@ -602,13 +624,55 @@ pit_write(uint16_t addr, uint8_t val, void *priv) else ctr->wm |= 0x80; break; + + default: + break; } break; + + default: + break; } } extern uint8_t *ram; +uint8_t +pit_read_reg(void *priv, uint8_t reg) +{ + pit_t *dev = (pit_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. + Update: But the SiS 5571 datasheet is clear. */ + ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; + ret |= (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; + ret |= (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; + ret |= (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; + ret |= (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; + ret |= (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + break; + } + + return ret; +} + static uint8_t pit_read(uint16_t addr, void *priv) { @@ -675,8 +739,14 @@ pit_read(uint16_t addr, void *priv) else ctr->rm |= 0x80; break; + + default: + break; } break; + + default: + break; } pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); @@ -714,7 +784,7 @@ pit_refresh_timer_at(int new_out, int old_out) } void -pit_speaker_timer(int new_out, int old_out) +pit_speaker_timer(int new_out, UNUSED(int old_out)) { int l; @@ -734,7 +804,7 @@ pit_speaker_timer(int new_out, int old_out) } void -pit_nmi_timer_ps2(int new_out, int old_out) +pit_nmi_timer_ps2(int new_out, UNUSED(int old_out)) { nmi = new_out; @@ -818,7 +888,7 @@ pit_init(const device_t *info) const device_t i8253_device = { .name = "Intel 8253/8253-5 Programmable Interval Timer", .internal_name = "i8253", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8253, .init = pit_init, .close = pit_close, @@ -832,7 +902,7 @@ const device_t i8253_device = { const device_t i8254_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8254, .init = pit_init, .close = pit_close, @@ -893,8 +963,8 @@ pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(i pit_intf_t *pit_intf = &pit_devs[0]; switch (type) { - case PIT_8253: default: + case PIT_8253: pit = device_add(&i8253_device); *pit_intf = pit_classic_intf; break; @@ -937,8 +1007,8 @@ pit_ps2_init(int type) pit_intf_t *ps2_pit = &pit_devs[1]; switch (type) { - case PIT_8254: default: + case PIT_8254: pit = device_add(&i8254_ps2_device); *ps2_pit = pit_classic_intf; break; @@ -966,11 +1036,11 @@ pit_ps2_init(int type) } void -pit_set_clock(int clock) +pit_set_clock(uint32_t clock) { /* Set default CPU/crystal clock and xt_cpu_multi. */ if (cpu_s->cpu_type >= CPU_286) { - int remainder = (clock % 100000000); + uint32_t remainder = (clock % 100000000); if (remainder == 66666666) cpuclock = (double) (clock - remainder) + (200000000.0 / 3.0); else if (remainder == 33333333) @@ -980,7 +1050,11 @@ pit_set_clock(int clock) PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); +#ifdef IMPRECISE_CGACONST CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32)); +#else + CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32)); +#endif ISACONST = (uint64_t) ((cpuclock / (double) cpu_isa_speed) * (double) (1ULL << 32)); xt_cpu_multi = 1ULL; } else { @@ -1030,7 +1104,11 @@ pit_set_clock(int clock) } else if (cpuclock != 14318184.0) { PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); +#ifdef IMPRECISE_CGACONST CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32)); +#else + CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32)); +#endif } ISACONST = (1ULL << 32ULL); @@ -1040,7 +1118,11 @@ pit_set_clock(int clock) /* Delay for empty I/O ports. */ io_delay = (int) round(((double) cpu_s->rspeed) / 3000000.0); +#ifdef WRONG_MDACONST MDACONST = (uint64_t) (cpuclock / 2032125.0 * (double) (1ULL << 32)); +#else + MDACONST = (uint64_t) (cpuclock / (16257000.0 / 9.0) * (double) (1ULL << 32)); +#endif HERCCONST = MDACONST; VGACONST1 = (uint64_t) (cpuclock / 25175000.0 * (double) (1ULL << 32)); VGACONST2 = (uint64_t) (cpuclock / 28322000.0 * (double) (1ULL << 32)); @@ -1050,9 +1132,9 @@ pit_set_clock(int clock) isa_timing = (cpuclock / (double) cpu_isa_speed); if (cpu_64bitbus) - bus_timing = (cpuclock / ((double) cpu_busspeed / 2)); + bus_timing = (cpuclock / (cpu_busspeed / 2)); else - bus_timing = (cpuclock / (double) cpu_busspeed); + bus_timing = (cpuclock / cpu_busspeed); pci_timing = (cpuclock / (double) cpu_pci_speed); agp_timing = (cpuclock / (double) cpu_agp_speed); @@ -1080,4 +1162,4 @@ const pit_intf_t pit_classic_intf = { &pit_ctr_set_load_func, &ctr_clock, NULL, -}; \ No newline at end of file +}; diff --git a/src/pit_fast.c b/src/pit_fast.c index 4e7bc77c70..f9d0553754 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -91,8 +91,9 @@ pitf_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, i static uint16_t pitf_ctr_get_count(void *data, int counter_id) { - pitf_t *pit = (pitf_t *) data; - ctrf_t *ctr = &pit->counters[counter_id]; + const pitf_t *pit = (pitf_t *) data; + const ctrf_t *ctr = &pit->counters[counter_id]; + return (uint16_t) ctr->l; } @@ -207,6 +208,9 @@ pitf_ctr_load(ctrf_t *ctr) case 5: /*Hardware triggered stobe*/ ctr->enabled = 1; break; + + default: + break; } if (ctr->load_func != NULL) @@ -266,6 +270,9 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate) } ctr->enabled = gate; break; + + default: + break; } ctr->gate = gate; ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; @@ -327,7 +334,10 @@ pitf_over(ctrf_t *ctr) if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); } - // if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); +#if 0 + if (!t) + pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); +#endif break; case 4: /*Software triggered strove*/ if (!ctr->thit) { @@ -356,6 +366,9 @@ pitf_over(ctrf_t *ctr) if (ctr->using_timer) timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); break; + + default: + break; } ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; if (ctr->using_timer && !ctr->running) @@ -366,8 +379,10 @@ static __inline void pitf_ctr_latch_count(ctrf_t *ctr) { ctr->rl = pitf_read_timer(ctr); - // pclog("Timer latch %f %04X %04X\n",pit->c[0],pit->rl[0],pit->l[0]); - // pit->ctrl |= 0x30; +#if 0 + pclog("Timer latch %f %04X %04X\n",pit->c[0],pit->rl[0],pit->l[0]); + pit->ctrl |= 0x30; +#endif ctr->rereadlatch = 0; ctr->rm = 3; ctr->latched = 1; @@ -389,6 +404,8 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + cycles -= ISA_CYCLES(8); + switch (addr & 3) { case 3: /* control */ t = val >> 6; @@ -472,11 +489,53 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) ctr->l |= val; ctr->wm = 0; break; + + default: + break; } break; + + default: + break; } } +uint8_t +pitf_read_reg(void *priv, uint8_t reg) +{ + pitf_t *dev = (pitf_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. + Update: But the SiS 5571 datasheet is clear. */ + ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; + ret |= (dev->counters[1].rm & 0x80) ? 0x02 : 0x00; + ret |= (dev->counters[2].rm & 0x80) ? 0x04 : 0x00; + ret |= (dev->counters[0].wm & 0x80) ? 0x08 : 0x00; + ret |= (dev->counters[1].wm & 0x80) ? 0x10 : 0x00; + ret |= (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + break; + } + + return ret; +} + static uint8_t pitf_read(uint16_t addr, void *priv) { @@ -485,6 +544,8 @@ pitf_read(uint16_t addr, void *priv) int t = (addr & 3); ctrf_t *ctr; + cycles -= ISA_CYCLES(8); + switch (addr & 3) { case 3: /* Control. */ /* This is 8254-only, 8253 returns 0x00. */ @@ -530,8 +591,14 @@ pitf_read(uint16_t addr, void *priv) else ctr->rm = 0; break; + + default: + break; } break; + + default: + break; } pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); @@ -540,9 +607,9 @@ pitf_read(uint16_t addr, void *priv) } static void -pitf_timer_over(void *p) +pitf_timer_over(void *priv) { - ctrf_t *ctr = (ctrf_t *) p; + ctrf_t *ctr = (ctrf_t *) priv; pitf_over(ctr); } @@ -627,7 +694,7 @@ pitf_init(const device_t *info) const device_t i8253_fast_device = { .name = "Intel 8253/8253-5 Programmable Interval Timer", .internal_name = "i8253_fast", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8253, .init = pitf_init, .close = pitf_close, @@ -641,7 +708,7 @@ const device_t i8253_fast_device = { const device_t i8254_fast_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254_fast", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8254, .init = pitf_init, .close = pitf_close, @@ -704,4 +771,4 @@ const pit_intf_t pit_fast_intf = { &pitf_ctr_set_load_func, &pitf_ctr_clock, NULL, -}; \ No newline at end of file +}; diff --git a/src/port_6x.c b/src/port_6x.c index 2bfebcee09..971b92d282 100644 --- a/src/port_6x.c +++ b/src/port_6x.c @@ -36,6 +36,8 @@ #include <86box/ppi.h> #include <86box/video.h> #include <86box/port_6x.h> +#include <86box/plat_unused.h> +#include <86box/random.h> #define PS2_REFRESH_TIME (16 * TIMER_USEC) @@ -44,13 +46,17 @@ #define PORT_6X_MIRROR 4 #define PORT_6X_SWA 8 +static int cycles_sub = 0; + static void port_6x_write(uint16_t port, uint8_t val, void *priv) { - port_6x_t *dev = (port_6x_t *) priv; + const port_6x_t *dev = (port_6x_t *) priv; port &= 3; + cycles -= cycles_sub; + if ((port == 3) && (dev->flags & PORT_6X_MIRROR)) port = 1; @@ -68,14 +74,19 @@ port_6x_write(uint16_t port, uint8_t val, void *priv) if (dev->flags & PORT_6X_TURBO) xi8088_turbo_set(!!(val & 0x04)); break; + + default: + break; } } static uint8_t -port_61_read_simple(uint16_t port, void *priv) +port_61_read_simple(UNUSED(uint16_t port), UNUSED(void *priv)) { uint8_t ret = ppi.pb & 0x1f; + cycles -= cycles_sub; + if (ppispeakon) ret |= 0x20; @@ -83,10 +94,12 @@ port_61_read_simple(uint16_t port, void *priv) } static uint8_t -port_61_read(uint16_t port, void *priv) +port_61_read(UNUSED(uint16_t port), void *priv) { - port_6x_t *dev = (port_6x_t *) priv; - uint8_t ret = 0xff; + const port_6x_t *dev = (port_6x_t *) priv; + uint8_t ret = 0xff; + + cycles -= cycles_sub; if (dev->flags & PORT_6X_EXT_REF) { ret = ppi.pb & 0x0f; @@ -106,7 +119,7 @@ port_61_read(uint16_t port, void *priv) } static uint8_t -port_62_read(uint16_t port, void *priv) +port_62_read(UNUSED(uint16_t port), UNUSED(void *priv)) { uint8_t ret = 0xff; @@ -186,6 +199,8 @@ port_6x_init(const device_t *info) if (dev->flags & PORT_6X_SWA) io_sethandler(0x0062, 1, port_62_read, NULL, NULL, NULL, NULL, NULL, dev); + cycles_sub = is486 ? ISA_CYCLES(8) : 0; + return dev; } diff --git a/src/port_92.c b/src/port_92.c index fd0471b0e9..1307ecba93 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -29,6 +29,7 @@ #include <86box/mem.h> #include <86box/pit.h> #include <86box/port_92.h> +#include <86box/plat_unused.h> #define PORT_92_INV 1 #define PORT_92_WORD 2 @@ -39,8 +40,8 @@ static uint8_t port_92_readb(uint16_t port, void *priv) { - uint8_t ret = 0x00; - port_92_t *dev = (port_92_t *) priv; + uint8_t ret = 0x00; + const port_92_t *dev = (port_92_t *) priv; if (port == 0x92) { /* Return bit 1 directly from mem_a20_alt, so the @@ -60,8 +61,8 @@ port_92_readb(uint16_t port, void *priv) static uint16_t port_92_readw(uint16_t port, void *priv) { - uint16_t ret = 0xffff; - port_92_t *dev = (port_92_t *) priv; + uint16_t ret = 0xffff; + const port_92_t *dev = (port_92_t *) priv; if (!(dev->flags & PORT_92_PCI)) ret = port_92_readb(port, priv); @@ -74,7 +75,7 @@ port_92_readw(uint16_t port, void *priv) TODO: ALi M1543(c) behavior. */ static void -port_92_pulse(void *priv) +port_92_pulse(UNUSED(void *priv)) { softresetx86(); /* Pulse reset! */ cpu_set_edx(); @@ -112,7 +113,7 @@ port_92_writeb(uint16_t port, uint8_t val, void *priv) static void port_92_writew(uint16_t port, uint16_t val, void *priv) { - port_92_t *dev = (port_92_t *) priv; + const port_92_t *dev = (port_92_t *) priv; if (!(dev->flags & PORT_92_PCI)) port_92_writeb(port, val & 0xff, priv); @@ -174,7 +175,7 @@ port_92_remove(void *priv) } static void -port_92_reset(void *priv) +port_92_reset(UNUSED(void *priv)) { cpu_alt_reset = 0; diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index c774258e2d..dea0c7fbe8 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -20,4 +20,15 @@ if(APPLE) if (NOT GHOSTSCRIPT_LIB) message(WARNING "Could not find ghostscript. The library will not be bundled and any related features will not work.") endif() -endif () \ No newline at end of file +endif() + +find_package(PkgConfig REQUIRED) +pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2) +target_link_libraries(86Box PkgConfig::FREETYPE) +if(STATIC_BUILD) + if(QT) + # Qt provides its own version of harfbuzz which leads to duplicated symbols. + target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") + endif() + target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) +endif() diff --git a/src/printer/png.c b/src/printer/png.c index 49da1ee180..c7443252be 100644 --- a/src/printer/png.c +++ b/src/printer/png.c @@ -92,13 +92,13 @@ png_log(const char *fmt, ...) #endif static void -error_handler(png_structp arg, const char *str) +error_handler(UNUSED(png_structp arg), UNUSED(const char *str)) { png_log("PNG: stream 0x%08lx error '%s'\n", arg, str); } static void -warning_handler(png_structp arg, const char *str) +warning_handler(UNUSED(png_structp arg), UNUSED(const char *str)) { png_log("PNG: stream 0x%08lx warning '%s'\n", arg, str); } @@ -196,7 +196,6 @@ png_write_rgb(char *fn, uint8_t *pix, int16_t w, int16_t h, uint16_t pitch, PALE png_bytep *rows; png_color palette[256]; FILE *fp; - int i; /* Create the image file. */ fp = plat_fopen(fn, "wb"); @@ -248,7 +247,7 @@ png_write_rgb(char *fn, uint8_t *pix, int16_t w, int16_t h, uint16_t pitch, PALE PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - for (i = 0; i < 256; i++) { + for (uint16_t i = 0; i < 256; i++) { palette[i].red = palcol[i].r; palette[i].green = palcol[i].g; palette[i].blue = palcol[i].b; @@ -259,7 +258,7 @@ png_write_rgb(char *fn, uint8_t *pix, int16_t w, int16_t h, uint16_t pitch, PALE /* Create a buffer for scanlines of pixels. */ rows = (png_bytep *) malloc(sizeof(png_bytep) * h); - for (i = 0; i < h; i++) { + for (int16_t i = 0; i < h; i++) { /* Create a buffer for this scanline. */ rows[i] = (pix + (i * pitch)); } diff --git a/src/printer/prt_cpmap.c b/src/printer/prt_cpmap.c index ba9e710854..153008f355 100644 --- a/src/printer/prt_cpmap.c +++ b/src/printer/prt_cpmap.c @@ -572,7 +572,7 @@ static const struct { void select_codepage(uint16_t code, uint16_t *curmap) { - int i = 0; + uint16_t i = 0; const uint16_t *map_to_use; map_to_use = maps[0].map; @@ -585,6 +585,6 @@ select_codepage(uint16_t code, uint16_t *curmap) i++; } - for (i = 0; i < 256; i++) - curmap[i] = map_to_use[i]; + for (uint16_t j = 0; j < 256; j++) + curmap[j] = map_to_use[j]; } diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index f1697e0744..8247ecfab8 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -65,7 +65,6 @@ #include <86box/pit.h> #include <86box/path.h> #include <86box/plat.h> -#include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/lpt.h> #include <86box/video.h> @@ -85,45 +84,8 @@ #define PAGE_CPI 10.0 /* standard 10 cpi */ #define PAGE_LPI 6.0 /* standard 6 lpi */ -#ifdef _WIN32 -# define PATH_FREETYPE_DLL "freetype.dll" -#elif defined __APPLE__ -# define PATH_FREETYPE_DLL "libfreetype.6.dylib" -#else -# define PATH_FREETYPE_DLL "libfreetype.so.6" -#endif - /* FreeType library handles - global so they can be shared. */ -FT_Library ft_lib = NULL; -void *ft_handle = NULL; - -static int (*ft_Init_FreeType)(FT_Library *alibrary); -static int (*ft_Done_Face)(FT_Face face); -static int (*ft_New_Face)(FT_Library library, const char *filepathname, - FT_Long face_index, FT_Face *aface); -static int (*ft_Set_Char_Size)(FT_Face face, FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution); -static int (*ft_Set_Transform)(FT_Face face, FT_Matrix *matrix, - FT_Vector *delta); -static int (*ft_Get_Char_Index)(FT_Face face, FT_ULong charcode); -static int (*ft_Load_Glyph)(FT_Face face, FT_UInt glyph_index, - FT_Int32 load_flags); -static int (*ft_Render_Glyph)(FT_GlyphSlot slot, - FT_Render_Mode render_mode); - -static dllimp_t ft_imports[] = { - {"FT_Init_FreeType", &ft_Init_FreeType }, - { "FT_New_Face", &ft_New_Face }, - { "FT_Done_Face", &ft_Done_Face }, - { "FT_Set_Char_Size", &ft_Set_Char_Size }, - { "FT_Set_Transform", &ft_Set_Transform }, - { "FT_Get_Char_Index", &ft_Get_Char_Index}, - { "FT_Load_Glyph", &ft_Load_Glyph }, - { "FT_Render_Glyph", &ft_Render_Glyph }, - { NULL, NULL } -}; +FT_Library ft_lib = NULL; /* The fonts. */ #define FONT_DEFAULT 0 @@ -181,7 +143,7 @@ static dllimp_t ft_imports[] = { #define PIXX ((unsigned) floor(dev->curr_x * dev->dpi + 0.5)) #define PIXY ((unsigned) floor(dev->curr_y * dev->dpi + 0.5)) -typedef struct { +typedef struct psurface_t { int8_t dirty; /* has the page been printed on? */ char pad; @@ -192,7 +154,7 @@ typedef struct { uint8_t *pixels; /* grayscale pixel data */ } psurface_t; -typedef struct { +typedef struct escp_t { const char *name; void *lpt; @@ -204,12 +166,12 @@ typedef struct { uint8_t color; /* page data (TODO: make configurable) */ - double page_width, /* all in inches */ - page_height, - left_margin, - top_margin, - right_margin, - bottom_margin; + double page_width; /* all in inches */ + double page_height; + double left_margin; + double top_margin; + double right_margin; + double bottom_margin; uint16_t dpi; double cpi; /* defined chars per inch */ double lpi; /* defined lines per inch */ @@ -255,7 +217,8 @@ typedef struct { char fontpath[1024]; char pagepath[1024]; psurface_t *page; - double curr_x, curr_y; /* print head position (inch) */ + double curr_x; /* print head position (x, inch) */ + double curr_y; /* print head position (y, inch) */ uint16_t current_font; FT_Face fontface; int8_t lq_typeface; @@ -474,6 +437,7 @@ reset_printer(escp_t *dev) dev->cpi = PAGE_CPI; dev->curr_char_table = 1; dev->font_style = 0; + dev->print_quality = QUALITY_DRAFT; dev->extra_intra_space = 0.0; dev->print_upper_control = 1; dev->bg_remaining_bytes = 0; @@ -531,11 +495,11 @@ init_codepage(escp_t *dev, uint16_t num) static void update_font(escp_t *dev) { - char path[1024]; - char *fn; - FT_Matrix matrix; - double hpoints = 10.5; - double vpoints = 10.5; + char path[1024]; + const char *fn; + FT_Matrix matrix; + double hpoints = 10.5; + double vpoints = 10.5; /* We need the FreeType library. */ if (ft_lib == NULL) @@ -543,11 +507,14 @@ update_font(escp_t *dev) /* Release current font if we have one. */ if (dev->fontface) - ft_Done_Face(dev->fontface); + FT_Done_Face(dev->fontface); - if (dev->print_quality == QUALITY_DRAFT) - fn = FONT_FILE_DOTMATRIX; - else + if (dev->print_quality == QUALITY_DRAFT) { + if (dev->font_style & STYLE_ITALICS) + fn = FONT_FILE_DOTMATRIX_ITALIC; + else + fn = FONT_FILE_DOTMATRIX; + } else switch (dev->lq_typeface) { case TYPEFACE_ROMAN: fn = FONT_FILE_ROMAN; @@ -568,7 +535,7 @@ update_font(escp_t *dev) fn = FONT_FILE_OCRB; break; default: - fn = FONT_FILE_DOTMATRIX; + fn = FONT_FILE_ROMAN; } /* Create a full pathname for the ROM file. */ @@ -579,7 +546,7 @@ update_font(escp_t *dev) escp_log("Temp file=%s\n", path); /* Load the new font. */ - if (ft_New_Face(ft_lib, path, 0, &dev->fontface)) { + if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; } @@ -625,17 +592,17 @@ update_font(escp_t *dev) dev->actual_cpi /= 2.0 / 3.0; } - ft_Set_Char_Size(dev->fontface, + FT_Set_Char_Size(dev->fontface, (uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64), dev->dpi, dev->dpi); - if ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0)) { + if ((dev->print_quality != QUALITY_DRAFT) && ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0))) { /* Italics transformation. */ matrix.xx = 0x10000L; matrix.xy = (FT_Fixed) (0.20 * 0x10000L); matrix.yx = 0; matrix.yy = 0x10000L; - ft_Set_Transform(dev->fontface, &matrix, 0); + FT_Set_Transform(dev->fontface, &matrix, 0); } } @@ -1499,7 +1466,7 @@ process_char(escp_t *dev, uint8_t ch) dev->curr_x = dev->left_margin; if (!dev->autofeed) return 1; - /*FALLTHROUGH*/ + fallthrough; case 0x0a: /* Line feed */ if (dev->font_style & STYLE_DOUBLEWIDTHONELINE) { @@ -1610,13 +1577,13 @@ handle_char(escp_t *dev, uint8_t ch) /* ok, so we need to print the character now */ if (ft_lib) { - char_index = ft_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); - ft_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); - ft_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); + char_index = FT_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); + FT_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); + FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); } - pen_x = PIXX + dev->fontface->glyph->bitmap_left; - pen_y = (uint16_t) (PIXY - dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64); + pen_x = PIXX + fmax(0.0, dev->fontface->glyph->bitmap_left); + pen_y = (uint16_t) (PIXY + fmax(0.0, -dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64)); if (dev->font_style & STYLE_SUBSCRIPT) pen_y += dev->fontface->glyph->bitmap.rows / 2; @@ -1686,9 +1653,9 @@ handle_char(escp_t *dev, uint8_t ch) static void blit_glyph(escp_t *dev, unsigned destx, unsigned desty, int8_t add) { - FT_Bitmap *bitmap = &dev->fontface->glyph->bitmap; - uint8_t src; - uint8_t *dst; + const FT_Bitmap *bitmap = &dev->fontface->glyph->bitmap; + uint8_t src; + uint8_t *dst; /* check if freetype is available */ if (ft_lib == NULL) @@ -1955,7 +1922,7 @@ write_ctrl(uint8_t val, void *priv) static uint8_t read_data(void *priv) { - escp_t *dev = (escp_t *) priv; + const escp_t *dev = (escp_t *) priv; return dev->data; } @@ -1963,7 +1930,7 @@ read_data(void *priv) static uint8_t read_ctrl(void *priv) { - escp_t *dev = (escp_t *) priv; + const escp_t *dev = (escp_t *) priv; return 0xe0 | (dev->autofeed ? 0x02 : 0x00) | (dev->ctrl & 0xfd); } @@ -1971,7 +1938,7 @@ read_ctrl(void *priv) static uint8_t read_status(void *priv) { - escp_t *dev = (escp_t *) priv; + const escp_t *dev = (escp_t *) priv; uint8_t ret = 0x1f; ret |= 0x80; @@ -1985,23 +1952,12 @@ read_status(void *priv) static void * escp_init(void *lpt) { - const char *fn = PATH_FREETYPE_DLL; - escp_t *dev; - - /* Dynamically load FreeType. */ - if (ft_handle == NULL) { - ft_handle = dynld_module(fn, ft_imports); - if (ft_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - return (NULL); - } - } + escp_t *dev; /* Initialize FreeType. */ if (ft_lib == NULL) { - if (ft_Init_FreeType(&ft_lib)) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - dynld_close(ft_lib); + if (FT_Init_FreeType(&ft_lib)) { + pclog("ESC/P: FT_Init_FreeType failed\n"); ft_lib = NULL; return (NULL); } diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 6c72e48dea..c0e3958b2e 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -51,13 +51,14 @@ #elif defined __APPLE__ # define PATH_GHOSTSCRIPT_DLL "libgs.dylib" #else -# define PATH_GHOSTSCRIPT_DLL "libgs.so.9" +# define PATH_GHOSTSCRIPT_DLL "libgs.so.9" +# define PATH_GHOSTSCRIPT_DLL_ALT1 "libgs.so.10" +# define PATH_GHOSTSCRIPT_DLL_ALT2 "libgs.so" #endif #define POSTSCRIPT_BUFFER_LENGTH 65536 -typedef struct -{ +typedef struct ps_t { const char *name; void *lpt; @@ -236,9 +237,9 @@ timeout_timer(void *priv) } static void -ps_write_data(uint8_t val, void *p) +ps_write_data(uint8_t val, void *priv) { - ps_t *dev = (ps_t *) p; + ps_t *dev = (ps_t *) priv; if (dev == NULL) return; @@ -285,9 +286,9 @@ process_data(ps_t *dev) } static void -ps_write_ctrl(uint8_t val, void *p) +ps_write_ctrl(uint8_t val, void *priv) { - ps_t *dev = (ps_t *) p; + ps_t *dev = (ps_t *) priv; if (dev == NULL) return; @@ -317,10 +318,10 @@ ps_write_ctrl(uint8_t val, void *p) } static uint8_t -ps_read_status(void *p) +ps_read_status(void *priv) { - ps_t *dev = (ps_t *) p; - uint8_t ret = 0x9f; + const ps_t *dev = (ps_t *) priv; + uint8_t ret = 0x9f; if (!dev->ack) ret |= 0x40; @@ -341,12 +342,21 @@ ps_init(void *lpt) /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); - if (ghostscript_handle == NULL) +#ifdef PATH_GHOSTSCRIPT_DLL_ALT1 + 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); +# endif + } +#endif + if (ghostscript_handle == NULL) { ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133); - else { - if (gsapi_revision(&rev, sizeof(rev)) == 0) + } else { + if (gsapi_revision(&rev, sizeof(rev)) == 0) { pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); - else { + } else { dynld_close(ghostscript_handle); ghostscript_handle = NULL; } @@ -368,9 +378,9 @@ ps_init(void *lpt) } static void -ps_close(void *p) +ps_close(void *priv) { - ps_t *dev = (ps_t *) p; + ps_t *dev = (ps_t *) priv; if (dev == NULL) return; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 54e5fe6d58..ddf9faf531 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -81,7 +81,7 @@ #define PAGE_CPI 10.0 /* standard 10 cpi */ #define PAGE_LPI 6.0 /* standard 6 lpi */ -typedef struct { +typedef struct psurface_t { int8_t dirty; /* has the page been printed on? */ char pad; @@ -91,7 +91,7 @@ typedef struct { char *chars; /* character data */ } psurface_t; -typedef struct { +typedef struct prnt_t { const char *name; void *lpt; @@ -104,23 +104,23 @@ typedef struct { pc_timer_t timeout_timer; /* page data (TODO: make configurable) */ - double page_width, /* all in inches */ - page_height, - left_margin, - top_margin, - right_margin, - bot_margin; + double page_width; /* all in inches */ + double page_height; + double left_margin; + double top_margin; + double right_margin; + double bot_margin; /* internal page data */ psurface_t *page; - uint8_t max_chars, - max_lines; - uint8_t curr_x, /* print head position (chars) */ - curr_y; + uint8_t max_chars; + uint8_t max_lines; + uint8_t curr_x; /* print head position (x, chars) */ + uint8_t curr_y; /* print head position (y, chars) */ /* font data */ - double cpi, /* defined chars per inch */ - lpi; /* defined lines per inch */ + double cpi; /* defined chars per inch */ + double lpi; /* defined lines per inch */ /* handshake data */ uint8_t data; @@ -283,7 +283,7 @@ process_char(prnt_t *dev, uint8_t ch) dev->curr_x = 0; if (!dev->autofeed) return 1; - /*FALLTHROUGH*/ + fallthrough; case 0x0a: /* Line feed */ dev->curr_x = 0; @@ -407,8 +407,8 @@ write_ctrl(uint8_t val, void *priv) static uint8_t read_status(void *priv) { - prnt_t *dev = (prnt_t *) priv; - uint8_t ret = 0x1f; + const prnt_t *dev = (prnt_t *) priv; + uint8_t ret = 0x1f; ret |= 0x80; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 23e2c748ee..4f073cf4a4 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -197,8 +197,7 @@ if(WIN32) else() target_sources(plat PRIVATE win_joystick_rawinput.c) endif() - target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp) - target_link_libraries(86Box hid d3d9) + target_link_libraries(86Box hid) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 @@ -340,7 +339,6 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE) # Install libraries that are loaded at runtime and not linked install_bundle_library("${GHOSTSCRIPT_LIB}" "libgs.dylib" RUNTIME_PLUGINS ${INSTALL_LIB_DIR}) - install_bundle_library("${FLUIDSYNTH_LIB}" "libfluidsynth.dylib" RUNTIME_PLUGINS ${INSTALL_LIB_DIR}) install_bundle_library("${VDE_LIB}" "libvdeplug.dylib" RUNTIME_PLUGINS ${INSTALL_LIB_DIR}) install_bundle_library("${MOLTENVK_LIB}" "libVulkan.dylib" RUNTIME_PLUGINS ${INSTALL_LIB_DIR}) @@ -372,6 +370,8 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE) endif() if (UNIX AND NOT APPLE AND NOT HAIKU) + target_sources(ui PRIVATE x11_util.c) + find_package(X11 REQUIRED) target_link_libraries(ui PRIVATE X11::X11 X11::Xi) target_sources(ui PRIVATE evdev_keyboard.cpp xinput2_mouse.cpp) diff --git a/src/qt/cocoa_keyboard.hpp b/src/qt/cocoa_keyboard.hpp index eaf0cdfe0f..da3161bb22 100644 --- a/src/qt/cocoa_keyboard.hpp +++ b/src/qt/cocoa_keyboard.hpp @@ -127,3 +127,9 @@ static std::array cocoa_keycodes = { /* key names in parentheses 0x150, /* DownArrow */ 0x148, /* UpArrow */ }; + +// https://developer.apple.com/documentation/appkit/nseventmodifierflags/ +qint32 NSEventModifierFlagCommand = 1 << 20; + +qint32 nvk_Delete = 0x75; +qint32 nvk_Insert = 0x72; \ No newline at end of file diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 4b487e65d8..b5f68a286c 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -37,21 +37,6 @@ static std::vector> evdev_mice; static std::atomic stopped = false; static QThread *evdev_thread; -static std::atomic evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0; - -void -evdev_mouse_poll() -{ - if (!evdev_mice.size() || !mouse_capture) { - evdev_mouse_rel_x = 0; - evdev_mouse_rel_y = 0; - return; - } - mouse_x = evdev_mouse_rel_x; - mouse_y = evdev_mouse_rel_y; - evdev_mouse_rel_x = evdev_mouse_rel_y = 0; -} - void evdev_thread_func() { @@ -67,11 +52,11 @@ evdev_thread_func() struct input_event ev; if (pfds[i].revents & POLLIN) { while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) { - if (ev.type == EV_REL && mouse_capture) { + if (evdev_mice.size() && (ev.type == EV_REL) && mouse_capture) { if (ev.code == REL_X) - evdev_mouse_rel_x += ev.value; + mouse_scale_x(ev.value); if (ev.code == REL_Y) - evdev_mouse_rel_y += ev.value; + mouse_scale_y(ev.value); } } } diff --git a/src/qt/evdev_mouse.hpp b/src/qt/evdev_mouse.hpp index 7681771c63..0b0b8b26fb 100644 --- a/src/qt/evdev_mouse.hpp +++ b/src/qt/evdev_mouse.hpp @@ -1,4 +1,3 @@ #ifdef EVDEV_INPUT void evdev_init(); -void evdev_mouse_poll(); #endif diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po new file mode 100644 index 0000000000..483e6ee531 --- /dev/null +++ b/src/qt/languages/ca-ES.po @@ -0,0 +1,1226 @@ +msgid "&Action" +msgstr "&Acció" + +msgid "&Keyboard requires capture" +msgstr "&Teclat requereix captura" + +msgid "&Right CTRL is left ALT" +msgstr "CTRL &dret és ALT esquerre" + +msgid "&Hard Reset..." +msgstr "&Reinicialització completa..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausa" + +msgid "E&xit..." +msgstr "&Sortir..." + +msgid "&View" +msgstr "&Vista" + +msgid "&Hide status bar" +msgstr "&Amagar barra d'estat" + +msgid "Hide &toolbar" +msgstr "Amagar &barra d'eines" + +msgid "&Resizeable window" +msgstr "&Finestra redimensionable" + +msgid "R&emember size && position" +msgstr "&Recordar mida i posició" + +msgid "Re&nderer" +msgstr "Re&nderitzador" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "E&specificar dimensions..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orçar ràtio 4:3" + +msgid "&Window scale factor" +msgstr "&Factor d'escalat de finestra" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "&Mètode de filtrat" + +msgid "&Nearest" +msgstr "&Més proper" + +msgid "&Linear" +msgstr "&Lineal" + +msgid "Hi&DPI scaling" +msgstr "&Escalat alta densitat" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "&Pantalla completa\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "Escalat pantalla completa" + +msgid "&Full screen stretch" +msgstr "&Estirar" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Píxels quadrats (Mant. aspecte)" + +msgid "&Integer scale" +msgstr "&Escala de valor enter" + +msgid "4:&3 Integer scale" +msgstr "Escala de valor enter 4:&3" + +msgid "E&GA/(S)VGA settings" +msgstr "&Ajustaments EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Monitor VGA invertit" + +msgid "VGA screen &type" +msgstr "&Tipus de pantalla VGA" + +msgid "RGB &Color" +msgstr "RGB &Color" + +msgid "&RGB Grayscale" +msgstr "RGB &Grisos" + +msgid "&Amber monitor" +msgstr "Monitor & Ambre" + +msgid "&Green monitor" +msgstr "Monitor &Verd" + +msgid "&White monitor" +msgstr "Monitor &Blanc" + +msgid "Grayscale &conversion type" +msgstr "&Conversió a grisos" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Mitjana" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Canviar contrast per a pantalla &monocroma" + +msgid "&Media" +msgstr "&Mitjans" + +msgid "&Tools" +msgstr "&Eines" + +msgid "&Settings..." +msgstr "&Ajustaments..." + +msgid "&Update status bar icons" +msgstr "&Actualitzar icones a la barra d'estat" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Prendre c&aptura\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferències..." + +msgid "Enable &Discord integration" +msgstr "Habilita la integració amb el &Discord" + +msgid "Sound &gain..." +msgstr "&Guany de so..." + +msgid "Begin trace\tCtrl+T" +msgstr "Començar traça\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Acabar traça\tCtrl+T" + +msgid "&Help" +msgstr "&Ajuda" + +msgid "&Documentation..." +msgstr "&Documentació..." + +msgid "&About 86Box..." +msgstr "&Quant a 86Box..." + +msgid "&New image..." +msgstr "&Nova imatge..." + +msgid "&Existing image..." +msgstr "Imatge &Existent..." + +msgid "Existing image (&Write-protected)..." +msgstr "Imatge Existent (&Només-lectura)..." + +msgid "&Record" +msgstr "&Gravar" + +msgid "&Play" +msgstr "&Reproduir" + +msgid "&Rewind to the beginning" +msgstr "&Rebobinar a l'inici" + +msgid "&Fast forward to the end" +msgstr "&Avanç ràpid al final" + +msgid "E&ject" +msgstr "E&xtreure" + +msgid "&Image..." +msgstr "&Imatge..." + +msgid "E&xport to 86F..." +msgstr "E&xportar a 86F..." + +msgid "&Mute" +msgstr "&Silenciar" + +msgid "E&mpty" +msgstr "E&xtreure disc" + +msgid "&Reload previous image" +msgstr "&Recarregar imatge prèvia" + +msgid "&Folder..." +msgstr "&Carpeta..." + +msgid "Target &framerate" +msgstr "&Taxa de refresc objectiu" + +msgid "&Sync with video" +msgstr "&Sincronitzar amb vídeo" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Seleccionar shader..." + +msgid "&Remove shader" +msgstr "&Eliminar shader" + +msgid "Preferences" +msgstr "Preferències" + +msgid "Sound Gain" +msgstr "Guany de So" + +msgid "New Image" +msgstr "Nova Imatge" + +msgid "Settings" +msgstr "Ajustaments" + +msgid "Specify Main Window Dimensions" +msgstr "Especificar Dimensions de la Finestra Principal" + +msgid "OK" +msgstr "D'acord" + +msgid "Cancel" +msgstr "Anuŀlació" + +msgid "Save these settings as &global defaults" +msgstr "Salvar aquests paràmetres com per &defecte globalment" + +msgid "&Default" +msgstr "&Per defecte" + +msgid "Language:" +msgstr "Idioma:" + +msgid "Icon set:" +msgstr "Conjunt d'icones:" + +msgid "Gain" +msgstr "Guany" + +msgid "File name:" +msgstr "Nom del fitxer:" + +msgid "Disk size:" +msgstr "Grandària de disc:" + +msgid "RPM mode:" +msgstr "Mode RPM:" + +msgid "Progress:" +msgstr "Progrés:" + +msgid "Width:" +msgstr "Amplada:" + +msgid "Height:" +msgstr "Alçada:" + +msgid "Lock to this size" +msgstr "Bloquejar aquesta mida" + +msgid "Machine type:" +msgstr "Tipus de màquina:" + +msgid "Machine:" +msgstr "Màquina:" + +msgid "Configure" +msgstr "Configurar" + +msgid "CPU type:" +msgstr "Tipus de CPU:" + +msgid "Speed:" +msgstr "Velocitat:" + +msgid "Frequency:" +msgstr "Freqüència:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Estats en espera:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memòria:" + +msgid "Time synchronization" +msgstr "Sincronització horària" + +msgid "Disabled" +msgstr "Desactuvat" + +msgid "Enabled (local time)" +msgstr "Activat (hora local)" + +msgid "Enabled (UTC)" +msgstr "Activat (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recopilador Dinàmic" + +msgid "Video:" +msgstr "Vídeo:" + +msgid "Voodoo Graphics" +msgstr "Gràfics Voodoo" + +msgid "IBM 8514/A Graphics" +msgstr "Gràfics IBM 8514/A" + +msgid "XGA Graphics" +msgstr "Gràfics XGA" + +msgid "Mouse:" +msgstr "Ratolí:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card #1:" +msgstr "Targeta de so 1:" + +msgid "Sound card #2:" +msgstr "Targeta de so 2:" + +msgid "Sound card #3:" +msgstr "Targeta de so 3:" + +msgid "Sound card #4:" +msgstr "Targeta de so 4:" + +msgid "MIDI Out Device:" +msgstr "Dispositiu de sortida MIDI:" + +msgid "MIDI In Device:" +msgstr "Dispositiu d'entrada MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autònom" + +msgid "Use FLOAT32 sound" +msgstr "Usar so FLOAT32" + +msgid "FM synth driver" +msgstr "Manejador de sintet. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (més acurat)" + +msgid "YMFM (faster)" +msgstr "YMFM (més ràpid)" + +msgid "Network type:" +msgstr "Tipus de xarxa:" + +msgid "PCap device:" +msgstr "Dispositiu PCap:" + +msgid "Network adapter:" +msgstr "Adaptador de xarxa:" + +msgid "COM1 Device:" +msgstr "Dispositiu COM1:" + +msgid "COM2 Device:" +msgstr "Dispositiu COM2:" + +msgid "COM3 Device:" +msgstr "Dispositiu COM3:" + +msgid "COM4 Device:" +msgstr "Dispositiu COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositiu LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositiu LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositiu LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositiu LPT4:" + +msgid "Serial port 1" +msgstr "Port sèrie 1" + +msgid "Serial port 2" +msgstr "Port sèrie 2" + +msgid "Serial port 3" +msgstr "Port sèrie 3" + +msgid "Serial port 4" +msgstr "Port sèrie 4" + +msgid "Parallel port 1" +msgstr "Port paral·lel 1" + +msgid "Parallel port 2" +msgstr "Port paral·lel 2" + +msgid "Parallel port 3" +msgstr "Port paral·lel 3" + +msgid "Parallel port 4" +msgstr "Port paral·lel 4" + +msgid "HD Controller:" +msgstr "Controlador de HD:" + +msgid "FD Controller:" +msgstr "Controlador de FD:" + +msgid "Tertiary IDE Controller" +msgstr "Controlador IDE terciari" + +msgid "Quaternary IDE Controller" +msgstr "Controlador IDE quaternari" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controlador 1:" + +msgid "Controller 2:" +msgstr "Controlador 2:" + +msgid "Controller 3:" +msgstr "Controlador 3:" + +msgid "Controller 4:" +msgstr "Controlador 4:" + +msgid "Cassette" +msgstr "Casset" + +msgid "Hard disks:" +msgstr "Discs durs:" + +msgid "&New..." +msgstr "&Nou..." + +msgid "&Existing..." +msgstr "&Existent..." + +msgid "&Remove" +msgstr "E&liminar" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "E&specificar..." + +msgid "Sectors:" +msgstr "Sectors:" + +msgid "Heads:" +msgstr "Caps:" + +msgid "Cylinders:" +msgstr "Cilindres:" + +msgid "Size (MB):" +msgstr "Mida (MB):" + +msgid "Type:" +msgstr "Tipus:" + +msgid "Image Format:" +msgstr "Format d'imatge:" + +msgid "Block Size:" +msgstr "Mida del bloc:" + +msgid "Floppy drives:" +msgstr "Unitats de disquet:" + +msgid "Turbo timings" +msgstr "Temps turbo" + +msgid "Check BPB" +msgstr "Comprovar BPB" + +msgid "CD-ROM drives:" +msgstr "Unitats de CD-ROM:" + +msgid "Earlier drive" +msgstr "Unitat anterior" + +msgid "MO drives:" +msgstr "Unitats MO:" + +msgid "ZIP drives:" +msgstr "Unitats ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Expansió de memòria ISA" + +msgid "Card 1:" +msgstr "Targeta 1:" + +msgid "Card 2:" +msgstr "Targeta 2:" + +msgid "Card 3:" +msgstr "Targeta 3:" + +msgid "Card 4:" +msgstr "Targeta 4:" + +msgid "ISABugger device" +msgstr "Dispositiu ISABugger" + +msgid "POST card" +msgstr "Targeta POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Error" + +msgid "Fatal error" +msgstr "Error fatal" + +msgid " - PAUSED" +msgstr " - EN PAUSA" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Premeu Ctrl+Alt+PgDn per tornar al mode de finestra." + +msgid "Speed" +msgstr "Velocitat" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Imatges ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box no ha pogut trobar cap imatge ROM utilitzable.\n\nSi us plau, descarregueu un conjunt de ROM i extreu-lo al directori \"roms\"." + +msgid "(empty)" +msgstr "(buit)" + +msgid "All files" +msgstr "Tots els fitxers" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "All images" +msgstr "Totes les imatges" + +msgid "Basic sector images" +msgstr "Imatges sectorials bàsiques" + +msgid "Surface images" +msgstr "Imatges superficials" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "La màquina \"%hs\" no està disponible perquè falten ROM al directori roms/machines. Canvi a una màquina disponible." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "La targeta de vídeo \"%hs\" no està disponible perquè falten ROM al directori roms/video. Canvi a una targeta de vídeo disponible." + +msgid "Machine" +msgstr "Màquina" + +msgid "Display" +msgstr "Vídeo" + +msgid "Input devices" +msgstr "Dispositius d'entrada" + +msgid "Sound" +msgstr "So" + +msgid "Network" +msgstr "Xarxa" + +msgid "Ports (COM & LPT)" +msgstr "Ports (COM i LPT)" + +msgid "Storage controllers" +msgstr "Controladors d'emmagatzematge" + +msgid "Hard disks" +msgstr "Discs durs" + +msgid "Floppy & CD-ROM drives" +msgstr "Unitats de disquet i CD-ROM" + +msgid "Other removable devices" +msgstr "Altres dispositius extraïbles" + +msgid "Other peripherals" +msgstr "Altres perifèrics" + +msgid "Click to capture mouse" +msgstr "Feu clic per capturar el ratolí" + +msgid "Press F8+F12 to release mouse" +msgstr "Premeu F8+F12 per alliberar el ratolí" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Premeu F8+F12 o el botó central per alliberar el ratolí" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "Fitxer" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "No has estat possible inicialitzar el renderitzador de vídeo." + +msgid "Default" +msgstr "Per defecte" + +msgid "%i estat(s) d'espera" +msgstr "%i estado(s) de Espera" + +msgid "Type" +msgstr "Tipus" + +msgid "Failed to set up PCap" +msgstr "No s'ha pogut configurar PCap" + +msgid "No PCap devices found" +msgstr "No s'han trobat dispositius PCap" + +msgid "Invalid PCap device" +msgstr "El dispositiu PCap no és vàlid" + +msgid "Standard 2-button joystick(s)" +msgstr "Joystick(s) estàndard de 2 botons" + +msgid "Standard 4-button joystick" +msgstr "Joystick(s) estàndard de 4 botons" + +msgid "Standard 6-button joystick" +msgstr "Joystick(s) estàndard de 6 botons" + +msgid "Standard 8-button joystick" +msgstr "Joystick(s) estàndard de 8 botons" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Cap" + +msgid "Unable to load keyboard accelerators." +msgstr "No has estat possible carregar els acceleradors del teclat." + +msgid "Unable to register raw input." +msgstr "No has estat possible registrar l'entrada en brut." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquet %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Imatges avançates del sector" + +msgid "Flux images" +msgstr "Imatges de flux" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Esteu segur que voleu restablir la màquina emulada?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Esteu segur que voleu sortir de 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "No es pot inicialitzar Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Imatges MO" + +msgid "Welcome to 86Box!" +msgstr "Benvingut a 86Box!" + +msgid "Internal controller" +msgstr "Controlador intern" + +msgid "Exit" +msgstr "Sortir" + +msgid "No ROMs found" +msgstr "No s'ha trobat cap ROM" + +msgid "Do you want to save the settings?" +msgstr "Voleu desar les configuracions?" + +msgid "This will hard reset the emulated machine." +msgstr "Es farà una reinicialització completa de la màquina emulada." + +msgid "Save" +msgstr "Desar" + +msgid "About 86Box" +msgstr "Quant a 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulador d'ordinadors antics\n\nAutors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne i altres.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho i altres.\n\nAlliberat sota la GNU General Public License versió 2 o posterior. Veure LLICENSE per a més informació." + +msgid "Hardware not available" +msgstr "Maquinari no disponible" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Assegureu-vos que el libpcap està instal·lat i que està en una connexió de xarxa compatible amb libpcap." + +msgid "Invalid configuration" +msgstr "Configuració invàlida" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica postScript es desarà com a fitxer PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Entrant en mode pantalla completa" + +msgid "Don't show this message again" +msgstr "No mostreu més aquest missatge" + +msgid "Don't exit" +msgstr "No sortir" + +msgid "Reset" +msgstr "Resetejar" + +msgid "Don't reset" +msgstr "No resetejar" + +msgid "CD-ROM images" +msgstr "Imatges de CD-ROM" + +msgid "%hs Device Configuration" +msgstr "%hs Configuració de Dispositiu" + +msgid "Monitor in sleep mode" +msgstr "Monitor en mode estalvi" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Opcions OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "S'està carregant una configuració no suportada" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "El Filtratge de tipus de CPU basat en màquina seleccionada està deshabilitat per a aquesta màquina.\n\nAixò fa possible seleccionar una CPU que sigui incompatible amb aquesta màquina. Per això, poden aparèixer incompatibilitat amb la BIOS de la màquina o un altre programari.\n\nActivar aquest ajustament no està oficialment suportat i qualsevol informe de fallada pot ser tancat com a invàlid." + +msgid "Continue" +msgstr "Continuar" + +msgid "Cassette: %s" +msgstr "Casset: %s" + +msgid "Cassette images" +msgstr "Imatges de casset" + +msgid "Cartridge %i: %ls" +msgstr "Cartutx %i: %ls" + +msgid "Cartridge images" +msgstr "Imatges de cartutx" + +msgid "Error initializing renderer" +msgstr "Error en inicialitzar el renderitzador" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "No has estat possible inicialitzar el renderitzador OpenGL (3.0 Core). Utilitzar un altre renderitzador." + +msgid "Resume execution" +msgstr "Reprendre l'execució" + +msgid "Pause execution" +msgstr "Pausar l'execució" + +msgid "Press Ctrl+Alt+Del" +msgstr "Pulsar Ctrl+Alt+Supr" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Pulsar Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Reinicialització completa" + +msgid "ACPI shutdown" +msgstr "Apagada ACPI" + +msgid "Hard disk (%s)" +msgstr "Disc dur (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Les unitats de CD-ROM MFM/RLL o ESDI no van existir mai" + +msgid "Custom..." +msgstr "Personalitzat..." + +msgid "Custom (large)..." +msgstr "Personalitzat (gran)..." + +msgid "Add New Hard Disk" +msgstr "Afegir disc dur nou" + +msgid "Add Existing Hard Disk" +msgstr "Afegir disc dur existent" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Les imatges de disc HDI no poden superar els 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Les imatges del disc no poden superar els 127 GB." + +msgid "Hard disk images" +msgstr "Imatges del disc dur" + +msgid "Unable to read file" +msgstr "No has estat possible llegir el fitxer" + +msgid "Unable to write file" +msgstr "No has estat possible escriure el fitxer" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Les imatges HDI o HDX amb una mida de sector diferent de 512 no s'admeten." + +msgid "USB is not yet supported" +msgstr "L'USB encara no s'admete" + +msgid "Disk image file already exists" +msgstr "El fitxer d'imatge de disc ja existeix" + +msgid "Please specify a valid file name." +msgstr "Especifiqueu un nom de fitxer vàlid." + +msgid "Disk image created" +msgstr "La imatge de disc ha estat creada" + +msgid "Make sure the file exists and is readable." +msgstr "Assegureu-vos que el fitxer existeix i és llegible." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Assegureu-vos que el fitxer s'està desant en un directori que es pugui escriure." + +msgid "Disk image too large" +msgstr "La imatge del disc és massa gran" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Recordeu particionar i formatar la unitat de nova creació." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "El fitxer seleccionat se sobreescriurà. Esteu segur que voleu utilitzar-lo?" + +msgid "Unsupported disk image" +msgstr "Imatge de disc no compatible" + +msgid "Overwrite" +msgstr "Sobreescriure" + +msgid "Don't overwrite" +msgstr "No sobreescriure" + +msgid "Raw image (.img)" +msgstr "Imatge crua (.img)" + +msgid "HDI image (.hdi)" +msgstr "Imatge HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Imatge HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD de mida fixa (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD de mida dinàmica (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD diferencial (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocs grans (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocs petits (512 KB)" + +msgid "VHD files" +msgstr "Fitxers VHD" + +msgid "Select the parent VHD" +msgstr "Seleccioneu el VHD pare" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Això pot ser perquè la imatge pare es va modificar després que la imatge diferencial es creés.\n\nTambé pot passar si les imatges van ser mogudes o copiades, o per una fallada al programa que va crear aquest disc.\n\n¿ Voleu corregir els registres de temps?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Les marques de temps del pare i el fill no coincideixen" + +msgid "Could not fix VHD timestamp." +msgstr "No has estat possible corregir la marca de temps del VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (clúster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (clúster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "RPM perfectes" + +msgid "1% below perfect RPM" +msgstr "1% per sota de RPM perfectes" + +msgid "1.5% below perfect RPM" +msgstr "1.5% per sota de RPM perfectes" + +msgid "2% below perfect RPM" +msgstr "2% per sota de RPM perfectes" + +msgid "(System Default)" +msgstr "(Per defecte del sistema)" + +msgid "Failed to initialize network driver" +msgstr "No has estat possible inicialitzar el controlador de xarxa" + +msgid "The network configuration will be switched to the null driver" +msgstr "La configuració de la xarxa es canviarà al controlador nul" + +msgid "Mouse sensitivity:" +msgstr "Sensibilitat del ratolí:" + +msgid "Select media images from program working directory" +msgstr "Seleccioneu imatges multimèdia del directori de treball del programa" + +msgid "PIT mode:" +msgstr "Mode PIT:" + +msgid "Auto" +msgstr "Automàtic" + +msgid "Slow" +msgstr "Lent" + +msgid "Fast" +msgstr "Ràpid" + +msgid "&Auto-pause on focus loss" +msgstr "&Pausa automàtica en la pèrdua del focus" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 422a00947d..84c7950927 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -124,6 +124,9 @@ msgstr "&Zachovat poměr stran" msgid "&Integer scale" msgstr "&Celočíselné škálování" +msgid "4:&3 Integer scale" +msgstr "4:&3 Celočíselné škálování" + msgid "E&GA/(S)VGA settings" msgstr "Nastavení pro E&GA a (S)VGA" @@ -349,6 +352,9 @@ msgstr "Procesor:" msgid "Speed:" msgstr "Rychlost:" +msgid "Frequency:" +msgstr "Frekvence:" + msgid "FPU:" msgstr "Koprocesor:" @@ -382,8 +388,8 @@ msgstr "Grafika:" msgid "Voodoo Graphics" msgstr "Použít grafický akcelerátor Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafika IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvuková karta 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvuková karta 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvuková karta 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvuková karta 4:" msgid "MIDI Out Device:" @@ -656,7 +662,7 @@ msgid "(empty)" msgstr "(prázdné)" msgid "All files" -msgstr "All files" +msgstr "Všechny soubory" msgid "Turbo" msgstr "Turbo" @@ -724,9 +730,6 @@ msgstr "Stiskněte F8+F12 pro uvolnění myši" msgid "Press F8+F12 or middle button to release mouse" msgstr "Stiskněte F8+F12 nebo prostřední tlačítko pro uvolnění myši" -msgid "Unable to initialize FluidSynth" -msgstr "Nastala chyba při inicializaci knihovny FluidSynth." - msgid "Bus" msgstr "Sběrnice" @@ -811,12 +814,6 @@ msgstr "Rozšířené sektorové obrazy" msgid "Flux images" msgstr "Obrazy magnetického toku" -msgid "Unable to initialize FreeType" -msgstr "Nastala chyba při inicializaci knihovny FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Opravdu chcete resetovat emulovaný počítač?" @@ -859,8 +856,8 @@ msgstr "O programu 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Emulátor starých počítačů\n\nAutoři: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." msgid "Hardware not available" msgstr "Hardware není dostupný" @@ -877,15 +874,6 @@ msgstr "Ujistěte se, že je nainstalován libpcap a používáte síťové při msgid "Invalid configuration" msgstr "Neplatná konfigurace" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " je potřeba pro emulaci ESC/P tiskáren." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " je potřeba pro MIDI výstup přes knihovnu FluidSynth." - msgid "Entering fullscreen mode" msgstr "Vstup do režimu celé obrazovky" @@ -956,10 +935,10 @@ msgid "Cartridge images" msgstr "Obrazy cartridge" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Chyba při inicializaci vykreslovače" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Vykreslovač OpenGL (3.0 Core) se nepodařilo inicializovat. Použijte jiný renderer." msgid "Resume execution" msgstr "Obnovit" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Výchozí nastavení systému)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Nepodařilo se inicializovat síťový ovladač" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Konfigurace sítě bude přepnuta na nulový ovladač" + +msgid "Mouse sensitivity:" +msgstr "Citlivost myší:" + +msgid "Select media images from program working directory" +msgstr "Výběr mediálních obrazů z pracovního adresáře programu" + +msgid "PIT mode:" +msgstr "Režim PIT:" + +msgid "Auto" +msgstr "Automatický" + +msgid "Slow" +msgstr "Pomalý" + +msgid "Fast" +msgstr "Rychlý" +msgid "&Auto-pause on focus loss" +msgstr "&Automatická pauza při ztrátě zaměření okna" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 5685994490..4a4fde3c29 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -98,7 +98,7 @@ msgid "Filter method" msgstr "Filteringmethode" msgid "&Nearest" -msgstr "&Nearest" +msgstr "&Nächst" msgid "&Linear" msgstr "&Linear" @@ -124,6 +124,9 @@ msgstr "&Quadratische Pixel (Seitenverhältnis beibehalten)" msgid "&Integer scale" msgstr "&Integer-Skalierung" +msgid "4:&3 Integer scale" +msgstr "4:&3 Integer-Skalierung" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA-Einstellungen" @@ -349,6 +352,9 @@ msgstr "CPU-Typ:" msgid "Speed:" msgstr "Takt:" +msgid "Frequency:" +msgstr "Frequenz:" + msgid "FPU:" msgstr "FPU-Einheit:" @@ -382,8 +388,8 @@ msgstr "Videokarte:" msgid "Voodoo Graphics" msgstr "Voodoo-Grafik" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-Grafik" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-Grafik" msgid "XGA Graphics" msgstr "XGA-Grafik" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Soundkarte 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Soundkarte 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Soundkarte 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Soundkarte 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Bitte F8+F12 zur Mausfreigabe drücken" msgid "Press F8+F12 or middle button to release mouse" msgstr "Bitte F8+F12 oder die mittlere Maustaste zur Mausfreigabe drücken" -msgid "Unable to initialize FluidSynth" -msgstr "FluidSynth konnte nicht initialisiert werden" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Fortgeschrittene Sektorimages" msgid "Flux images" msgstr "Fluximages" -msgid "Unable to initialize FreeType" -msgstr "FreeType konnte nicht initialisiert werden" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" @@ -859,8 +856,8 @@ msgstr "Über 86Box" msgid "86Box v" msgstr "86Box Version " -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Ein Emulator für alte Computer\n\nAutoren: Sarah Walker, Miran Grča, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." msgid "Hardware not available" msgstr "Hardware nicht verfügbar" @@ -877,15 +874,6 @@ msgstr "Bitte stellen Sie sicher, dass libpcap installiert ist und sie eine libp msgid "Invalid configuration" msgstr "Ungültige Konfiguration" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " wird für die ESC/P-Druckeremulation benötigt." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " wird für die FluidSynth-MIDI-Ausgabe benötigt." - msgid "Entering fullscreen mode" msgstr "Vollbildmodus wird aktiviert" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Systemstandard)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Netzwerktreiber konnte nicht initialisiert werden" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Die Netzwerkkonfiguration wird auf den Nulltreiber umgestellt" + +msgid "Mouse sensitivity:" +msgstr "Empfindlichkeit der Maus:" + +msgid "Select media images from program working directory" +msgstr "Medienbilder aus dem Arbeitsverzeichnis des Programms auswählen" + +msgid "PIT mode:" +msgstr "PIT-Modus:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Langsam" + +msgid "Fast" +msgstr "Schnell" +msgid "&Auto-pause on focus loss" +msgstr "&Auto-Pause bei Fokusverlust" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index ddf6e7ef00..031a365c06 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -124,6 +124,9 @@ msgstr "&Square pixels (Keep ratio)" msgid "&Integer scale" msgstr "&Integer scale" +msgid "4:&3 Integer scale" +msgstr "4:&3 Integer scale" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA settings" @@ -349,6 +352,9 @@ msgstr "CPU type:" msgid "Speed:" msgstr "Speed:" +msgid "Frequency:" +msgstr "Frequency:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" @@ -406,17 +412,17 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" -msgstr "Sound card 1:" +msgid "Sound card #1:" +msgstr "Sound card #1:" -msgid "Sound card 2:" -msgstr "Sound card 2:" +msgid "Sound card #2:" +msgstr "Sound card #2:" -msgid "Sound card 3:" -msgstr "Sound card 3:" +msgid "Sound card #3:" +msgstr "Sound card #3:" -msgid "Sound card 4:" -msgstr "Sound card 4:" +msgid "Sound card #4:" +msgstr "Sound card #4:" msgid "MIDI Out Device:" msgstr "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Press F8+F12 to release mouse" msgid "Press F8+F12 or middle button to release mouse" msgstr "Press F8+F12 or middle button to release mouse" -msgid "Unable to initialize FluidSynth" -msgstr "Unable to initialize FluidSynth" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize FreeType" -msgstr "Unable to initialize FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" @@ -859,8 +856,8 @@ msgstr "About 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgid "Hardware not available" msgstr "Hardware not available" @@ -877,15 +874,6 @@ msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible msgid "Invalid configuration" msgstr "Invalid configuration" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " is required for ESC/P printer emulation." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " is required for FluidSynth MIDI output." - msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -1225,3 +1204,23 @@ msgstr "Failed to initialize network driver" msgid "The network configuration will be switched to the null driver" msgstr "The network configuration will be switched to the null driver" +msgid "Mouse sensitivity:" +msgstr "Mouse sensitivity:" + +msgid "Select media images from program working directory" +msgstr "Select media images from program working directory" + +msgid "PIT mode:" +msgstr "PIT mode:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Slow" + +msgid "Fast" +msgstr "Fast" + +msgid "&Auto-pause on focus loss" +msgstr "&Auto-pause on focus loss" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 09adcdb760..06a4b60f1c 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -124,6 +124,9 @@ msgstr "&Square pixels (Keep ratio)" msgid "&Integer scale" msgstr "&Integer scale" +msgid "4:&3 Integer scale" +msgstr "4:&3 Integer scale" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA settings" @@ -349,6 +352,9 @@ msgstr "CPU type:" msgid "Speed:" msgstr "Speed:" +msgid "Frequency:" +msgstr "Frequency:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" @@ -406,17 +412,17 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" -msgstr "Sound card 1:" +msgid "Sound card #1:" +msgstr "Sound card #1:" -msgid "Sound card 2:" -msgstr "Sound card 2:" +msgid "Sound card #2:" +msgstr "Sound card #2:" -msgid "Sound card 3:" -msgstr "Sound card 3:" +msgid "Sound card #3:" +msgstr "Sound card #3:" -msgid "Sound card 4:" -msgstr "Sound card 4:" +msgid "Sound card #4:" +msgstr "Sound card #4:" msgid "MIDI Out Device:" msgstr "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Press F8+F12 to release mouse" msgid "Press F8+F12 or middle button to release mouse" msgstr "Press F8+F12 or middle button to release mouse" -msgid "Unable to initialize FluidSynth" -msgstr "Unable to initialize FluidSynth" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Advanced sector images" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize FreeType" -msgstr "Unable to initialize FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Unable to initialize SDL, SDL2.dll is required" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Are you sure you want to hard reset the emulated machine?" @@ -859,8 +856,8 @@ msgstr "About 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgid "Hardware not available" msgstr "Hardware not available" @@ -877,15 +874,6 @@ msgstr "Make sure libpcap is installed and that you are on a libpcap-compatible msgid "Invalid configuration" msgstr "Invalid configuration" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " is required for ESC/P printer emulation." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " is required for FluidSynth MIDI output." - msgid "Entering fullscreen mode" msgstr "Entering fullscreen mode" @@ -1225,3 +1204,23 @@ msgstr "Failed to initialize network driver" msgid "The network configuration will be switched to the null driver" msgstr "The network configuration will be switched to the null driver" +msgid "Mouse sensitivity:" +msgstr "Mouse sensitivity:" + +msgid "Select media images from program working directory" +msgstr "Select media images from program working directory" + +msgid "PIT mode:" +msgstr "PIT mode:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Slow" + +msgid "Fast" +msgstr "Fast" + +msgid "&Auto-pause on focus loss" +msgstr "&Auto-pause on focus loss" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 8fbc442b98..60ac5fb5c9 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -29,7 +29,7 @@ msgid "&Hide status bar" msgstr "&Ocultar barra de estado" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Ocultar &barra de herramientas" msgid "&Resizeable window" msgstr "&Ventana redimensionable" @@ -124,8 +124,11 @@ msgstr "&Píxeles cuadrados (Mant. aspecto)" msgid "&Integer scale" msgstr "&Escalado valor entero" +msgid "4:&3 Integer scale" +msgstr "Escalado valor entero 4:&3" + msgid "E&GA/(S)VGA settings" -msgstr "&Ajustes EGA/(S)VGA" +msgstr "&Configuraciones EGA/(S)VGA" msgid "&Inverted VGA monitor" msgstr "&Monitor VGA invertido" @@ -173,7 +176,7 @@ msgid "&Tools" msgstr "&Herramientas" msgid "&Settings..." -msgstr "&Ajustes..." +msgstr "&Configuraciones..." msgid "&Update status bar icons" msgstr "&Actualizar iconos en barra de estado" @@ -287,7 +290,7 @@ msgid "New Image" msgstr "Nueva Imagen" msgid "Settings" -msgstr "Ajustes" +msgstr "Configuraciones" msgid "Specify Main Window Dimensions" msgstr "Especificar Dimensiones de la Ventana Principal" @@ -299,7 +302,7 @@ msgid "Cancel" msgstr "Cancelar" msgid "Save these settings as &global defaults" -msgstr "Salvar estos ajustes como por &defecto globalmente" +msgstr "Salvar estos configuraciones como por &defecto globalmente" msgid "&Default" msgstr "&Por defecto" @@ -349,6 +352,9 @@ msgstr "Tipo de CPU:" msgid "Speed:" msgstr "Velocidad:" +msgid "Frequency:" +msgstr "Frecuencia:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" @@ -406,16 +412,16 @@ msgstr "Mando 3..." msgid "Joystick 4..." msgstr "Mando 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Tarjeta de sonido 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Tarjeta de sonido 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Tarjeta de sonido 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Tarjeta de sonido 4:" msgid "MIDI Out Device:" @@ -650,13 +656,13 @@ msgid "ZIP images" msgstr "Imagenes ZIP" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descarga un grupo de imágenes y extráelas en el directorio \"roms\"." +msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descargue un conjunte de ROMs y extráigalo en el directorio \"roms\"." msgid "(empty)" msgstr "(vacío)" msgid "All files" -msgstr "All files" +msgstr "Todos los archivos" msgid "Turbo" msgstr "Turbo" @@ -716,16 +722,13 @@ msgid "Other peripherals" msgstr "Otros periféricos" msgid "Click to capture mouse" -msgstr "Haz click para capturar el ratón" +msgstr "Haga click para capturar el ratón" msgid "Press F8+F12 to release mouse" -msgstr "Pulsa F8+F12 para liberar el ratón" +msgstr "Pulse F8+F12 para liberar el ratón" msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pulsa F8+F12 o el botón central para liberar el ratón" - -msgid "Unable to initialize FluidSynth" -msgstr "Incapaz de inicializar FluidSynth" +msgstr "Pulse F8+F12 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -746,7 +749,7 @@ msgid "KB" msgstr "KB" msgid "Could not initialize the video renderer." -msgstr "Incapaz de inicializar el renderizador de vídeo." +msgstr "No fué posible inicializar el renderizador de vídeo." msgid "Default" msgstr "Por defecto" @@ -791,10 +794,10 @@ msgid "None" msgstr "Ninguno" msgid "Unable to load keyboard accelerators." -msgstr "Incapaz de cargar aceleradores de teclado." +msgstr "No fué posible cargar aceleradores de teclado." msgid "Unable to register raw input." -msgstr "Incapaz de registrar entrada directa." +msgstr "No fué posible registrar entrada directa." msgid "%u" msgstr "%u" @@ -806,25 +809,19 @@ msgid "Floppy %i (%s): %ls" msgstr "Disquete %i (%s): %ls" msgid "Advanced sector images" -msgstr "Advanced sector images" +msgstr "Imágenes avanzadas de sector" msgid "Flux images" -msgstr "Flux images" - -msgid "Unable to initialize FreeType" -msgstr "Incapaz de inicializar FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll" +msgstr "Imágenes de fluxo" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "¿Seguro que quieres resetear la máquina emulada?" +msgstr "¿Está seguro de que quieres hacer una reinicialización completa de la máquina emulada?" msgid "Are you sure you want to exit 86Box?" -msgstr "¿Seguro que quieres cerrar 86Box?" +msgstr "¿Está seguro de que quiere cerrar a 86Box?" msgid "Unable to initialize Ghostscript" -msgstr "Incapaz de inicializar Ghostscript" +msgstr "No fué posible inicializar Ghostscript" msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -845,10 +842,10 @@ msgid "No ROMs found" msgstr "No se encontraron ROMs" msgid "Do you want to save the settings?" -msgstr "¿Quieres guardar los ajustes?" +msgstr "¿Quiere guardar los configuraciones?" msgid "This will hard reset the emulated machine." -msgstr "Se hará hard reset de la máquina emulada." +msgstr "Se hará una reinicialización completa de la máquina emulada." msgid "Save" msgstr "Guardar" @@ -859,11 +856,11 @@ msgstr "Acerca de 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." msgid "Hardware not available" -msgstr "Hardware no disponible" +msgstr "Equipo no disponible" msgid "WinPcap" msgstr "WinPcap" @@ -877,15 +874,6 @@ msgstr "Asegúrate de que libpcap está instalado y de que estás en una conexi msgid "Invalid configuration" msgstr "Configuración inválida" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " es necesaria para emulación de impresión ESC/P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " es necesario para salida MIDI FluidSynth." - msgid "Entering fullscreen mode" msgstr "Entrando en modo pantalla completa" @@ -914,10 +893,10 @@ msgid "Don't exit" msgstr "No salir" msgid "Reset" -msgstr "Resetear" +msgstr "Reinicializar" msgid "Don't reset" -msgstr "No resetear" +msgstr "No reinicializar" msgid "CD-ROM images" msgstr "Imágenes de CD-ROM" @@ -935,10 +914,10 @@ msgid "OpenGL options" msgstr "Opciones OpenGL" msgid "You are loading an unsupported configuration" -msgstr "Estás cargando una configuración no soportada" +msgstr "Está cargando una configuración no soportada" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." +msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar esta configuración no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." msgid "Continue" msgstr "Continuar" @@ -956,28 +935,28 @@ msgid "Cartridge images" msgstr "Imágenes de Cartucho" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Error al inicializar el renderizador" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "No fué posible inicializar el renderizador OpenGL (3.0 Core). Utilice otro renderizador." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Retomar la ejecución" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Pausar la ejecución" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Pulsar Ctrl+Alt+Supr" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Pulsar Ctrl+Alt+Esc" msgid "Hard reset" msgstr "Hard reset" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "Parada ACPI" msgid "Hard disk (%s)" msgstr "Disco duro (%s)" @@ -989,7 +968,7 @@ msgid "%01i" msgstr "%01i" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI" +msgstr "Nunca existieron unidades de CD-ROM MFM/RLL o ESDI" msgid "Custom..." msgstr "A medida..." @@ -1094,7 +1073,7 @@ msgid "Parent and child disk timestamps do not match" msgstr "Las marcas de tiempo del padre e hijo no coinciden" msgid "Could not fix VHD timestamp." -msgstr "No se pudo corregir la marca de tiempo del VHD." +msgstr "No fué posible corregir la marca de tiempo del VHD." msgid "%01i:%02i" msgstr "%01i:%02i" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Por defecto del sistema)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "No fué posible inicializar el controlador de red" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "La configuración de red se cambiará al controlador nulo" + +msgid "Mouse sensitivity:" +msgstr "Sensibilidad del ratón:" + +msgid "Select media images from program working directory" +msgstr "Seleccionar imágenes de media del directorio de trabajo del programa" + +msgid "PIT mode:" +msgstr "Modalidad PIT:" + +msgid "Auto" +msgstr "Automática" + +msgid "Slow" +msgstr "Lenta" + +msgid "Fast" +msgstr "Rápida" +msgid "&Auto-pause on focus loss" +msgstr "&Pausa automática al perder el foco" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index d1c524558f..50ebffccb6 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -124,6 +124,9 @@ msgstr "&Tasasivuiset kuvapisteet (säilytä kuvasuhde)" msgid "&Integer scale" msgstr "&Kokonaislukuskaalaus" +msgid "4:&3 Integer scale" +msgstr "4:&3 Kokonaislukuskaalaus" + msgid "E&GA/(S)VGA settings" msgstr "&EGA/(S)VGA-asetukset" @@ -349,6 +352,9 @@ msgstr "Suorittimen tyyppi:" msgid "Speed:" msgstr "Nopeus:" +msgid "Frequency:" +msgstr "Taajuus:" + msgid "FPU:" msgstr "Apusuoritin:" @@ -382,8 +388,8 @@ msgstr "Näytönohjain:" msgid "Voodoo Graphics" msgstr "Voodoo-grafiikkasuoritin" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-grafiikkasuoritin" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-grafiikkasuoritin" msgid "XGA Graphics" msgstr "XGA-grafiikkasuoritin" @@ -406,16 +412,16 @@ msgstr "Peliohjain 3..." msgid "Joystick 4..." msgstr "Peliohjain 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Äänikortti 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Äänikortti 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Äänikortti 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Äänikortti 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Paina F8+F12 vapauttaaksesi hiiren" msgid "Press F8+F12 or middle button to release mouse" msgstr "Paina F8+F12 tai keskipainiketta vapauttaaksesi hiiren" -msgid "Unable to initialize FluidSynth" -msgstr "FluidSynthin alustus epäonnistui" - msgid "Bus" msgstr "Väylä" @@ -811,12 +814,6 @@ msgstr "Kehittyneet sektorilevykuvat" msgid "Flux images" msgstr "Flux-levykuvat" -msgid "Unable to initialize FreeType" -msgstr "FreeType:n alustus epäonnistui" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" @@ -859,8 +856,8 @@ msgstr "Tietoja 86Box:sta" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." msgid "Hardware not available" msgstr "Laitteisto ei ole saatavilla" @@ -877,15 +874,6 @@ msgstr "Varmista, että libpcap on asennettu ja että verkkoyhteytesi on libpcap msgid "Invalid configuration" msgstr "Virheelliset määritykset" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " vaaditaan ESC/P-tulostimen emuloimiseksi." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " vaaditaan FluidSynth MIDI-ulostuloa varten." - msgid "Entering fullscreen mode" msgstr "Siirrytään koko näytön tilaan" @@ -1220,9 +1199,28 @@ msgid "(System Default)" msgstr "(Järjestelmän oletus)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Verkkoajurin alustaminen epäonnistui" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Verkkokokoonpano vaihtuu nolla-ajuriin" + +msgid "Mouse sensitivity:" +msgstr "Hiiren herkkyys:" + +msgid "Select media images from program working directory" +msgstr "Valitse mediakuvat ohjelman työhakemistosta" + +msgid "PIT mode:" +msgstr "PIT-tila:" + +msgid "Auto" +msgstr "Automaattinen" + +msgid "Slow" +msgstr "Hidas" +msgid "Fast" +msgstr "Nopea" +msgid "&Auto-pause on focus loss" +msgstr "&Automaattinen tauko tarkennuksen hävitessä" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index f83c8f5fd3..52bccebd26 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -124,6 +124,9 @@ msgstr "pixels &Carrés(Keep ratio)" msgid "&Integer scale" msgstr "Echelle &Entière" +msgid "4:&3 Integer scale" +msgstr "Echelle Entière 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Réglages E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Type du processeur:" msgid "Speed:" msgstr "Vitesse:" +msgid "Frequency:" +msgstr "Fréquence:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Vidéo:" msgid "Voodoo Graphics" msgstr "Graphique Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Graphique IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Graphique IBM 8514/A" msgid "XGA Graphics" msgstr "Graphique XGA" @@ -406,16 +412,16 @@ msgstr "Manette 3..." msgid "Joystick 4..." msgstr "Manette 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Carte son 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Carte son 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Carte son 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Carte son 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Appuyer sur F8+F12 pour libérer la souris" msgid "Press F8+F12 or middle button to release mouse" msgstr "Appuyer sur F8+F12 ou le bouton central pour libérer la souris" -msgid "Unable to initialize FluidSynth" -msgstr "Impossible d'initialiser FluidSynth" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Images du secteur avancés" msgid "Flux images" msgstr "Images du flux" -msgid "Unable to initialize FreeType" -msgstr "Impossible d'initialiser FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossible d'initialiser SDL, SDL2.dll est nécessaire" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" @@ -859,8 +856,8 @@ msgstr "À propos de 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Un émulateur de vieux ordinateurs\n\nAuteurs: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." msgid "Hardware not available" msgstr "Matériel non disponible" @@ -877,15 +874,6 @@ msgstr "Assurez-vous que libpcap est installé et que vou utilisez une connexion msgid "Invalid configuration" msgstr "Configuration non valide" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " est nécessaire pour l'émulation de l'imprimante ESC/P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " est nécessaire pour la sortie MIDI FluidSynth." - msgid "Entering fullscreen mode" msgstr "Entrer en mode plein écran" @@ -956,28 +935,28 @@ msgid "Cartridge images" msgstr "Images cartouche" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Erreur d'initialisation du moteur de rendu" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Le moteur de rendu OpenGL (3.0 Core) n'a pas pu être initialisé. Utilisez un autre moteur de rendu." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Reprendre l'exécution" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Pause de l'exécution" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Appuyer sur Ctrl+Alt+Suppr." msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Appuyer sur Ctrl+Alt+Esc" msgid "Hard reset" msgstr "Hard reset" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "Arrêt ACPI" msgid "Hard disk (%s)" msgstr "Disque dur (%s)" @@ -1220,8 +1199,29 @@ msgid "(System Default)" msgstr "(Défaut du système)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Échec de l'initialisation du pilote réseau" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "La configuration du réseau passera au pilote nul" + +msgid "Mouse sensitivity:" +msgstr "Sensibilité de la souris:" + +msgid "Select media images from program working directory" +msgstr "Sélectionner des images dans le répertoire de travail du programme" + +msgid "PIT mode:" +msgstr "Mode PIT:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Lent" + +msgid "Fast" +msgstr "Rapide" + +msgid "&Auto-pause on focus loss" +msgstr "&Pause automatique à perte de mise au point" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 76973f796e..19b6a6e854 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -124,6 +124,9 @@ msgstr "&Kvadratni pikseli (zadrži omjer)" msgid "&Integer scale" msgstr "&Cijelobrojno skaliranje" +msgid "4:&3 Integer scale" +msgstr "4:&3 Cijelobrojno skaliranje" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA postavke" @@ -349,6 +352,9 @@ msgstr "Tip procesora:" msgid "Speed:" msgstr "Brzina:" +msgid "Frequency:" +msgstr "Frekvencija:" + msgid "FPU:" msgstr "FPU uređaj:" @@ -382,8 +388,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a grafika" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A grafika" msgid "XGA Graphics" msgstr "XGA grafika" @@ -406,16 +412,16 @@ msgstr "Palica za igru 3..." msgid "Joystick 4..." msgstr "Palica za igru 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvučna kartica 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvučna kartica 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvučna kartica 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvučna kartica 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Pritisnite F8+F12 za otpustanje miša" msgid "Press F8+F12 or middle button to release mouse" msgstr "Pritisnite F8+F12 ili srednji gumb miša za otpuštanje miša" -msgid "Unable to initialize FluidSynth" -msgstr "Nije moguće inicijalizirati FluidSynth" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Flux slike" -msgid "Unable to initialize FreeType" -msgstr "Nije moguće inicijalizirati FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jeste li sigurni da želite hard resetirati emulirani sistem?" @@ -859,8 +856,8 @@ msgstr "O programu 86Box" msgid "86Box v" msgstr "86Box verzija " -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Emulator starih računala\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." msgid "Hardware not available" msgstr "Hardver nije dostupan" @@ -877,15 +874,6 @@ msgstr "Provjerite je li libpcap instaliran i jeste li na mreži, kompadibilnoj msgid "Invalid configuration" msgstr "Nevažeća konfiguracija" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " je potrebno za emuliranje ESC/P pisača." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " je potrebno za FluidSynth MIDI izlaz." - msgid "Entering fullscreen mode" msgstr "Ulazim u cijelozaslonski način" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Zadana postavka operativnog sustava)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Neuspješno pokretanje mrežnog upravljačkog programa" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Konfiguracija mreže bit će prebačena na nulti upravljački program" + +msgid "Mouse sensitivity:" +msgstr "Osjetljivost miša:" + +msgid "Select media images from program working directory" +msgstr "Medijske slike su odabrane iz radnog direktorija programa" + +msgid "PIT mode:" +msgstr "PIT način:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Spori" + +msgid "Fast" +msgstr "Brzi" +msgid "&Auto-pause on focus loss" +msgstr "&Automatska pauza pri gubitku fokusa" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 2f812ba2e6..338d2ff5e1 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -124,6 +124,9 @@ msgstr "&Négyzetes képpontok (aránytartás)" msgid "&Integer scale" msgstr "&Egész tényezős nagyítás" +msgid "4:&3 Integer scale" +msgstr "4:&3 Egész tényezős nagyítás" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA beállítások" @@ -349,6 +352,9 @@ msgstr "Processzor:" msgid "Speed:" msgstr "Seb.:" +msgid "Frequency:" +msgstr "Frekvencia:" + msgid "FPU:" msgstr "FPU-egység:" @@ -382,8 +388,8 @@ msgstr "Videokártya:" msgid "Voodoo Graphics" msgstr "Voodoo-gyorsítókártya" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a-gyorsítókártya" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-gyorsítókártya" msgid "XGA Graphics" msgstr "XGA-gyorsítókártya" @@ -406,16 +412,16 @@ msgstr "Játékvez. 3..." msgid "Joystick 4..." msgstr "Játékvez. 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Hangkártya 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Hangkártya 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Hangkártya 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Hangkártya 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Nyomja meg az F8+F12-t az egér elengédéséhez" msgid "Press F8+F12 or middle button to release mouse" msgstr "Nyomja meg az F8+F12-t vagy a középső gombot az egér elengédéséhez" -msgid "Unable to initialize FluidSynth" -msgstr "Nem sikerült a FluidSynth inicializálása" - msgid "Bus" msgstr "Busz" @@ -811,12 +814,6 @@ msgstr "Továbbfejlesztett szektor képek" msgid "Flux images" msgstr "Flux képekfájlok" -msgid "Unable to initialize FreeType" -msgstr "A FreeType inicializálása nem lehetséges" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Biztosan szeretné újraindítani az emulált gépet?" @@ -859,8 +856,8 @@ msgstr "A 86Box névjegye" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Régi számítógépek emulátora\n\nFejlesztők: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." msgid "Hardware not available" msgstr "Hardver nem elérhető" @@ -877,15 +874,6 @@ msgstr "Győződjön meg hogy a(z) libpcap telepítve van és jelenleg a libpcap msgid "Invalid configuration" msgstr "Érvénytelen konfiguráció" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " szükséges az ESC/P nyomtató emulációhoz." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " szükséges a FluidSynth MIDI kimenethez." - msgid "Entering fullscreen mode" msgstr "Teljes képernyős módra váltás" @@ -962,22 +941,22 @@ msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer msgstr "Az OpenGL (3.0 Core) megjelenítő-motort nem sikerült inicializálni. Kérem használjon másik renderelőt." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Folytassa a végrehajtást" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Kivitelezés szüneteltetése" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Nyomja meg a Ctrl+Alt+Del" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Nyomja meg a Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "Hardveres újraindítás" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "ACPI leállítás" msgid "Hard disk (%s)" msgstr "Merevlemez (%s)" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(A rendszer nyelve)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Nem sikerült inicializálni a hálózati illesztőprogramot" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "A hálózati konfiguráció átvált a null illesztőprogramra" + +msgid "Mouse sensitivity:" +msgstr "Egér érzékenység:" + +msgid "Select media images from program working directory" +msgstr "Médiaképek kiválasztása a program munkakönyvtárából" + +msgid "PIT mode:" +msgstr "PIT üzemmód:" + +msgid "Auto" +msgstr "Automatikus" + +msgid "Slow" +msgstr "Lassú" + +msgid "Fast" +msgstr "Gyors" +msgid "&Auto-pause on focus loss" +msgstr "&Automatikus szünet fókuszvesztéskor" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index a9b3b7ce36..20c15c6564 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -124,6 +124,9 @@ msgstr "&Pixel quadrati (mantiene l'aspetto)" msgid "&Integer scale" msgstr "&Scala intera" +msgid "4:&3 Integer scale" +msgstr "Scala intera 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Impostazioni E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Tipo del CPU:" msgid "Speed:" msgstr "Veloc.:" +msgid "Frequency:" +msgstr "Frequenza:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Grafica Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafica IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafica IBM 8514/A" msgid "XGA Graphics" msgstr "Grafica XGA" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Scheda audio 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Scheda audio 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Scheda audio 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Scheda audio 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Premi F8+F12 per rilasciare il mouse" msgid "Press F8+F12 or middle button to release mouse" msgstr "Premi F8+F12 o pulsante centrale per rilasciare il mouse" -msgid "Unable to initialize FluidSynth" -msgstr "Impossibile inizializzare FluidSynth" - msgid "Bus" msgstr "Bus" @@ -811,12 +814,6 @@ msgstr "Immagini da settori avanzati" msgid "Flux images" msgstr "Immagini flusso" -msgid "Unable to initialize FreeType" -msgstr "Impossibile inizializzare FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Impossibile inizializzare SDL, SDL2.dll è necessario" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Sei sicuro di voler riavviare la macchina emulata?" @@ -859,8 +856,8 @@ msgstr "Informazioni su 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Un emulatore di computer vecchi\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." msgid "Hardware not available" msgstr "Hardware non disponibile" @@ -872,20 +869,11 @@ msgid "libpcap" msgstr "libpcap" msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." -msgstr "Controlla se libpcap è installato e che tu sia connesso ad una connessione libpcap compatibile." +msgstr "Controllare se libpcap è installato e che tu sia connesso ad una connessione libpcap compatibile." msgid "Invalid configuration" msgstr "Configurazione invalida" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " è richesto per l'emuazione di stampanti ESC/P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " è richiesto per l'output FluidSynth MIDI." - msgid "Entering fullscreen mode" msgstr "Entrando nella modalità schermo intero" @@ -956,28 +935,28 @@ msgid "Cartridge images" msgstr "Immagini cartuccia" msgid "Error initializing renderer" -msgstr "Error initializing renderer" +msgstr "Errore nell'inizializzazione del renderer" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Non è stato possibile inizializzare il renderer OpenGL (3.0 Core). Utilizzare un altro renderer." msgid "Resume execution" -msgstr "Resume execution" +msgstr "Riprendere l'esecuzione" msgid "Pause execution" -msgstr "Pause execution" +msgstr "Sospendere l'esecuzione" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Premere Ctrl+Alt+Canc" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Premere Ctrl+Alt+Esc" msgid "Hard reset" -msgstr "Hard reset" +msgstr "Riavvia" msgid "ACPI shutdown" -msgstr "ACPI shutdown" +msgstr "Arresto ACPI" msgid "Hard disk (%s)" msgstr "Hard disk (%s)" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Predefinito del sistema)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Impossibile inizializzare il driver di rete" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "La configurazione di rete verrà commutata sul driver nullo" + +msgid "Mouse sensitivity:" +msgstr "Sensitività del mouse:" + +msgid "Select media images from program working directory" +msgstr "Seleziona le immagini media dalla directory di lavoro del programma" + +msgid "PIT mode:" +msgstr "Modalità PIT:" + +msgid "Auto" +msgstr "Automatica" + +msgid "Slow" +msgstr "Lenta" + +msgid "Fast" +msgstr "Veloce" +msgid "&Auto-pause on focus loss" +msgstr "&Pausa automatica alla perdita della messa a fuoco" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index eb4e5241e9..d0f206dc9a 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1,14 +1,14 @@ msgid "&Action" -msgstr "動作(&A)" +msgstr "操作(&A)" msgid "&Keyboard requires capture" msgstr "キーボードはキャプチャが必要(&K)" msgid "&Right CTRL is left ALT" -msgstr "右CTRLを左ALTへ(&R)" +msgstr "右CTRLを左ALTへ変換(&R)" msgid "&Hard Reset..." -msgstr "ハードリセット(&H)..." +msgstr "ハード リセット(&H)..." msgid "&Ctrl+Alt+Del\tCtrl+F12" msgstr "Ctrl+Alt+Del(&C)\tCtrl+F12" @@ -26,16 +26,16 @@ msgid "&View" msgstr "表示(&V)" msgid "&Hide status bar" -msgstr "ステータスバーを隠す(&H)" +msgstr "ステータス バーを隠す(&H)" msgid "Hide &toolbar" -msgstr "ツールバーを隠す(&T)" +msgstr "ツール バーを隠す(&T)" msgid "&Resizeable window" -msgstr "ウィンドウのサイズをリサイズ可能(&R)" +msgstr "ウィンドウのサイズを変更可能(&R)" msgid "R&emember size && position" -msgstr "ウィンドウのサイズと位置を記憶(&E)" +msgstr "ウィンドウのサイズと位置を保存(&E)" msgid "Re&nderer" msgstr "レンダラー(&N)" @@ -56,10 +56,10 @@ msgid "&VNC" msgstr "VNC(&V)" msgid "Specify dimensions..." -msgstr "ウィンドウのサイズを指定..." +msgstr "ディメンションを指定..." msgid "F&orce 4:3 display ratio" -msgstr "4:3アスペクト比を固定(&O)" +msgstr "4:3の縦横比を強制表示(&O)" msgid "&Window scale factor" msgstr "ウィンドウの表示倍率(&W)" @@ -107,13 +107,13 @@ msgid "Hi&DPI scaling" msgstr "HiDPIスケーリング(&D)" msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "フルスクリーン(&F)\tCtrl+Alt+PgUp" +msgstr "全画面表示(&F)\tCtrl+Alt+PgUp" msgid "Fullscreen &stretch mode" -msgstr "フルスクリーンのスケール(&S)" +msgstr "全画面の拡大表示モード(&S)" msgid "&Full screen stretch" -msgstr "フルスクリーンに拡大(&F)" +msgstr "全画面の拡大表示(&F)" msgid "&4:3" msgstr "4:3(&4)" @@ -124,11 +124,14 @@ msgstr "正方形ピクセル(アスペクト比を維持)(&S)" msgid "&Integer scale" msgstr "整数倍(&I)" +msgid "4:&3 Integer scale" +msgstr "4:3 整数倍(&3)" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGAの設定" msgid "&Inverted VGA monitor" -msgstr "色を反転(&I)" +msgstr "色反転(&I)" msgid "VGA screen &type" msgstr "画面タイプ(&T)" @@ -140,7 +143,7 @@ msgid "&RGB Grayscale" msgstr "RGB(グレースケール)(&R)" msgid "&Amber monitor" -msgstr "モニター(琥珀色)(&A)" +msgstr "モニター(黄色)(&A)" msgid "&Green monitor" msgstr "モニター(緑色)(&G)" @@ -185,10 +188,10 @@ msgid "&Preferences..." msgstr "環境設定(&P)..." msgid "Enable &Discord integration" -msgstr "Discordとの連携機能(&D)" +msgstr "Discord連携機能(&D)" msgid "Sound &gain..." -msgstr "音量を調節(&G)..." +msgstr "音量調整(&G)..." msgid "Begin trace\tCtrl+T" msgstr "トレース開始\tCtrl+T" @@ -200,7 +203,7 @@ msgid "&Help" msgstr "ヘルプ(&H)" msgid "&Documentation..." -msgstr "ドキュメント(&D)..." +msgstr "文書(&D)..." msgid "&About 86Box..." msgstr "86Boxのバージョン情報(&A)..." @@ -212,7 +215,7 @@ msgid "&Existing image..." msgstr "既存のイメージを開く(&E)..." msgid "Existing image (&Write-protected)..." -msgstr "既存のイメージを開く(書き込み保護)(&W)..." +msgstr "既存のイメージを開く(書き込み禁止)(&W)..." msgid "&Record" msgstr "録音(&R)" @@ -221,7 +224,7 @@ msgid "&Play" msgstr "再生(&P)" msgid "&Rewind to the beginning" -msgstr "冒頭に巻き戻す(&R)" +msgstr "先頭まで巻き戻す(&R)" msgid "&Fast forward to the end" msgstr "最後まで早送り(&F)" @@ -239,7 +242,7 @@ msgid "&Mute" msgstr "ミュート(&M)" msgid "E&mpty" -msgstr "空(&M)" +msgstr "なし(&M)" msgid "&Reload previous image" msgstr "前のイメージを再読み込み(&R)" @@ -299,7 +302,7 @@ msgid "Cancel" msgstr "キャンセル" msgid "Save these settings as &global defaults" -msgstr "これらの設定をグローバル既定値として保存する(&G)" +msgstr "これらの設定をグローバル既定値として保存(&G)" msgid "&Default" msgstr "既定値(&D)" @@ -311,7 +314,7 @@ msgid "Icon set:" msgstr "アイコンセット:" msgid "Gain" -msgstr "ゲイン値" +msgstr "音量" msgid "File name:" msgstr "ファイル名:" @@ -320,7 +323,7 @@ msgid "Disk size:" msgstr "ディスクサイズ:" msgid "RPM mode:" -msgstr "回転数モード:" +msgstr "RPMモード:" msgid "Progress:" msgstr "進行状況:" @@ -332,7 +335,7 @@ msgid "Height:" msgstr "高さ:" msgid "Lock to this size" -msgstr "このサイズをロックする" +msgstr "サイズを固定" msgid "Machine type:" msgstr "マシンタイプ:" @@ -349,11 +352,14 @@ msgstr "CPUタイプ:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "頻度:" + msgid "FPU:" msgstr "FPU:" msgid "Wait states:" -msgstr "待機状態:" +msgstr "ウェイトステート:" msgid "MB" msgstr "MB" @@ -365,16 +371,16 @@ msgid "Time synchronization" msgstr "時刻同期機能" msgid "Disabled" -msgstr "無効にする" +msgstr "無効" msgid "Enabled (local time)" -msgstr "有効にする (現地時間)" +msgstr "有効(現地時間)" msgid "Enabled (UTC)" -msgstr "有効にする (UTC)" +msgstr "有効(UTC)" msgid "Dynamic Recompiler" -msgstr "動的リコンパイラ" +msgstr "動的再コンパイル" msgid "Video:" msgstr "ビデオカード:" @@ -382,8 +388,8 @@ msgstr "ビデオカード:" msgid "Voodoo Graphics" msgstr "Voodooグラフィック" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/aグラフィック" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/Aグラフィック" msgid "XGA Graphics" msgstr "XGAグラフィック" @@ -406,17 +412,17 @@ msgstr "ジョイスティック3..." msgid "Joystick 4..." msgstr "ジョイスティック4..." -msgid "Sound card 1:" -msgstr "サウンドカード 1:" +msgid "Sound card #1:" +msgstr "サウンドカード1:" -msgid "Sound card 2:" -msgstr "サウンドカード 2:" +msgid "Sound card #2:" +msgstr "サウンドカード2:" -msgid "Sound card 3:" -msgstr "サウンドカード 3:" +msgid "Sound card #3:" +msgstr "サウンドカード3:" -msgid "Sound card 4:" -msgstr "サウンドカード 4:" +msgid "Sound card #4:" +msgstr "サウンドカード4:" msgid "MIDI Out Device:" msgstr "MIDI出力デバイス:" @@ -434,13 +440,13 @@ msgid "FM synth driver" msgstr "FMシンセドライバー" msgid "Nuked (more accurate)" -msgstr "Nuked (高精度化)" +msgstr "Nuked(高精度化)" msgid "YMFM (faster)" -msgstr "YMFM (より速く)" +msgstr "YMFM(より速く)" msgid "Network type:" -msgstr "ネットワークタイプ:" +msgstr "ネットワーク タイプ:" msgid "PCap device:" msgstr "PCapデバイス:" @@ -497,16 +503,16 @@ msgid "Parallel port 4" msgstr "パラレルポート4" msgid "HD Controller:" -msgstr "HDコントローラー:" +msgstr "HDDコントローラー:" msgid "FD Controller:" -msgstr "FDコントローラー:" +msgstr "FDDコントローラー:" msgid "Tertiary IDE Controller" -msgstr "第三のIDEコントローラー" +msgstr "第三IDEコントローラー" msgid "Quaternary IDE Controller" -msgstr "第四のIDEコントローラー" +msgstr "第四IDEコントローラー" msgid "SCSI" msgstr "SCSI" @@ -527,7 +533,7 @@ msgid "Cassette" msgstr "カセット" msgid "Hard disks:" -msgstr "ハードディスク:" +msgstr "ハード ディスク:" msgid "&New..." msgstr "新規(&N)..." @@ -536,7 +542,7 @@ msgid "&Existing..." msgstr "既定(&E)..." msgid "&Remove" -msgstr "除去(&R)" +msgstr "削除(&R)" msgid "Bus:" msgstr "バス:" @@ -578,13 +584,13 @@ msgid "Turbo timings" msgstr "高速タイミング" msgid "Check BPB" -msgstr "BPBをチェック" +msgstr "BPBチェック" msgid "CD-ROM drives:" msgstr "CD-ROMドライブ:" msgid "Earlier drive" -msgstr "アーリードライブ" +msgstr "先のドライブ" msgid "MO drives:" msgstr "光磁気ドライブ:" @@ -599,7 +605,7 @@ msgid "ISA RTC:" msgstr "ISA RTCカード:" msgid "ISA Memory Expansion" -msgstr "ISAメモリー拡張カード" +msgstr "ISAメモリ拡張カード" msgid "Card 1:" msgstr "カード1:" @@ -638,7 +644,7 @@ msgid " - PAUSED" msgstr " - 一時停止" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Ctrl+Alt+PgDnでウィンドウモードに戻ります。" +msgstr "Ctrl+Alt+PgDnでウィンドウ モードに戻ります。" msgid "Speed" msgstr "速度" @@ -650,7 +656,7 @@ msgid "ZIP images" msgstr "ZIPイメージ" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Boxで使用可能なROMイメージが見つかりませんでした。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" +msgstr "86Boxで使用可能なROMイメージが見つかりません。\n\nROMセットをダウンロードして、roms ディレクトリに解凍してください。" msgid "(empty)" msgstr "(空)" @@ -671,22 +677,22 @@ msgid "All images" msgstr "すべてのイメージ" msgid "Basic sector images" -msgstr "基本的なセクターイメージ" +msgstr "ベーシック セクター イメージ" msgid "Surface images" -msgstr "表面イメージ" +msgstr "サーフェス イメージ" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "roms/machinesディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" +msgstr "roms/machines ディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "roms/videoディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" +msgstr "roms/video ディレクトリにROMがないため、ビデオ カード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" msgid "Machine" msgstr "マシン" msgid "Display" -msgstr "画面表示" +msgstr "ディスプレイ" msgid "Input devices" msgstr "入力デバイス" @@ -698,7 +704,7 @@ msgid "Network" msgstr "ネットワーク" msgid "Ports (COM & LPT)" -msgstr "ポート (COM & LPT)" +msgstr "ポート (COM/LPT)" msgid "Storage controllers" msgstr "ストレージコントローラ" @@ -707,25 +713,22 @@ msgid "Hard disks" msgstr "ハードディスク" msgid "Floppy & CD-ROM drives" -msgstr "フロッピー/CD-ROMドライブ" +msgstr "フロッピー/CD-ROMドライブ" msgid "Other removable devices" -msgstr "その他のリムーバブルデバイス" +msgstr "他のリムーバブルデバイス" msgid "Other peripherals" -msgstr "その他の周辺装置" +msgstr "他の周辺デバイス" msgid "Click to capture mouse" -msgstr "クリックするとマウスをキャプチャします" +msgstr "左クリックでマウスをキャプチャします" msgid "Press F8+F12 to release mouse" msgstr "F8+F12キーでマウスを解放します" msgid "Press F8+F12 or middle button to release mouse" -msgstr "F8+F12キーまたは中ボタンでマウスを解放します" - -msgid "Unable to initialize FluidSynth" -msgstr "FluidSynthが初期化できません" +msgstr "F8+F12キーまたは中クリックでマウスを解放します" msgid "Bus" msgstr "バス" @@ -752,7 +755,7 @@ msgid "Default" msgstr "既定値" msgid "%i Wait state(s)" -msgstr "%iつの待機状態" +msgstr "%iつのウェイト ステート" msgid "Type" msgstr "タイプ" @@ -764,7 +767,7 @@ msgid "No PCap devices found" msgstr "PCapデバイスがありません" msgid "Invalid PCap device" -msgstr "不正なPCapデバイスです" +msgstr "不正なPCapデバイス" msgid "Standard 2-button joystick(s)" msgstr "標準ジョイスティック(2ボタン)" @@ -782,10 +785,10 @@ msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinderパッド" msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgstr "Thrustmaster飛行制御システム" msgid "None" msgstr "なし" @@ -794,13 +797,13 @@ msgid "Unable to load keyboard accelerators." msgstr "キーボードアクセラレータを読み込めません。" msgid "Unable to register raw input." -msgstr "生の入力が登録できません。" +msgstr "生入力が登録できません。" msgid "%u" msgstr "%u" msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS値: %i、%i、%i)" msgid "Floppy %i (%s): %ls" msgstr "フロッピー %i (%s): %ls" @@ -809,16 +812,10 @@ msgid "Advanced sector images" msgstr "アドバンスドセクターイメージ" msgid "Flux images" -msgstr "フラックスイメージ" - -msgid "Unable to initialize FreeType" -msgstr "FreeTypeが初期化できません" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDLが初期化できません。SDL2.dllが必要です" +msgstr "Fluxイメージ" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "使用中のマシンをハードリセットしますか?" +msgstr "使用中のマシンをハード リセットしますか?" msgid "Are you sure you want to exit 86Box?" msgstr "86Boxを終了しますか?" @@ -848,7 +845,7 @@ msgid "Do you want to save the settings?" msgstr "設定を保存しますか?" msgid "This will hard reset the emulated machine." -msgstr "保存すると使用中のマシンがハードリセットされます。" +msgstr "使用中のマシンがハードリセットされます。" msgid "Save" msgstr "保存" @@ -859,8 +856,8 @@ msgstr "86Boxのバージョン情報" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "古いパソコンのエミュレーター\n\n著者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" msgid "Hardware not available" msgstr "ハードウェアが利用できません" @@ -877,15 +874,6 @@ msgstr "がインストールされてるか、libpcapに対応したネット msgid "Invalid configuration" msgstr "不正な設定です" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "ESC/Pプリンタのエミュレーションにはlibfreetypeが必要です。" - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -893,19 +881,10 @@ msgid "libgs" msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -msgstr "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信されたドキュメントは、PostScript(.ps)ファイルとして保存されます。" - -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "FluidSynthのMIDI出力にはlibfluidsynthが必要です。" +msgstr "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" msgid "Entering fullscreen mode" -msgstr "フルスクリーンに切り替えています" +msgstr "全画面モードを入力" msgid "Don't show this message again" msgstr "今後、このメッセージを表示しない" @@ -923,7 +902,7 @@ msgid "CD-ROM images" msgstr "CD-ROMイメージ" msgid "%hs Device Configuration" -msgstr "%hs デバイスの設定" +msgstr "%hs のデバイス設定" msgid "Monitor in sleep mode" msgstr "モニターのスリープモード" @@ -935,10 +914,10 @@ msgid "OpenGL options" msgstr "OpenGL設定" msgid "You are loading an unsupported configuration" -msgstr "サポートされていない設定を読み込んでいます" +msgstr "読み込んでいる設定がサポートされません" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" +msgstr "選択したマシンに基づくCPUタイプのフィルター機能は、使用中のマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。しかし、マシンのBIOSや他のソフトウェアと互換性がない場合があります。\n\nこの設定を有効にすることは公式にはサポートされておらず、バグレポートは無効として中止される可能性があります。" msgid "Continue" msgstr "続行" @@ -959,7 +938,7 @@ msgid "Error initializing renderer" msgstr "レンダラーの初期化エラー" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0コア) レンダラーが初期化できませんでした。別のレンダラーを使用してください。" +msgstr "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" msgid "Resume execution" msgstr "実行を再開" @@ -968,10 +947,10 @@ msgid "Pause execution" msgstr "実行を一時停止" msgid "Press Ctrl+Alt+Del" -msgstr "Ctrl+Alt+DELを押し" +msgstr "Ctrl+Alt+DELを押す" msgid "Press Ctrl+Alt+Esc" -msgstr "Ctrl+Alt+Escを押し" +msgstr "Ctrl+Alt+Escを押す" msgid "Hard reset" msgstr "ハードリセット" @@ -989,13 +968,13 @@ msgid "%01i" msgstr "%01i" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLLまたはESDIのCD-ROMドライブが存在しません" +msgstr "MFM/RLLやESDI CD-ROMドライブが存在しません" msgid "Custom..." msgstr "カスタム..." msgid "Custom (large)..." -msgstr "カスタム (大型)..." +msgstr "カスタム (大容量)..." msgid "Add New Hard Disk" msgstr "新規のディスクを追加" @@ -1022,7 +1001,7 @@ msgid "HDI or HDX images with a sector size other than 512 are not supported." msgstr "512以外のセクタサイズを持つHDIまたはHDXイメージはサポートされていません。" msgid "USB is not yet supported" -msgstr "USBはまだサポートされていません" +msgstr "USBはまだ非対応です" msgid "Disk image file already exists" msgstr "ディスクイメージファイルが既に存在します" @@ -1046,10 +1025,10 @@ msgid "Remember to partition and format the newly-created drive." msgstr "新規ドライブをパーティション分割し、フォーマットを必ずしといてください。" msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "選択したファイルが上書きされます。使っていいですか?" +msgstr "選択したファイルは上書きされます。よろしいですか?" msgid "Unsupported disk image" -msgstr "サポートされていないディスクイメージ" +msgstr "非対応のディスクイメージジ" msgid "Overwrite" msgstr "上書き" @@ -1067,19 +1046,19 @@ msgid "HDX image (.hdx)" msgstr "HDXイメージ (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "VHD(容量固定)(.vhd)" +msgstr "VHD (容量固定) (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "VHD(容量可変)(.vhd)" +msgstr "VHD (容量可変) (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "VHD(差分)(.vhd)" +msgstr "VHD (差分) (.vhd)" msgid "Large blocks (2 MB)" -msgstr "大型ブロック (2 MB)" +msgstr "大きなブロック (2 MB)" msgid "Small blocks (512 KB)" -msgstr "小型ブロック (512 KB)" +msgstr "小さなブロック (512 KB)" msgid "VHD files" msgstr "VHDファイル" @@ -1088,13 +1067,13 @@ msgid "Select the parent VHD" msgstr "親VHDの選択" msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "親イメージがディファレンシングイメージの作成の後に修正した可能性があります。\n\nイメージファイルの移動、コピーまたはこのディスクを作成したプログラムにバグが発生した可能性があります。\n\nタイムスタンプを修正しますか?" +msgstr "親イメージが差分イメージの作成の後に変更される可能性があります。\n\nイメージ ファイルが移動またはコピーされたか、イメージ ファイルを作成したプログラムにバグが発生した可能性があります。\n\nタイムスタンプを修正しますか?" msgid "Parent and child disk timestamps do not match" -msgstr "親ディスクと子ディスクのタイムスタンプが一致しません" +msgstr "親ディスクと子ディスクのタイムス タンプが一致しません" msgid "Could not fix VHD timestamp." -msgstr "VHD のタイムスタンプを修正できませんでした。" +msgstr "VHD のタイムスタンプを修正できません。" msgid "%01i:%02i" msgstr "%01i:%02i" @@ -1205,23 +1184,43 @@ msgid "5.25\" 1.3 GB" msgstr "5.25\" 1.3 GB" msgid "Perfect RPM" -msgstr "規定の回転数" +msgstr "既定RPM" msgid "1% below perfect RPM" -msgstr "1%低い回転数" +msgstr "1%低いRPM" msgid "1.5% below perfect RPM" -msgstr "1.5%低い回転数" +msgstr "1.5%低いRPM" msgid "2% below perfect RPM" -msgstr "2%低い回転数" +msgstr "2%低いRPM" msgid "(System Default)" msgstr "(システム既定値)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "ネットワークドライバの初期化に失敗しました" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "ネットワーク設定がヌルドライバに切り替えられます" + +msgid "Mouse sensitivity:" +msgstr "マウスの感度:" + +msgid "Select media images from program working directory" +msgstr "プログラムの作業ディレクトリからメディアイメージを選択してください" + +msgid "PIT mode:" +msgstr "PITモード:" + +msgid "Auto" +msgstr "自動" + +msgid "Slow" +msgstr "遅い" + +msgid "Fast" +msgstr "速い" +msgid "&Auto-pause on focus loss" +msgstr "フォーカスが奪われると自動停止(&A)" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 112506fe59..f5d1502b0d 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -124,6 +124,9 @@ msgstr "정사각형 픽셀 (비율 유지)(&S)" msgid "&Integer scale" msgstr "정수배 확대(&I)" +msgid "4:&3 Integer scale" +msgstr "4:3 정수배 확대(&3)" + msgid "E&GA/(S)VGA settings" msgstr "E&GA/(S)VGA 설정" @@ -349,6 +352,9 @@ msgstr "CPU 종류:" msgid "Speed:" msgstr "속도:" +msgid "Frequency:" +msgstr "빈도:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "비디오 카드:" msgid "Voodoo Graphics" msgstr "Voodoo 그래픽" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a 그래픽" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A 그래픽" msgid "XGA Graphics" msgstr "XGA 그래픽" @@ -406,16 +412,16 @@ msgstr "조이스틱 3..." msgid "Joystick 4..." msgstr "조이스틱 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "사운드 카드 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "사운드 카드 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "사운드 카드 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "사운드 카드 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "F12+F8키를 누르면 마우스를 해제합니다" msgid "Press F8+F12 or middle button to release mouse" msgstr "F12+F8키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" -msgid "Unable to initialize FluidSynth" -msgstr "FluidSynth를 초기화할 수 없습니다" - msgid "Bus" msgstr "버스" @@ -811,12 +814,6 @@ msgstr "어드밴스드 섹터 이미지" msgid "Flux images" msgstr "플럭스 이미지" -msgid "Unable to initialize FreeType" -msgstr "FreeType을 초기화할 수 없습니다" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "실행중인 머신을 재시작하시겠습니까?" @@ -859,8 +856,8 @@ msgstr "86Box에 대해" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." msgid "Hardware not available" msgstr "하드웨어를 이용할 수 없습니다" @@ -877,15 +874,6 @@ msgstr "이 설치되었는지 libpcap에 대응하는 네트워크에 접속되 msgid "Invalid configuration" msgstr "올바르지 않은 설정입니다" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "ESC/P 프린터 에뮬레이션에 libfreetype이(가) 필요합니다." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "FluidSynth의 MIDI 출력에 libfluidsynth이(가) 필요합니다." - msgid "Entering fullscreen mode" msgstr "전체 화면으로 전환" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(시스템 기본값)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "네트워크 드라이버를 초기화하지 못했습니다" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "네트워크 구성이 널 드라이버로 전환됩니다" + +msgid "Mouse sensitivity:" +msgstr "마우스 감도:" + +msgid "Select media images from program working directory" +msgstr "프로그램 작업 디렉토리에서 미디어 이미지 선택" + +msgid "PIT mode:" +msgstr "PIT 모드:" + +msgid "Auto" +msgstr "자동" + +msgid "Slow" +msgstr "느린" + +msgid "Fast" +msgstr "빠른" +msgid "&Auto-pause on focus loss" +msgstr "집중력 저하 시 자동 일시 중지(&A)" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 7809cd2638..eb7a13e4ef 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -124,6 +124,9 @@ msgstr "&Kwadratowe piksele (Zachowaj proporcje)" msgid "&Integer scale" msgstr "&Skalowanie całkowite" +msgid "4:&3 Integer scale" +msgstr "Skalowanie całkowite 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Ustawienia E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Rodzaj procesora:" msgid "Speed:" msgstr "Szybkość:" +msgid "Frequency:" +msgstr "Częstotliwość:" + msgid "FPU:" msgstr "Jednostka FPU:" @@ -382,8 +388,8 @@ msgstr "Wideo:" msgid "Voodoo Graphics" msgstr "Grafika Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Grafika IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Karta dźwiękowa 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Karta dźwiękowa 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Karta dźwiękowa 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Karta dźwiękowa 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Naciśnij klawisze F8+F12 w celu uwolnienia myszy" msgid "Press F8+F12 or middle button to release mouse" msgstr "Naciśnij klawisze F8+F12 lub środkowy przycisk w celu uwolnienia myszy" -msgid "Unable to initialize FluidSynth" -msgstr "Nie można zainicjować FluidSynth" - msgid "Bus" msgstr "Magistrala" @@ -811,12 +814,6 @@ msgstr "Zaawansowane obrazy sektorów" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize FreeType" -msgstr "Nie można zainicjować FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Nie można zainicjować SDL, wymagany SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" @@ -859,8 +856,8 @@ msgstr "O 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Emulator starych komputerów\n\nAutorzy: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i inni.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." msgid "Hardware not available" msgstr "Sprzęt niedostępny" @@ -877,15 +874,6 @@ msgstr "Sprawdź, czy libpcap jest zainstalowany i czy posiadasz połączenie si msgid "Invalid configuration" msgstr "Nieprawidłowa konfiguracja" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " jest wymagany do emulacji drukarki ESC-P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " jest wymagany dla wyjścia FluidSynth MIDI." - msgid "Entering fullscreen mode" msgstr "Przechodzenie do trybu pełnoekranowego" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Domyślne ustawienie systemowe)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Nie udało się zainicjować sterownika sieciowego" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Konfiguracja sieci zostanie przełączona na sterownik null" + +msgid "Mouse sensitivity:" +msgstr "Wrażliwość myszy:" + +msgid "Select media images from program working directory" +msgstr "Wybór obrazów multimedialnych z katalogu roboczego programu" + +msgid "PIT mode:" +msgstr "Tryb PIT:" + +msgid "Auto" +msgstr "Automatyczny" + +msgid "Slow" +msgstr "Powolny" + +msgid "Fast" +msgstr "Szybki" +msgid "&Auto-pause on focus loss" +msgstr "&Automatyczna pauza po utracie fokusu" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index b6c2e2b70a..148ca716c2 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -124,6 +124,9 @@ msgstr "Pixel&s quadrados (manter proporção)" msgid "&Integer scale" msgstr "&Redimensionamento com valores inteiros" +msgid "4:&3 Integer scale" +msgstr "Redimensionamento com valores inteiros 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Configurações E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Tipo de CPU:" msgid "Speed:" msgstr "Veloc.:" +msgid "Frequency:" +msgstr "Frequência:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "3DFX Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Gráficos IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Placa de som 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Placa de som 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Placa de som 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Placa de som 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Aperte F8+F12 para liberar o mouse" msgid "Press F8+F12 or middle button to release mouse" msgstr "Aperte F8+F12 ou botão do meio para liberar o mouse" -msgid "Unable to initialize FluidSynth" -msgstr "Não foi possível inicializar o FluidSynth" - msgid "Bus" msgstr "Barramento" @@ -811,12 +814,6 @@ msgstr "Imagens de setor avançado" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize FreeType" -msgstr "Não foi possível inicializar o FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não é possível inicializar o SDL, é necessário o SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem certeza de que deseja reiniciar completamente a máquina emulada?" @@ -859,8 +856,8 @@ msgstr "Sobre o 86Box" msgid "86Box v" msgstr "86Box versão" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." msgid "Hardware not available" msgstr "Hardware não disponível" @@ -877,15 +874,6 @@ msgstr "Certifique-se de que libpcap esteja instalado e que você tenha uma cone msgid "Invalid configuration" msgstr "Configuração inválida" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " é necessário para emulação de impressora ESC/P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " é necessário para a saída MIDI FluidSynth." - msgid "Entering fullscreen mode" msgstr "Entrando no modo de tela cheia" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Padrão do sistema)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Falha ao inicializar o driver de rede" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "A configuração de rede será alterada para o driver nulo" + +msgid "Mouse sensitivity:" +msgstr "Sensibilidade do rato:" + +msgid "Select media images from program working directory" +msgstr "Selecione imagens de mídia do diretório de trabalho do programa" + +msgid "PIT mode:" +msgstr "Modo PIT:" + +msgid "Auto" +msgstr "Automático" + +msgid "Slow" +msgstr "Lento" + +msgid "Fast" +msgstr "Rápido" +msgid "&Auto-pause on focus loss" +msgstr "Pausa &automática ao perder o foco" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 7e4fc9053d..e309d91bfd 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -124,6 +124,9 @@ msgstr "Pixels &quadrados (Manter rácio)" msgid "&Integer scale" msgstr "Escala &inteira" +msgid "4:&3 Integer scale" +msgstr "Escala inteira 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Definições E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Tipo do CPU:" msgid "Speed:" msgstr "Velocidade:" +msgid "Frequency:" +msgstr "Frequência:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Vídeo:" msgid "Voodoo Graphics" msgstr "Gráficos Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Gráficos IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" @@ -406,16 +412,16 @@ msgstr "Joystick 3..." msgid "Joystick 4..." msgstr "Joystick 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Placa de som 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Placa de som 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Placa de som 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Placa de som 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Pressione F8+F12 para soltar o rato" msgid "Press F8+F12 or middle button to release mouse" msgstr "Pressione F8+F12 ou tecla média para soltar o rato" -msgid "Unable to initialize FluidSynth" -msgstr "Não foi possível inicializar o FluidSynth" - msgid "Bus" msgstr "Barramento" @@ -811,12 +814,6 @@ msgstr "Imagens avançadas de sector" msgid "Flux images" msgstr "Imagens de fluxo" -msgid "Unable to initialize FreeType" -msgstr "Não foi possível inicializar o FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Tem a certeza de que quer um reinício completo da máquina emulada?" @@ -859,8 +856,8 @@ msgstr "Acerca do 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." msgid "Hardware not available" msgstr "Hardware não disponível" @@ -877,15 +874,6 @@ msgstr "Certifique-se de que a biblioteca libpcap está instalada e de que está msgid "Invalid configuration" msgstr "Configuração inválida" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " é requerida para a emulação de impressora ESC/P." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " é necessário para a saída MIDI FluidSynth MIDI." - msgid "Entering fullscreen mode" msgstr "A entrar no modo de ecrã cheio" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Padrão do sistema)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Falha ao inicializar o driver de rede" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "A configuração da rede será alterada para o controlador nulo" + +msgid "Mouse sensitivity:" +msgstr "Sensibilidade do rato:" + +msgid "Select media images from program working directory" +msgstr "Selecionar imagens multimédia do diretório de trabalho do programa" + +msgid "PIT mode:" +msgstr "Modo PIT:" + +msgid "Auto" +msgstr "Automático" + +msgid "Slow" +msgstr "Lento" + +msgid "Fast" +msgstr "Rápido" +msgid "&Auto-pause on focus loss" +msgstr "Pausa &automática na perda de focagem" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 78794cd350..4aa99eb873 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -31,6 +31,9 @@ msgstr "&Скрыть строку состояния" msgid "Hide &toolbar" msgstr "С&крыть панель инструментов" +msgid "Show non-primary monitors" +msgstr "&Показывать неосновные мониторы" + msgid "&Resizeable window" msgstr "&Изменяемый размер окна" @@ -55,8 +58,32 @@ msgstr "Open&GL (3.0)" msgid "&VNC" msgstr "&VNC" +msgid "Renderer options..." +msgstr "Параметры рендеринга..." + +msgid "OpenGL 3.0 renderer options" +msgstr "Параметры рендеринга OpenGL 3.0" + +msgid "Render behavior" +msgstr "Режим рендеринга" + +msgid "Synchronize with video" +msgstr "Синхронизировать с видео" + +msgid "Use target framerate:" +msgstr "Использовать целевую частоту кадров:" + +msgid "VSync" +msgstr "Вертикальная синхронизация" + +msgid "Shaders" +msgstr "Шейдеры" + +msgid "No shader selected" +msgstr "Шейдер не выбран" + msgid "Specify dimensions..." -msgstr "&Указать размеры..." +msgstr "&Указать размеры главного окна..." msgid "F&orce 4:3 display ratio" msgstr "У&становить соотношение сторон 4:3" @@ -124,6 +151,12 @@ msgstr "&Квадратные пиксели (сохранить соотнош msgid "&Integer scale" msgstr "&Целочисленное масштабирование" +msgid "4:&3 Integer scale" +msgstr "4:&3 Целочисленное масштабирование" + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Применить полноэкранный режим растяжения при разворачивании окна" + msgid "E&GA/(S)VGA settings" msgstr "Настройки E&GA/(S)VGA" @@ -190,6 +223,9 @@ msgstr "Включить интеграцию &Discord" msgid "Sound &gain..." msgstr "&Усиление звука..." +msgid "Open screenshots folder..." +msgstr "Открыть папку скриншотов..." + msgid "Begin trace\tCtrl+T" msgstr "Начать трассировку\tCtrl+T" @@ -229,6 +265,9 @@ msgstr "&Перемотка в конец" msgid "E&ject" msgstr "И&звлечь" +msgid "Eject %s" +msgstr "Извлечь %s" + msgid "&Image..." msgstr "&Образ..." @@ -238,6 +277,9 @@ msgstr "Э&кспорт в 86F..." msgid "&Mute" msgstr "О&тключить звук" +msgid "&Unmute" +msgstr "В&ключить звук" + msgid "E&mpty" msgstr "П&устой" @@ -349,6 +391,9 @@ msgstr "Тип ЦП:" msgid "Speed:" msgstr "Скорость:" +msgid "Frequency:" +msgstr "Частота:" + msgid "FPU:" msgstr "FPU:" @@ -365,25 +410,28 @@ msgid "Time synchronization" msgstr "Синхронизация времени" msgid "Disabled" -msgstr "Отключить" +msgstr "Отключено" msgid "Enabled (local time)" -msgstr "Включить (местное)" +msgstr "Включено (местное)" msgid "Enabled (UTC)" -msgstr "Включить (UTC)" +msgstr "Включено (UTC)" msgid "Dynamic Recompiler" msgstr "Динамический рекомпилятор" msgid "Video:" -msgstr "Видеокарта:" +msgstr "Видеокарта 1:" + +msgid "Video #2:" +msgstr "Видеокарта 2:" msgid "Voodoo Graphics" msgstr "Ускоритель Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Ускоритель IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Ускоритель IBM 8514/A" msgid "XGA Graphics" msgstr "Ускоритель XGA" @@ -406,23 +454,23 @@ msgstr "Джойстик 3..." msgid "Joystick 4..." msgstr "Джойстик 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Звуковая карта 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Звуковая карта 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Звуковая карта 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Звуковая карта 4:" msgid "MIDI Out Device:" -msgstr "MIDI Out устр-во:" +msgstr "MIDI Out устройство:" msgid "MIDI In Device:" -msgstr "MIDI In устр-во:" +msgstr "MIDI In устройство:" msgid "Standalone MPU-401" msgstr "Отдельный MPU-401" @@ -437,7 +485,7 @@ msgid "Nuked (more accurate)" msgstr "Nuked (более точный)" msgid "YMFM (faster)" -msgstr "YMFM (быстрей)" +msgstr "YMFM (быстрее)" msgid "Network type:" msgstr "Тип сети:" @@ -448,6 +496,30 @@ msgstr "Устройство PCap:" msgid "Network adapter:" msgstr "Сетевая карта:" +msgid "Network Card #1" +msgstr "Сетевая карта 1:" + +msgid "Network Card #2" +msgstr "Сетевая карта 2:" + +msgid "Network Card #3" +msgstr "Сетевая карта 3:" + +msgid "Network Card #4" +msgstr "Сетевая карта 4:" + +msgid "Mode" +msgstr "Режим:" + +msgid "Interface" +msgstr "Интерфейс:" + +msgid "Adapter" +msgstr "Адаптер:" + +msgid "VDE Socket" +msgstr "VDE Socket:" + msgid "COM1 Device:" msgstr "Устройство COM1:" @@ -473,16 +545,28 @@ msgid "LPT4 Device:" msgstr "Устройство LPT4:" msgid "Serial port 1" -msgstr "Последов. порт COM1" +msgstr "Последовательный порт COM1" msgid "Serial port 2" -msgstr "Последов. порт COM2" +msgstr "Последовательный порт COM2" msgid "Serial port 3" -msgstr "Последов. порт COM3" +msgstr "Последовательный порт COM3" msgid "Serial port 4" -msgstr "Последов. порт COM4" +msgstr "Последовательный порт COM4" + +msgid "Serial port passthrough 1" +msgstr "Сквозной последовательный порт COM1" + +msgid "Serial port passthrough 2" +msgstr "Сквозной последовательный порт COM2" + +msgid "Serial port passthrough 3" +msgstr "Сквозной последовательный порт COM3" + +msgid "Serial port passthrough 4" +msgstr "Сквозной последовательный порт COM4" msgid "Parallel port 1" msgstr "Параллельный порт LPT1" @@ -535,8 +619,14 @@ msgstr "&Создать..." msgid "&Existing..." msgstr "&Выбрать..." +msgid "Browse..." +msgstr "Выбрать..." + msgid "&Remove" -msgstr "&Убрать" +msgstr "&Удалить" + +msgid "Remove" +msgstr "Удалить" msgid "Bus:" msgstr "Шина:" @@ -551,7 +641,7 @@ msgid "&Specify..." msgstr "&Указать..." msgid "Sectors:" -msgstr "Сектора:" +msgstr "Секторы:" msgid "Heads:" msgstr "Головки:" @@ -599,7 +689,7 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr "Карта расширения памяти (ISA)" +msgstr "Карта расширения памяти ISA" msgid "Card 1:" msgstr "Карта 1:" @@ -619,6 +709,9 @@ msgstr "Устройство ISABugger" msgid "POST card" msgstr "Карта POST" +msgid "86Box Unit Tester" +msgstr "Модульный Тестер 86Box" + msgid "FONT_SIZE" msgstr "9" @@ -655,6 +748,9 @@ msgstr "86Box не смог найти ни одного подходящего msgid "(empty)" msgstr "(пусто)" +msgid "Clear image history" +msgstr "Очистить историю образов" + msgid "All files" msgstr "Все файлы" @@ -710,7 +806,7 @@ msgid "Floppy & CD-ROM drives" msgstr "Гибкие диски и CD-ROM" msgid "Other removable devices" -msgstr "Другие съёмные устр-ва" +msgstr "Другие съёмные устройства" msgid "Other peripherals" msgstr "Другая периферия" @@ -724,9 +820,6 @@ msgstr "Нажмите F8+F12 чтобы освободить курсор" msgid "Press F8+F12 or middle button to release mouse" msgstr "Нажмите F8+F12 или среднюю кнопку мыши чтобы освободить курсор" -msgid "Unable to initialize FluidSynth" -msgstr "Невозможно инициализировать FluidSynth" - msgid "Bus" msgstr "Шина" @@ -785,7 +878,7 @@ msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" -msgstr "Система управления полетом Thrustmaster" +msgstr "Система управления полётом Thrustmaster" msgid "None" msgstr "Нет" @@ -811,12 +904,6 @@ msgstr "Расширенные образы секторов" msgid "Flux images" msgstr "Образы Flux" -msgid "Unable to initialize FreeType" -msgstr "Невозможно инициализировать FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Невозможно инициализировать SDL, требуется SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" @@ -848,7 +935,7 @@ msgid "Do you want to save the settings?" msgstr "Хотите ли вы сохранить настройки?" msgid "This will hard reset the emulated machine." -msgstr "Это приведет к холодной перезагрузке эмулируемой машины." +msgstr "Это приведёт к холодной перезагрузке эмулируемой машины." msgid "Save" msgstr "Сохранить" @@ -857,10 +944,10 @@ msgid "About 86Box" msgstr "О 86Box" msgid "86Box v" -msgstr "86Box v." +msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Эмулятор старых компьютеров\n\nАвторы: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." msgid "Hardware not available" msgstr "Оборудование недоступно" @@ -877,15 +964,6 @@ msgstr "Убедитесь, что libpcap установлен и ваше се msgid "Invalid configuration" msgstr "Недопустимая конфигурация" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "Для эмуляции принтера ESC/P требуется libfreetype." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +973,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "Для FluidSynth MIDI-вывода требуется libfluidsynth." - msgid "Entering fullscreen mode" msgstr "Вход в полноэкранный режим" @@ -1220,8 +1289,28 @@ msgid "(System Default)" msgstr "(Системный)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Не удалось инициализировать сетевой драйвер" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Сетевая конфигурация будет переключена на нулевой драйвер" + +msgid "Mouse sensitivity:" +msgstr "Чувствительность мыши:" + +msgid "Select media images from program working directory" +msgstr "Выбор медиа-образов из рабочего каталога программы" + +msgid "PIT mode:" +msgstr "Режим PIT:" + +msgid "Auto" +msgstr "Авто" + +msgid "Slow" +msgstr "Медленный" + +msgid "Fast" +msgstr "Быстрый" +msgid "&Auto-pause on focus loss" +msgstr "&Автопауза при потере фокуса" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po new file mode 100644 index 0000000000..376723efa9 --- /dev/null +++ b/src/qt/languages/sk-SK.po @@ -0,0 +1,1226 @@ +msgid "&Action" +msgstr "&Podujatia" + +msgid "&Keyboard requires capture" +msgstr "&Klávesnica vyžaduje záber" + +msgid "&Right CTRL is left ALT" +msgstr "&Pravý Ctrl je ľavý Alt" + +msgid "&Hard Reset..." +msgstr "&Resetovať" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "P&ozastaviť" + +msgid "E&xit..." +msgstr "&Ukončiť" + +msgid "&View" +msgstr "&Zobrazenie" + +msgid "&Hide status bar" +msgstr "&Skryť stavový riadok" + +msgid "Hide &toolbar" +msgstr "Skryť panel &nástrojov" + +msgid "&Resizeable window" +msgstr "&Premenná veľkosť okna" + +msgid "R&emember size && position" +msgstr "&Pamätať si veľkosť a polohu" + +msgid "Re&nderer" +msgstr "&Renderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Zadať veľkosť..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Zachovať pomer strán 4:3" + +msgid "&Window scale factor" +msgstr "&Násobné zväčšenie okna" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "Spôsob &filtrovania" + +msgid "&Nearest" +msgstr "&Najbližší" + +msgid "&Linear" +msgstr "&Lineárny" + +msgid "Hi&DPI scaling" +msgstr "Š&kálovanie HiDPI" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "&Celá obrazovka\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "Režim roztia&hnutia na celú obrazovku" + +msgid "&Full screen stretch" +msgstr "&Rozšíriť" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Zachovať pomer strán" + +msgid "&Integer scale" +msgstr "&Celočíselné škálovanie" + +msgid "4:&3 Integer scale" +msgstr "4:&3 Celočíselné škálovanie" + +msgid "E&GA/(S)VGA settings" +msgstr "Nastavenia pre E&GA a (S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Obrátiť farby" + +msgid "VGA screen &type" +msgstr "&Typ monitora VGA" + +msgid "RGB &Color" +msgstr "RGB &farebný" + +msgid "&RGB Grayscale" +msgstr "&Odtiene sivej" + +msgid "&Amber monitor" +msgstr "&Jantárová obrazovka" + +msgid "&Green monitor" +msgstr "&Zelená obrazovka" + +msgid "&White monitor" +msgstr "&Biela obrazovka" + +msgid "Grayscale &conversion type" +msgstr "Konverzia na &odtiene sivej" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Priemer" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Prekrytie obrazu CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "&Úprava kontrastu čiernobielej obrazovky" + +msgid "&Media" +msgstr "&Média" + +msgid "&Tools" +msgstr "&Nástroje" + +msgid "&Settings..." +msgstr "&Nastavenia..." + +msgid "&Update status bar icons" +msgstr "&Aktualizovať ikony na stavovom riadku" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Urobiť snímku &obrazovky\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Predvoľby..." + +msgid "Enable &Discord integration" +msgstr "Povolenie integrácie s &Discordem" + +msgid "Sound &gain..." +msgstr "&Zosilnenie zvuku" + +msgid "Begin trace\tCtrl+T" +msgstr "Začať trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Zastaviť trace\tCtrl+T" + +msgid "&Help" +msgstr "&Pomoc" + +msgid "&Documentation..." +msgstr "&Dokumentácia" + +msgid "&About 86Box..." +msgstr "&O programu 86Box" + +msgid "&New image..." +msgstr "&Nový obraz..." + +msgid "&Existing image..." +msgstr "&Existujúci obraz..." + +msgid "Existing image (&Write-protected)..." +msgstr "Existujúci obraz (&ochrana proti zápisu)..." + +msgid "&Record" +msgstr "&Nahrávať" + +msgid "&Play" +msgstr "&Prehrať" + +msgid "&Rewind to the beginning" +msgstr "Previnuť na &začiatok" + +msgid "&Fast forward to the end" +msgstr "Previnuť na &koniec" + +msgid "E&ject" +msgstr "&Vystrihnúť" + +msgid "&Image..." +msgstr "&Obraz..." + +msgid "E&xport to 86F..." +msgstr "E&xportovať do 86F..." + +msgid "&Mute" +msgstr "&Stíšiť" + +msgid "E&mpty" +msgstr "&Vystrihnúť" + +msgid "&Reload previous image" +msgstr "&Načítať znova predchádzajúci obraz" + +msgid "&Folder..." +msgstr "&Zložka..." + +msgid "Target &framerate" +msgstr "&Cieľová snímková frekvencia" + +msgid "&Sync with video" +msgstr "&Synchronizovať s obrazom" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Zvoliť shader..." + +msgid "&Remove shader" +msgstr "&Odobrať shader" + +msgid "Preferences" +msgstr "Predvoľby" + +msgid "Sound Gain" +msgstr "Zosilnenie zvuku" + +msgid "New Image" +msgstr "Nový obraz" + +msgid "Settings" +msgstr "Nastavenia" + +msgid "Specify Main Window Dimensions" +msgstr "Zadať rozmery hlavného okna" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Storno" + +msgid "Save these settings as &global defaults" +msgstr "Uložiť toto nastavenie ako &globálny východiskový stav" + +msgid "&Default" +msgstr "&Východiskové" + +msgid "Language:" +msgstr "Jazyk:" + +msgid "Icon set:" +msgstr "Súprava ikon:" + +msgid "Gain" +msgstr "Zosilnenie" + +msgid "File name:" +msgstr "Názov súboru:" + +msgid "Disk size:" +msgstr "Veľkosť disku:" + +msgid "RPM mode:" +msgstr "Režim ot./m:" + +msgid "Progress:" +msgstr "Priebeh:" + +msgid "Width:" +msgstr "Šírka:" + +msgid "Height:" +msgstr "Výška:" + +msgid "Lock to this size" +msgstr "Uzamknúť na tieto rozmery" + +msgid "Machine type:" +msgstr "Typ počítača:" + +msgid "Machine:" +msgstr "Počítač:" + +msgid "Configure" +msgstr "Nastaviť" + +msgid "CPU type:" +msgstr "Procesor:" + +msgid "Speed:" +msgstr "Rýchlosť:" + +msgid "Frequency:" +msgstr "Frekvencia:" + +msgid "FPU:" +msgstr "Koprocesor:" + +msgid "Wait states:" +msgstr "Čakacie stavy:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Pamäť:" + +msgid "Time synchronization" +msgstr "Synchronizácia času" + +msgid "Disabled" +msgstr "Vypnutá" + +msgid "Enabled (local time)" +msgstr "Zapnutá (miestny čas)" + +msgid "Enabled (UTC)" +msgstr "Zapnutá (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamický prekladač" + +msgid "Video:" +msgstr "Grafika:" + +msgid "Voodoo Graphics" +msgstr "Použiť grafický akcelerátor Voodoo" + +msgid "IBM 8514/A Graphics" +msgstr "Grafika IBM 8514/A" + +msgid "XGA Graphics" +msgstr "Grafika XGA" + +msgid "Mouse:" +msgstr "Myš:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card #1:" +msgstr "Zvuková karta 1:" + +msgid "Sound card #2:" +msgstr "Zvuková karta 2:" + +msgid "Sound card #3:" +msgstr "Zvuková karta 3:" + +msgid "Sound card #4:" +msgstr "Zvuková karta 4:" + +msgid "MIDI Out Device:" +msgstr "MIDI výstup:" + +msgid "MIDI In Device:" +msgstr "MIDI vstup:" + +msgid "Standalone MPU-401" +msgstr "Samostatný MPU-401" + +msgid "Use FLOAT32 sound" +msgstr "Použiť zvuk FLOAT32" + +msgid "FM synth driver" +msgstr "Ovládač FM syntetizátora" + +msgid "Nuked (more accurate)" +msgstr "Nuked (presnejší)" + +msgid "YMFM (faster)" +msgstr "YMFM (rýchlejší)" + +msgid "Network type:" +msgstr "Druh siete:" + +msgid "PCap device:" +msgstr "PCap zariadenia:" + +msgid "Network adapter:" +msgstr "Sieťový adaptér:" + +msgid "COM1 Device:" +msgstr "Zariadenie na COM1:" + +msgid "COM2 Device:" +msgstr "Zariadenie na COM2:" + +msgid "COM3 Device:" +msgstr "Zariadenie na COM3:" + +msgid "COM4 Device:" +msgstr "Zariadenie na COM4:" + +msgid "LPT1 Device:" +msgstr "Zariadenie na LPT1:" + +msgid "LPT2 Device:" +msgstr "Zariadenie na LPT2:" + +msgid "LPT3 Device:" +msgstr "Zariadenie na LPT3:" + +msgid "LPT4 Device:" +msgstr "Zariadenie na LPT4:" + +msgid "Serial port 1" +msgstr "Povoliť port COM1" + +msgid "Serial port 2" +msgstr "Povoliť port COM2" + +msgid "Serial port 3" +msgstr "Povoliť port COM3" + +msgid "Serial port 4" +msgstr "Povoliť port COM4" + +msgid "Parallel port 1" +msgstr "Povoliť port LPT1" + +msgid "Parallel port 2" +msgstr "Povoliť port LPT2" + +msgid "Parallel port 3" +msgstr "Povoliť port LPT3" + +msgid "Parallel port 4" +msgstr "Povoliť port LPT4" + +msgid "HD Controller:" +msgstr "Radič disku:" + +msgid "FD Controller:" +msgstr "Disketový radič:" + +msgid "Tertiary IDE Controller" +msgstr "Tretí radič IDE" + +msgid "Quaternary IDE Controller" +msgstr "Štvrtý radič IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Radič 1:" + +msgid "Controller 2:" +msgstr "Radič 2:" + +msgid "Controller 3:" +msgstr "Radič 3:" + +msgid "Controller 4:" +msgstr "Radič 4:" + +msgid "Cassette" +msgstr "Kazeta" + +msgid "Hard disks:" +msgstr "Pevné disky:" + +msgid "&New..." +msgstr "&Nový..." + +msgid "&Existing..." +msgstr "&Existujúcý..." + +msgid "&Remove" +msgstr "&Odobrať" + +msgid "Bus:" +msgstr "Zbernica:" + +msgid "Channel:" +msgstr "Kanál:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Zadať..." + +msgid "Sectors:" +msgstr "Sektory:" + +msgid "Heads:" +msgstr "Hlavy:" + +msgid "Cylinders:" +msgstr "Cylindre:" + +msgid "Size (MB):" +msgstr "Veľkosť (MB):" + +msgid "Type:" +msgstr "Typ:" + +msgid "Image Format:" +msgstr "Formát obrazu:" + +msgid "Block Size:" +msgstr "Veľkosť blokov:" + +msgid "Floppy drives:" +msgstr "Disketové mechaniky:" + +msgid "Turbo timings" +msgstr "Turbo časovanie" + +msgid "Check BPB" +msgstr "Kontrola BPB" + +msgid "CD-ROM drives:" +msgstr "Mechaniky CD-ROM:" + +msgid "Earlier drive" +msgstr "Skorá mechanika" + +msgid "MO drives:" +msgstr "Magnetooptické mechaniky:" + +msgid "ZIP drives:" +msgstr "Mechaniky ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA hodiny:" + +msgid "ISA Memory Expansion" +msgstr "ISA rozšírenie pamäte" + +msgid "Card 1:" +msgstr "Karta 1:" + +msgid "Card 2:" +msgstr "Karta 2:" + +msgid "Card 3:" +msgstr "Karta 3:" + +msgid "Card 4:" +msgstr "Karta 4:" + +msgid "ISABugger device" +msgstr "Zariadenie ISABugger" + +msgid "POST card" +msgstr "Karta pre kódy POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Chyba" + +msgid "Fatal error" +msgstr "Kritická chyba" + +msgid " - PAUSED" +msgstr " - POZASTAVENÝ" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Stlačte Ctrl+Alt+PgDn pre návrat z režimu celej obrazovky." + +msgid "Speed" +msgstr "Rýchlosť" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Obrazy ZIP diskov" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box nenašiel žiadne použiteľné imidž pamätí ROM.\n\nStiahnite sadu obrazov ROM a extrahujte ju do zložky \"roms\"." + +msgid "(empty)" +msgstr "(prázdne)" + +msgid "All files" +msgstr "Všetky súbory" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Zap." + +msgid "Off" +msgstr "Vyp." + +msgid "All images" +msgstr "Všetky obrazy diskov" + +msgid "Basic sector images" +msgstr "Základné sektorové obrazy" + +msgid "Surface images" +msgstr "Obrazy povrchu" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Počítač \"%hs\" ie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/machines\". Konfigurácia sa prepne na iný dostupný počítač." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video adaptér \"%hs\" nie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/video\". Konfigurácia sa prepne na iný dostupný adaptér." + +msgid "Machine" +msgstr "Počítač" + +msgid "Display" +msgstr "Obraz" + +msgid "Input devices" +msgstr "Vstupné zariadenie" + +msgid "Sound" +msgstr "Zvuk" + +msgid "Network" +msgstr "Sieť" + +msgid "Ports (COM & LPT)" +msgstr "COM a LPT porty" + +msgid "Storage controllers" +msgstr "Radiče úložiska" + +msgid "Hard disks" +msgstr "Pevné disky" + +msgid "Floppy & CD-ROM drives" +msgstr "Disketové a CD-ROM mechaniky" + +msgid "Other removable devices" +msgstr "Ďalšie vymeniteľné zariadenia" + +msgid "Other peripherals" +msgstr "Iné príslušenstvo" + +msgid "Click to capture mouse" +msgstr "Kliknite pre zabráni myši" + +msgid "Press F8+F12 to release mouse" +msgstr "Stlačte F8+F12 pre uvoľnenie myši" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Stlačte F8+F12 alebo prostredné tlačidlo na uvoľnenie myši" + +msgid "Bus" +msgstr "Zbernica" + +msgid "File" +msgstr "Súbor" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nastala chyba pri inicializácii video renderera." + +msgid "Default" +msgstr "Východiskové" + +msgid "%i Wait state(s)" +msgstr "%i čakací stav(y)" + +msgid "Type" +msgstr "Typ" + +msgid "Failed to set up PCap" +msgstr "Nastala chyba pri inicializácii knižnice PCap" + +msgid "No PCap devices found" +msgstr "Neboli nájdené žiadne PCap zariadenia" + +msgid "Invalid PCap device" +msgstr "Neplatné PCap zariadenie" + +msgid "Standard 2-button joystick(s)" +msgstr "Štandardný 2tlačidlový joystick" + +msgid "Standard 4-button joystick" +msgstr "Štandardný 4tlačidlový joystick" + +msgid "Standard 6-button joystick" +msgstr "Štandardný 6tlačidlový joystick" + +msgid "Standard 8-button joystick" +msgstr "Štandardný 8tlačidlový joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Žiadne" + +msgid "Unable to load keyboard accelerators." +msgstr "Nebolo možné nahrať klávesnicové skratky." + +msgid "Unable to register raw input." +msgstr "Nebolo možné zaregistrovať raw input." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disketová mechanika %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Rozšírené sektorové obrazy" + +msgid "Flux images" +msgstr "Obrazy magnetického toku" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Naozaj chcete resetovať emulovaný počítač?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Naozaj chcete ukončiť 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nastala chyba pri inicializácii knižnice Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Obrazy MO" + +msgid "Welcome to 86Box!" +msgstr "Vitajte v programe 86Box!" + +msgid "Internal controller" +msgstr "Vstavaný radič" + +msgid "Exit" +msgstr "Ukončiť" + +msgid "No ROMs found" +msgstr "Neboli nájdené žiadne obrazy ROM" + +msgid "Do you want to save the settings?" +msgstr "Chcete uložiť nastavenia?" + +msgid "This will hard reset the emulated machine." +msgstr "Pokračovaním sa resetuje emulovaný počítač." + +msgid "Save" +msgstr "Uložiť" + +msgid "About 86Box" +msgstr "O programe 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZverejnené pod licenciou GNU General Public License verzie 2 alebo novšej. Pozri súbor LICENSE pre viac informácií." + +msgid "Hardware not available" +msgstr "Hardvér nie je dostupný" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Uistite sa, že je nainštalovaný libpcap a používate sieťové pripojenie s ním kompatibilné." + +msgid "Invalid configuration" +msgstr "Neplatná konfigurácia" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " je potrebná pre automatický prevod PostScript dokumentov do PDF.\n\nAkékoľvek dokumenty vytlačené cez všeobecnú PostScriptovú tlačiareň budú uložené ako PostScript (.ps) súbory." + +msgid "Entering fullscreen mode" +msgstr "Vstup do režimu celej obrazovky" + +msgid "Don't show this message again" +msgstr "Nezobrazovať ďalej túto správu" + +msgid "Don't exit" +msgstr "Neukončovať" + +msgid "Reset" +msgstr "Resetovať" + +msgid "Don't reset" +msgstr "Neresetovať" + +msgid "CD-ROM images" +msgstr "Obraz CD-ROM disku" + +msgid "%hs Device Configuration" +msgstr "Konfigurácia zariadenia %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor je v režime spánku" + +msgid "OpenGL Shaders" +msgstr "Shadery OpenGL" + +msgid "OpenGL options" +msgstr "Možnosti OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Pokúšate sa spustiť nepodporovanú konfiguráciu" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Pre túto konfiguráciu bolo vypnuté filtrovanie procesorov podľa zvoleného počítača.\n\nToto umožňuje zvoliť procesor, ktorý by inak so zvoleným počítačom nebol kompatibilný. Môžu však nastať problémy s BIOSom alebo iným softvérom.\n\nPovolenie tohto nastavenia nie je oficiálne podporované a akékoľvek hlásenia o chybách môžu byť uzavreté ako neplatné." + +msgid "Continue" +msgstr "Pokračovať" + +msgid "Cassette: %s" +msgstr "Kazeta: %s" + +msgid "Cassette images" +msgstr "Kazetové nahrávky" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Obrazy cartridge" + +msgid "Error initializing renderer" +msgstr "Chyba pri inicializácii vykresľovača" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Vykresľovač OpenGL (3.0 Core) sa nepodarilo inicializovať. Použite iný renderer." + +msgid "Resume execution" +msgstr "Obnoviť" + +msgid "Pause execution" +msgstr "Pozastaviť" + +msgid "Press Ctrl+Alt+Del" +msgstr "Stlačiť Ctrl+Alt+Delete" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Stlačiť Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Resetovať" + +msgid "ACPI shutdown" +msgstr "Vypnúť cez rozhranie ACPI" + +msgid "Hard disk (%s)" +msgstr "Pevný disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "CD-ROM mechaniky pre rozhranie MFM/RLL alebo ESDI nikdy neexistovali" + +msgid "Custom..." +msgstr "Vlastná..." + +msgid "Custom (large)..." +msgstr "Vlastná (veľká)..." + +msgid "Add New Hard Disk" +msgstr "Pridať nový pevný disk" + +msgid "Add Existing Hard Disk" +msgstr "Pridať existujúci pevný disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Obraz disku formátu HDI nemôžu byť väčší ako 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Obraz disku nemôžu byť väčší ako 127 GB." + +msgid "Hard disk images" +msgstr "Obrazy pevného disku" + +msgid "Unable to read file" +msgstr "Nebolo možné prečítať súbor" + +msgid "Unable to write file" +msgstr "Nebolo možné zapisovať do súboru" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Obraz disku vo formáte HDI alebo HDX s veľkosťou sektora inou ako 512 bajtov nie sú podporované." + +msgid "USB is not yet supported" +msgstr "USB zatiaľ nie je podporované." + +msgid "Disk image file already exists" +msgstr "Súbor obrazu disku už existuje" + +msgid "Please specify a valid file name." +msgstr "Zadajte platný názov súboru." + +msgid "Disk image created" +msgstr "Obraz disku bol vytvorený" + +msgid "Make sure the file exists and is readable." +msgstr "Uistite sa, že súbor existuje a možno ho prečítať." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Uistite sa, že sa do zložky, kde sa má súbor uložiť, dá zapisovať." + +msgid "Disk image too large" +msgstr "Obraz disku je príliš veľký" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nezabudnite novo vytvorený disk rozdeliť a naformátovať." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Zvolený súbor bude prepísaný. Naozaj ho chcete použiť?" + +msgid "Unsupported disk image" +msgstr "Nepodporovaný obraz disku" + +msgid "Overwrite" +msgstr "Prepísať" + +msgid "Don't overwrite" +msgstr "Neprepisovať" + +msgid "Raw image (.img)" +msgstr "Surový obraz (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI obraz (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX obraz (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD s pevnou veľkosťou (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD s dynamickou veľkosťou (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Rozdielový VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Veľké bloky (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Malé bloky (512 KB)" + +msgid "VHD files" +msgstr "Súbory VHD" + +msgid "Select the parent VHD" +msgstr "Vyberte nadradený virtuálny disk" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "To môže znamenať, že sa obsahy nadradeného disku zmenili po vytvorení rozdielového disku.\n\nTáto chyba tiež môže nastať, ak bol obraz disku kopírovaný alebo presunutý, alebo kvôli chybe v programe, ktorý ho vytvoril.\n\nChcete časové pečiatky opraviť?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Časové pečiatky nadradeného a podradeného disku nesúhlasia" + +msgid "Could not fix VHD timestamp." +msgstr "Nebolo možné opraviť časovú pečiatku VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "Dokonalé otáčky za minútu" + +msgid "1% below perfect RPM" +msgstr "1% pod dokonalými ot./m" + +msgid "1.5% below perfect RPM" +msgstr "1.5% pod dokonalými ot./m" + +msgid "2% below perfect RPM" +msgstr "2% pod dokonalými ot./m" + +msgid "(System Default)" +msgstr "(Predvolené nastavenie systému)" + +msgid "Failed to initialize network driver" +msgstr "Nepodarilo sa inicializovať sieťový ovládač" + +msgid "The network configuration will be switched to the null driver" +msgstr "Konfigurácia siete bude prepnutá na nulový ovládač" + +msgid "Mouse sensitivity:" +msgstr "Citlivosť myší:" + +msgid "Select media images from program working directory" +msgstr "Výber mediálnych obrazov z pracovného adresára programu" + +msgid "PIT mode:" +msgstr "Režim PIT:" + +msgid "Auto" +msgstr "Automatický" + +msgid "Slow" +msgstr "Pomalý" + +msgid "Fast" +msgstr "Rýchly" + +msgid "&Auto-pause on focus loss" +msgstr "&Automatická pauza pri strate fokusu okna" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 5f32a6b03b..cde1011d18 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -124,6 +124,9 @@ msgstr "&Kvadratni piksli (ohrani razmerje)" msgid "&Integer scale" msgstr "&Celoštevilsko raztezanje" +msgid "4:&3 Integer scale" +msgstr "Celoštevilsko raztezanje 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Nastavitve E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Vrsta procesorja:" msgid "Speed:" msgstr "Hitrost:" +msgid "Frequency:" +msgstr "Pogostost:" + msgid "FPU:" msgstr "Procesor plavajoče vejice:" @@ -382,8 +388,8 @@ msgstr "Video:" msgid "Voodoo Graphics" msgstr "Voodoo grafika" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a grafika" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A grafika" msgid "XGA Graphics" msgstr "XGA grafika" @@ -406,16 +412,16 @@ msgstr "Igralna palica 3..." msgid "Joystick 4..." msgstr "Igralna palica 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Zvočna kartica 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Zvočna kartica 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Zvočna kartica 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Zvočna kartica 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Pritisnite F8+F12 za izpust miške" msgid "Press F8+F12 or middle button to release mouse" msgstr "Pritisnite F8+F12 ali srednji gumb za izpust miške" -msgid "Unable to initialize FluidSynth" -msgstr "Ne morem inicializirati FluidSynth" - msgid "Bus" msgstr "Vodilo" @@ -811,12 +814,6 @@ msgstr "Napredne sektorske slike" msgid "Flux images" msgstr "Tokovne slike" -msgid "Unable to initialize FreeType" -msgstr "Ne morem inicializirati FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ste prepričani, da želite ponovno zagnati emulirani sistem?" @@ -859,8 +856,8 @@ msgstr "O programu 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Emulator starih računalnikov\n\nAvtorji: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." msgid "Hardware not available" msgstr "Strojna oprema ni na voljo" @@ -877,15 +874,6 @@ msgstr "Prepičajte se, da je nameščen libpcap in da ste na omrežni povezavi, msgid "Invalid configuration" msgstr "Neveljavna konfiguracija" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " je potreben za emuliranje ESC/P tiskalnika." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " je potreben za FluidSynth MIDI izhod." - msgid "Entering fullscreen mode" msgstr "Preklapljam v celozaslonski način" @@ -968,10 +947,10 @@ msgid "Pause execution" msgstr "Prekini izvajanje" msgid "Press Ctrl+Alt+Del" -msgstr "Press Ctrl+Alt+Del" +msgstr "Pritisni Ctrl+Alt+Del" msgid "Press Ctrl+Alt+Esc" -msgstr "Press Ctrl+Alt+Esc" +msgstr "Pritisni Ctrl+Alt+Esc" msgid "Hard reset" msgstr "Ponovni zagon" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Sistemsko privzeto)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Ni uspelo inicializirati omrežnega gonilnika" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Omrežne nastavitve bodo preklopljene na ničelni gonilnik" + +msgid "Mouse sensitivity:" +msgstr "Občutljivost miške:" + +msgid "Select media images from program working directory" +msgstr "Izberi slike medijev iz delovnega imenika programa" + +msgid "PIT mode:" +msgstr "Način PIT:" + +msgid "Auto" +msgstr "Samodejni" + +msgid "Slow" +msgstr "Počasni" + +msgid "Fast" +msgstr "Hitri" +msgid "&Auto-pause on focus loss" +msgstr "&Samodejni premor ob izgubi fokusa" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 72ad49bf85..0989218e5d 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -124,6 +124,9 @@ msgstr "&Kare piksel (ölçeği koru)" msgid "&Integer scale" msgstr "Tam &sayı ölçeklemesi" +msgid "4:&3 Integer scale" +msgstr "4:&3 Tam sayı ölçeklemesi" + msgid "E&GA/(S)VGA settings" msgstr "EGA/&(S)VGA ayarları" @@ -349,6 +352,9 @@ msgstr "CPU türü:" msgid "Speed:" msgstr "Hız:" +msgid "Frequency:" +msgstr "Sıklık:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Ekran kartı:" msgid "Voodoo Graphics" msgstr "Voodoo Grafikleri" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Grafikleri" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Grafikleri" msgid "XGA Graphics" msgstr "XGA Grafikleri" @@ -406,16 +412,16 @@ msgstr "Oyun kolu 3..." msgid "Joystick 4..." msgstr "Oyun kolu 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Ses kartı 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Ses kartı 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Ses kartı 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Ses kartı 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Farenin bırakılması için F8+F12 tuşlarına basın" msgid "Press F8+F12 or middle button to release mouse" msgstr "Farenin bırakılması için F8+F12 veya farenin orta tuşuna basın" -msgid "Unable to initialize FluidSynth" -msgstr "FluidSynth başlatılamadı" - msgid "Bus" msgstr "Veri yolu" @@ -811,12 +814,6 @@ msgstr "Gelişmiş sektör imajları" msgid "Flux images" msgstr "Flux images" -msgid "Unable to initialize FreeType" -msgstr "FreeType başlatılamadı" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "SDL başlatılamadı, SDL2.dll gerekmektedir" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" @@ -859,8 +856,8 @@ msgstr "86Box Hakkında" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Bir eski bilgisayar emülatörü\n\nYapanlar: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, ve diğerleri.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." msgid "Hardware not available" msgstr "Donanım mevcut değil" @@ -877,15 +874,6 @@ msgstr "libpcap kurulu olduğundan ve libpcap-uyumlu bir internet ağında bulun msgid "Invalid configuration" msgstr "Geçersiz konfigürasyon" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr " ESC/P yazıcı emülasyonu için gereklidir." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr " FluidSynth MIDI çıkışı için gereklidir." - msgid "Entering fullscreen mode" msgstr "Tam ekran moduna geçiliyor" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Sistem Varsayılanı)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Ağ sürücüsü başlatılamadı" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Ağ yapılandırması null sürücüye geçirilecektir" + +msgid "Mouse sensitivity:" +msgstr "Fare hassasiyeti:" + +msgid "Select media images from program working directory" +msgstr "Program çalışma dizininden medya görüntülerini seçme" + +msgid "PIT mode:" +msgstr "PIT modu:" + +msgid "Auto" +msgstr "Otomatik" + +msgid "Slow" +msgstr "Yavaş" + +msgid "Fast" +msgstr "Hızlı" +msgid "&Auto-pause on focus loss" +msgstr "&Odak kaybında otomatik duraklatma" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 4d7708ef6c..76796a57ae 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -124,6 +124,9 @@ msgstr "&Квадратні пікселі (зберегти відношенн msgid "&Integer scale" msgstr "&Цілісночисленне масштабування" +msgid "4:&3 Integer scale" +msgstr "Цілісночисленне масштабування 4:&3" + msgid "E&GA/(S)VGA settings" msgstr "Налаштування E&GA/(S)VGA" @@ -349,6 +352,9 @@ msgstr "Тип ЦП:" msgid "Speed:" msgstr "Швидкість:" +msgid "Frequency:" +msgstr "Частота:" + msgid "FPU:" msgstr "FPU:" @@ -382,8 +388,8 @@ msgstr "Відеокарта:" msgid "Voodoo Graphics" msgstr "Прискорювач Voodoo" -msgid "IBM 8514/a Graphics" -msgstr "Прискорювач IBM 8514/a" +msgid "IBM 8514/A Graphics" +msgstr "Прискорювач IBM 8514/A" msgid "XGA Graphics" msgstr "Прискорювач XGA" @@ -406,16 +412,16 @@ msgstr "Джойстик 3..." msgid "Joystick 4..." msgstr "Джойстик 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "Звукова карта 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "Звукова карта 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "Звукова карта 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "Звукова карта 4:" msgid "MIDI Out Device:" @@ -724,9 +730,6 @@ msgstr "Натисніть F8+F12, щоб звільнити курсор" msgid "Press F8+F12 or middle button to release mouse" msgstr "Натисніть F8+F12 або середню кнопку миші, щоб звільнити курсор" -msgid "Unable to initialize FluidSynth" -msgstr "Неможливо ініціалізувати FluidSynth" - msgid "Bus" msgstr "Шина" @@ -811,12 +814,6 @@ msgstr "Розширені образи секторів" msgid "Flux images" msgstr "Образи Flux" -msgid "Unable to initialize FreeType" -msgstr "Неможливо ініціалізувати FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "Неможливо ініціалізувати SDL, потрібно SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" @@ -857,10 +854,10 @@ msgid "About 86Box" msgstr "Про 86Box" msgid "86Box v" -msgstr "86Box v." +msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Емулятор старих комп'ютерів\n\nАвтори: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." msgid "Hardware not available" msgstr "Обладнання недоступне" @@ -877,15 +874,6 @@ msgstr "Переконайтесь, що libpcap встановлений і в msgid "Invalid configuration" msgstr "Неприпустима конфігурація" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "Для емуляції принтера ESC/P потрібно libfreetype." - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "Для FluidSynth MIDI-висновку потрібно libfluidsynth." - msgid "Entering fullscreen mode" msgstr "Вхід у повноекранний режим" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(Системний)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "Не вдалося ініціалізувати мережевий драйвер" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "Конфігурацію мережі буде змінено на нульовий драйвер" + +msgid "Mouse sensitivity:" +msgstr "Чутливість миші:" + +msgid "Select media images from program working directory" +msgstr "Виберіть медіа-зображення з робочої директорії програми" + +msgid "PIT mode:" +msgstr "Режим PIT:" + +msgid "Auto" +msgstr "Авто" + +msgid "Slow" +msgstr "Повільний" + +msgid "Fast" +msgstr "Швидкий" +msgid "&Auto-pause on focus loss" +msgstr "&Автопауза при втраті фокусу" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index da37b4fb25..94c468d802 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -124,6 +124,9 @@ msgstr "保持比例(&S)" msgid "&Integer scale" msgstr "整数比例(&I)" +msgid "4:&3 Integer scale" +msgstr "4:3 整数比例(&3)" + msgid "E&GA/(S)VGA settings" msgstr "EGA/(S)VGA 设置(&G)" @@ -206,13 +209,13 @@ msgid "&About 86Box..." msgstr "关于 86Box(&A)..." msgid "&New image..." -msgstr "新建镜像(&N)..." +msgstr "新建映像(&N)..." msgid "&Existing image..." -msgstr "打开已存在的镜像(&E)..." +msgstr "打开已存在的映像(&E)..." msgid "Existing image (&Write-protected)..." -msgstr "打开已存在的镜像并写保护(&W)..." +msgstr "打开已存在的映像并写保护(&W)..." msgid "&Record" msgstr "录制(&R)" @@ -230,7 +233,7 @@ msgid "E&ject" msgstr "弹出(&J)" msgid "&Image..." -msgstr "镜像(&I)..." +msgstr "映像(&I)..." msgid "E&xport to 86F..." msgstr "导出为 86F 格式(&x)..." @@ -242,7 +245,7 @@ msgid "E&mpty" msgstr "空置驱动器(&M)" msgid "&Reload previous image" -msgstr "载入上一个镜像(&R)" +msgstr "载入上一个映像(&R)" msgid "&Folder..." msgstr "文件夹(&F)..." @@ -284,7 +287,7 @@ msgid "Sound Gain" msgstr "音量增益" msgid "New Image" -msgstr "新建镜像" +msgstr "新建映像" msgid "Settings" msgstr "设置" @@ -349,6 +352,9 @@ msgstr "CPU 类型:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "频率:" + msgid "FPU:" msgstr "浮点处理器 (FPU):" @@ -382,8 +388,8 @@ msgstr "显卡:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" @@ -406,16 +412,16 @@ msgstr "操纵杆 3..." msgid "Joystick 4..." msgstr "操纵杆 4..." -msgid "Sound card 1:" +msgid "Sound card #1:" msgstr "声卡 1:" -msgid "Sound card 2:" +msgid "Sound card #2:" msgstr "声卡 2:" -msgid "Sound card 3:" +msgid "Sound card #3:" msgstr "声卡 3:" -msgid "Sound card 4:" +msgid "Sound card #4:" msgstr "声卡 4:" msgid "MIDI Out Device:" @@ -533,7 +539,7 @@ msgid "&New..." msgstr "新建(&N)..." msgid "&Existing..." -msgstr "已有镜像(&E)..." +msgstr "已有映像(&E)..." msgid "&Remove" msgstr "移除(&R)" @@ -566,7 +572,7 @@ msgid "Type:" msgstr "类型:" msgid "Image Format:" -msgstr "镜像格式:" +msgstr "映像格式:" msgid "Block Size:" msgstr "块大小:" @@ -599,7 +605,7 @@ msgid "ISA RTC:" msgstr "ISA 实时时钟:" msgid "ISA Memory Expansion" -msgstr "ISA 内存扩充" +msgstr "ISA 内存扩展" msgid "Card 1:" msgstr "扩展卡 1:" @@ -647,10 +653,10 @@ msgid "ZIP %03i %i (%s): %ls" msgstr "ZIP %03i %i (%s): %ls" msgid "ZIP images" -msgstr "ZIP 镜像" +msgstr "ZIP 映像" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box 找不到任何可用的 ROM 镜像。\n\n请下载ROM 包并将其解压到 \"roms\" 文件夹。" +msgstr "86Box 找不到任何可用的 ROM 映像。\n\n请下载 ROM 包并将其解压到 \"roms\" 文件夹中。" msgid "(empty)" msgstr "(空)" @@ -668,13 +674,13 @@ msgid "Off" msgstr "关" msgid "All images" -msgstr "所有镜像" +msgstr "所有映像" msgid "Basic sector images" -msgstr "基本扇区镜像" +msgstr "基本扇区映像" msgid "Surface images" -msgstr "表面镜像" +msgstr "表面映像" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." msgstr "由于 roms/machines 文件夹中缺少合适的 ROM,机型 \"%hs\" 不可用。将切换到其他可用机型。" @@ -724,9 +730,6 @@ msgstr "按下 F8+F12 释放鼠标" msgid "Press F8+F12 or middle button to release mouse" msgstr "按下 F8+F12 或鼠标中键释放鼠标" -msgid "Unable to initialize FluidSynth" -msgstr "无法初始化 FluidSynth" - msgid "Bus" msgstr "总线" @@ -806,16 +809,10 @@ msgid "Floppy %i (%s): %ls" msgstr "软盘 %i (%s): %ls" msgid "Advanced sector images" -msgstr "高级扇区镜像" +msgstr "高级扇区映像" msgid "Flux images" -msgstr "Flux 镜像" - -msgid "Unable to initialize FreeType" -msgstr "无法初始化 FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "无法初始化 SDL,需要 SDL2.dll" +msgstr "Flux 映像" msgid "Are you sure you want to hard reset the emulated machine?" msgstr "确定要硬重置模拟器吗?" @@ -830,7 +827,7 @@ msgid "MO %i (%ls): %ls" msgstr "磁光盘 %i (%ls): %ls" msgid "MO images" -msgstr "磁光盘镜像" +msgstr "磁光盘映像" msgid "Welcome to 86Box!" msgstr "欢迎使用 86Box!" @@ -859,8 +856,8 @@ msgstr "关于 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" msgid "Hardware not available" msgstr "硬件不可用" @@ -877,15 +874,6 @@ msgstr "请确认 libpcap 已安装且使用兼容 libpcap 的网络连接。" msgid "Invalid configuration" msgstr "无效配置" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "ESC/P 打印机模拟需要" - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "FluidSynth MIDI 输出需要" - msgid "Entering fullscreen mode" msgstr "正在进入全屏模式" @@ -920,7 +899,7 @@ msgid "Don't reset" msgstr "不重置" msgid "CD-ROM images" -msgstr "光盘镜像" +msgstr "光盘映像" msgid "%hs Device Configuration" msgstr "%hs 设备配置" @@ -947,13 +926,13 @@ msgid "Cassette: %s" msgstr "磁带: %s" msgid "Cassette images" -msgstr "磁带镜像" +msgstr "磁带映像" msgid "Cartridge %i: %ls" msgstr "卡带 %i: %ls" msgid "Cartridge images" -msgstr "卡带镜像" +msgstr "卡带映像" msgid "Error initializing renderer" msgstr "初始化渲染器时出错" @@ -1004,13 +983,13 @@ msgid "Add Existing Hard Disk" msgstr "添加已存在的硬盘" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI 磁盘镜像不能超过 4 GB。" +msgstr "HDI 磁盘映像不能超过 4 GB。" msgid "Disk images cannot be larger than 127 GB." -msgstr "磁盘镜像不能超过 127 GB。" +msgstr "磁盘映像不能超过 127 GB。" msgid "Hard disk images" -msgstr "硬盘镜像" +msgstr "硬盘映像" msgid "Unable to read file" msgstr "无法读取文件" @@ -1019,19 +998,19 @@ msgid "Unable to write file" msgstr "无法写入文件" msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "不支持非 512 字节扇区大小的 HDI 或 HDX 镜像。" +msgstr "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" msgid "USB is not yet supported" msgstr "尚未支持 USB" msgid "Disk image file already exists" -msgstr "磁盘镜像文件已存在" +msgstr "磁盘映像文件已存在" msgid "Please specify a valid file name." msgstr "请指定有效的文件名。" msgid "Disk image created" -msgstr "已创建磁盘镜像" +msgstr "已创建磁盘映像" msgid "Make sure the file exists and is readable." msgstr "请确定此文件已存在并可读取。" @@ -1040,16 +1019,16 @@ msgid "Make sure the file is being saved to a writable directory." msgstr "请确定此文件保存在可写目录中。" msgid "Disk image too large" -msgstr "磁盘镜像太大" +msgstr "磁盘映像太大" msgid "Remember to partition and format the newly-created drive." -msgstr "请记得为新创建的镜像分区并格式化。" +msgstr "请记得为新创建的映像分区并格式化。" msgid "The selected file will be overwritten. Are you sure you want to use it?" msgstr "选定的文件将被覆盖。确定继续使用此文件吗?" msgid "Unsupported disk image" -msgstr "不支持的磁盘镜像" +msgstr "不支持的磁盘映像" msgid "Overwrite" msgstr "覆盖" @@ -1058,13 +1037,13 @@ msgid "Don't overwrite" msgstr "不覆盖" msgid "Raw image (.img)" -msgstr "原始镜像 (.img)" +msgstr "原始映像 (.img)" msgid "HDI image (.hdi)" -msgstr "HDI 镜像 (.hdi)" +msgstr "HDI 映像 (.hdi)" msgid "HDX image (.hdx)" -msgstr "HDX 镜像 (.hdx)" +msgstr "HDX 映像 (.hdx)" msgid "Fixed-size VHD (.vhd)" msgstr "固定大小 VHD (.vhd)" @@ -1088,7 +1067,7 @@ msgid "Select the parent VHD" msgstr "选择父 VHD 文件" msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" -msgstr "父映像可能在创建差异镜像后被修改。\n\n如果镜像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" +msgstr "父映像可能在创建差异映像后被修改。\n\n如果映像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" msgid "Parent and child disk timestamps do not match" msgstr "父盘与子盘的时间戳不匹配" @@ -1220,8 +1199,29 @@ msgid "(System Default)" msgstr "(系统默认)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "网络驱动程序初始化失败" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "网络配置将切换为空驱动程序" + +msgid "Mouse sensitivity:" +msgstr "鼠标敏感度:" + +msgid "Select media images from program working directory" +msgstr "从程序工作目录中选择介质映像" + +msgid "PIT mode:" +msgstr "PIT 模式:" + +msgid "Auto" +msgstr "自动" + +msgid "Slow" +msgstr "慢" + +msgid "Fast" +msgstr "快" + +msgid "&Auto-pause on focus loss" +msgstr "失去焦点时自动暂停(&A)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index f1bbfffd9a..7836f7ef89 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -124,6 +124,9 @@ msgstr "保持比例(&S)" msgid "&Integer scale" msgstr "整數比例(&I)" +msgid "4:&3 Integer scale" +msgstr "4:3 整數比例(&3)" + msgid "E&GA/(S)VGA settings" msgstr "EGA/(S)VGA 設定(&G)" @@ -182,7 +185,7 @@ msgid "Take s&creenshot\tCtrl+F11" msgstr "擷圖(&C)\tCtrl+F11" msgid "&Preferences..." -msgstr "首選項(&P)..." +msgstr "偏好設定(&P)..." msgid "Enable &Discord integration" msgstr "啟用 Discord 整合(&D)" @@ -278,7 +281,7 @@ msgid "&Remove shader" msgstr "移除著色器(&R)" msgid "Preferences" -msgstr "首選項" +msgstr "偏好設定" msgid "Sound Gain" msgstr "音量增益" @@ -349,6 +352,9 @@ msgstr "CPU 類型:" msgid "Speed:" msgstr "速度:" +msgid "Frequency:" +msgstr "頻率:" + msgid "FPU:" msgstr "浮點處理器 (FPU):" @@ -365,7 +371,7 @@ msgid "Time synchronization" msgstr "時間同步" msgid "Disabled" -msgstr "禁用" +msgstr "停用" msgid "Enabled (local time)" msgstr "啟用 (本地時間)" @@ -382,8 +388,8 @@ msgstr "顯示卡:" msgid "Voodoo Graphics" msgstr "Voodoo Graphics" -msgid "IBM 8514/a Graphics" -msgstr "IBM 8514/a Graphics" +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" @@ -406,17 +412,17 @@ msgstr "搖桿 3..." msgid "Joystick 4..." msgstr "搖桿 4..." -msgid "Sound card 1:" -msgstr "音訊卡 1:" +msgid "Sound card #1:" +msgstr "音效卡 1:" -msgid "Sound card 2:" -msgstr "音訊卡 2:" +msgid "Sound card #2:" +msgstr "音效卡 2:" -msgid "Sound card 3:" -msgstr "音訊卡 3:" +msgid "Sound card #3:" +msgstr "音效卡 3:" -msgid "Sound card 4:" -msgstr "音訊卡 4:" +msgid "Sound card #4:" +msgstr "音效卡 4:" msgid "MIDI Out Device:" msgstr "MIDI 輸出裝置:" @@ -557,7 +563,7 @@ msgid "Heads:" msgstr "磁頭(H):" msgid "Cylinders:" -msgstr "柱面(C):" +msgstr "磁柱(C):" msgid "Size (MB):" msgstr "大小 (MB):" @@ -724,9 +730,6 @@ msgstr "按下 F8+F12 釋放滑鼠" msgid "Press F8+F12 or middle button to release mouse" msgstr "按下 F8+F12 或滑鼠中鍵釋放滑鼠" -msgid "Unable to initialize FluidSynth" -msgstr "無法初始化 FluidSynth" - msgid "Bus" msgstr "匯流排" @@ -811,12 +814,6 @@ msgstr "進階磁區映像" msgid "Flux images" msgstr "Flux 映像" -msgid "Unable to initialize FreeType" -msgstr "無法初始化 FreeType" - -msgid "Unable to initialize SDL, SDL2.dll is required" -msgstr "無法初始化 SDL,需要 SDL2.dll" - msgid "Are you sure you want to hard reset the emulated machine?" msgstr "確定要硬重設模擬器嗎?" @@ -859,8 +856,8 @@ msgstr "關於 86Box" msgid "86Box v" msgstr "86Box v" -msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "一個舊式電腦模擬器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" msgid "Hardware not available" msgstr "硬體不可用" @@ -877,15 +874,6 @@ msgstr "請確認 libpcap 已安裝且使用相容 libpcap 的網路連線。" msgid "Invalid configuration" msgstr "無效設定" -msgid "freetype.dll" -msgstr "freetype.dll" - -msgid "libfreetype" -msgstr "libfreetype" - -msgid " is required for ESC/P printer emulation." -msgstr "ESC/P 印表機模擬需要" - msgid "gsdll32.dll" msgstr "gsdll32.dll" @@ -895,15 +883,6 @@ msgstr "libgs" msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." msgstr " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" -msgid "libfluidsynth.dll" -msgstr "libfluidsynth.dll" - -msgid "libfluidsynth" -msgstr "libfluidsynth" - -msgid " is required for FluidSynth MIDI output." -msgstr "FluidSynth MIDI 輸出需要" - msgid "Entering fullscreen mode" msgstr "正在進入全螢幕模式" @@ -938,7 +917,7 @@ msgid "You are loading an unsupported configuration" msgstr "正在載入一個不受支援的設定" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" +msgstr "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" msgid "Continue" msgstr "繼續" @@ -1220,8 +1199,28 @@ msgid "(System Default)" msgstr "(系統預設)" msgid "Failed to initialize network driver" -msgstr "Failed to initialize network driver" +msgstr "初始化網路驅動程式失敗" msgid "The network configuration will be switched to the null driver" -msgstr "The network configuration will be switched to the null driver" +msgstr "網路設定將切換為空驅動程式" + +msgid "Mouse sensitivity:" +msgstr "滑鼠靈敏度:" + +msgid "Select media images from program working directory" +msgstr "從程式工作目錄中選擇介質映像" + +msgid "PIT mode:" +msgstr "PIT模式:" + +msgid "Auto" +msgstr "自動" + +msgid "Slow" +msgstr "慢" + +msgid "Fast" +msgstr "快" +msgid "&Auto-pause on focus loss" +msgstr "失去焦點時自動暫停(&A)" diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm index 6f84beee55..ff4e7c4d20 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -17,13 +17,6 @@ extern void plat_mouse_capture(int); } -typedef struct mouseinputdata { - int deltax, deltay, deltaz; - int mousebuttons; -} mouseinputdata; - -static mouseinputdata mousedata; - CocoaEventFilter::~CocoaEventFilter() { } @@ -31,6 +24,8 @@ bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { + int b = 0; + if (mouse_capture) { if (eventType == "mac_generic_NSEvent") { NSEvent *event = (NSEvent *) message; @@ -38,12 +33,11 @@ || [event type] == NSEventTypeLeftMouseDragged || [event type] == NSEventTypeRightMouseDragged || [event type] == NSEventTypeOtherMouseDragged) { - mousedata.deltax += [event deltaX]; - mousedata.deltay += [event deltaY]; + mouse_scalef((double) [event deltaX], (double) [event deltaY]); return true; } if ([event type] == NSEventTypeScrollWheel) { - mousedata.deltaz += [event deltaY]; + mouse_set_z([event deltaY]); return true; } switch ([event type]) { @@ -51,27 +45,32 @@ return false; case NSEventTypeLeftMouseDown: { - mousedata.mousebuttons |= 1; + b = mouse_get_buttons_ex() | 1; + mouse_set_buttons_ex(b); break; } case NSEventTypeLeftMouseUp: { - mousedata.mousebuttons &= ~1; + b = mouse_get_buttons_ex() & ~1; + mouse_set_buttons_ex(b); break; } case NSEventTypeRightMouseDown: { - mousedata.mousebuttons |= 2; + b = mouse_get_buttons_ex() | 2; + mouse_set_buttons_ex(b); break; } case NSEventTypeRightMouseUp: { - mousedata.mousebuttons &= ~2; + b = mouse_get_buttons_ex() & ~2; + mouse_set_buttons_ex(b); break; } case NSEventTypeOtherMouseDown: { - mousedata.mousebuttons |= 4; + b = mouse_get_buttons_ex() | 4; + mouse_set_buttons_ex(b); break; } case NSEventTypeOtherMouseUp: @@ -80,7 +79,8 @@ plat_mouse_capture(0); return true; } - mousedata.mousebuttons &= ~4; + b = mouse_get_buttons_ex() & ~4; + mouse_set_buttons_ex(b); break; } } @@ -89,13 +89,3 @@ } return false; } - -extern "C" void -macos_poll_mouse() -{ - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; - mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; -} diff --git a/src/qt/qt.c b/src/qt/qt.c index c2a5396da0..47f5b94100 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -52,10 +52,8 @@ plat_vidapi(char *api) return 3; } else if (!strcasecmp(api, "qt_vulkan")) { return 4; - } else if (!strcasecmp(api, "qt_d3d9")) { - return 5; } else if (!strcasecmp(api, "vnc")) { - return 6; + return 5; } return 0; @@ -83,9 +81,6 @@ plat_vidapi_name(int api) name = "qt_vulkan"; break; case 5: - name = "qt_d3d9"; - break; - case 6: name = "vnc"; break; default: diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c index 6e28966b03..1facae4868 100644 --- a/src/qt/qt_cdrom.c +++ b/src/qt/qt_cdrom.c @@ -10,8 +10,7 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * * Copyright 2016-2018 Miran Grca. diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp deleted file mode 100644 index 868f58274f..0000000000 --- a/src/qt/qt_d3d9renderer.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include "qt_mainwindow.hpp" -#include "qt_d3d9renderer.hpp" -#include -#include - -extern "C" { -#include <86box/86box.h> -#include <86box/video.h> -} - -D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) - : QWidget { parent } - , RendererCommon() -{ - QPalette pal = palette(); - pal.setColor(QPalette::Window, Qt::black); - setAutoFillBackground(true); - setPalette(pal); - - setAttribute(Qt::WA_NativeWindow); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_OpaquePaintEvent); - - windowHandle = (HWND) winId(); - surfaceInUse = true; - finalized = true; - - RendererCommon::parentWidget = parent; - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->m_monitor_index = monitor_index; - - d3d9surface = nullptr; - d3d9dev = nullptr; - d3d9 = nullptr; -} - -D3D9Renderer::~D3D9Renderer() -{ - finalize(); -} - -void -D3D9Renderer::finalize() -{ - if (!finalized) { - while (surfaceInUse) { } - finalized = true; - } - surfaceInUse = true; - if (d3d9surface) { - d3d9surface->Release(); - d3d9surface = nullptr; - } - if (d3d9dev) { - d3d9dev->Release(); - d3d9dev = nullptr; - } - if (d3d9) { - d3d9->Release(); - d3d9 = nullptr; - } -} - -void -D3D9Renderer::hideEvent(QHideEvent *event) -{ - finalize(); -} - -void -D3D9Renderer::showEvent(QShowEvent *event) -{ - if (d3d9) finalize(); - params = {}; - - if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) { - return error("Failed to create Direct3D 9 context"); - } - - params.Windowed = true; - params.SwapEffect = D3DSWAPEFFECT_FLIPEX; - params.BackBufferWidth = width() * devicePixelRatioF(); - params.BackBufferHeight = height() * devicePixelRatioF(); - params.BackBufferCount = 1; - params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - params.hDeviceWindow = (HWND) winId(); - - HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) - result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 device"); - } - - result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) - result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) { - return error("Failed to create Direct3D 9 surface"); - } - if (!alreadyInitialized) { - emit initialized(); - alreadyInitialized = true; - } - surfaceInUse = false; - finalized = false; -} - -void -D3D9Renderer::paintEvent(QPaintEvent *event) -{ - IDirect3DSurface9 *backbuffer = nullptr; - RECT srcRect; - RECT dstRect; - HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - - if (FAILED(result)) { - return; - } - - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - dstRect.top = destination.top() * devicePixelRatioF(); - dstRect.bottom = destination.bottom() * devicePixelRatioF(); - dstRect.left = destination.left() * devicePixelRatioF(); - dstRect.right = destination.right() * devicePixelRatioF(); - d3d9dev->BeginScene(); - d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); - while (surfaceInUse) { } - surfaceInUse = true; - d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR); - result = d3d9dev->EndScene(); - surfaceInUse = false; - if (SUCCEEDED(result)) { - if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) { - finalize(); - showEvent(nullptr); - } - } -} - -bool -D3D9Renderer::event(QEvent *event) -{ - bool res = false; - if (!eventDelegate(event, res)) - return QWidget::event(event); - return res; -} - -void -D3D9Renderer::resizeEvent(QResizeEvent *event) -{ - onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF()); - - params.BackBufferWidth = event->size().width() * devicePixelRatioF(); - params.BackBufferHeight = event->size().height() * devicePixelRatioF(); - if (d3d9dev) - d3d9dev->Reset(¶ms); - QWidget::resizeEvent(event); -} - -void -D3D9Renderer::blit(int x, int y, int w, int h) -{ - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { - video_blit_complete_monitor(m_monitor_index); - return; - } - surfaceInUse = true; - auto origSource = source; - source.setRect(x, y, w, h); - RECT srcRect; - D3DLOCKED_RECT lockRect; - srcRect.top = source.top(); - srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - - if (monitors[m_monitor_index].mon_screenshots) { - video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index); - } - if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) { - for (int y1 = 0; y1 < h; y1++) { - video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); - } - video_blit_complete_monitor(m_monitor_index); - d3d9surface->UnlockRect(); - } else - video_blit_complete_monitor(m_monitor_index); - if (origSource != source) - onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); - surfaceInUse = false; - QTimer::singleShot(0, this, [this] { this->update(); }); -} diff --git a/src/qt/qt_d3d9renderer.hpp b/src/qt/qt_d3d9renderer.hpp deleted file mode 100644 index 37c27443b6..0000000000 --- a/src/qt/qt_d3d9renderer.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef D3D9RENDERER_HPP -#define D3D9RENDERER_HPP - -#include -#include "qt_renderercommon.hpp" - -#include -#include -#include - -class D3D9Renderer : public QWidget, public RendererCommon { - Q_OBJECT -public: - explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0); - ~D3D9Renderer(); - bool hasBlitFunc() override { return true; } - void blit(int x, int y, int w, int h) override; - void finalize() override; - -protected: - void showEvent(QShowEvent *event) override; - void hideEvent(QHideEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; - bool event(QEvent *event) override; - QPaintEngine *paintEngine() const override { return nullptr; } - -signals: - void initialized(); - void error(QString); - -private: - HWND windowHandle = 0; - D3DPRESENT_PARAMETERS params {}; - IDirect3D9Ex *d3d9 = nullptr; - IDirect3DDevice9Ex *d3d9dev = nullptr; - IDirect3DSurface9 *d3d9surface = nullptr; - - std::atomic surfaceInUse { false }; - std::atomic finalized { false }; - bool alreadyInitialized = false; - int m_monitor_index = 0; -}; - -#endif // D3D9RENDERER_HPP diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index eaa5e95667..6c7db0f3d3 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -138,6 +138,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se { auto *cbox = new QComboBox(); cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); auto *model = cbox->model(); int currentIndex = -1; int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); @@ -158,6 +159,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se { auto *cbox = new QComboBox(); cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); auto *model = cbox->model(); int currentIndex = -1; int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); @@ -181,6 +183,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se { auto *cbox = new QComboBox(); cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); auto *model = cbox->model(); int currentIndex = -1; int selected = 0; @@ -210,6 +213,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se { auto *cbox = new QComboBox(); cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); auto *model = cbox->model(); int currentIndex = -1; char *selected; @@ -269,6 +273,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se { auto *cbox = new QComboBox(); cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); auto *model = cbox->model(); int currentIndex = 0; auto serialDevices = EnumerateSerialDevices(); diff --git a/src/qt/qt_filefield.cpp b/src/qt/qt_filefield.cpp index b6db5e611d..9272e31a19 100644 --- a/src/qt/qt_filefield.cpp +++ b/src/qt/qt_filefield.cpp @@ -31,6 +31,12 @@ FileField::FileField(QWidget *parent) fileName_ = ui->label->text(); emit fileSelected(ui->label->text(), true); }); + + connect(ui->label, &QLineEdit::textChanged, this, [this]() { + fileName_ = ui->label->text(); + emit fileTextEntered(ui->label->text(), true); + }); + this->setFixedWidth(this->sizeHint().width() + ui->pushButton->sizeHint().width()); } diff --git a/src/qt/qt_filefield.hpp b/src/qt/qt_filefield.hpp index ee011a38bd..e3569fd31b 100644 --- a/src/qt/qt_filefield.hpp +++ b/src/qt/qt_filefield.hpp @@ -19,12 +19,14 @@ class FileField : public QWidget { void setFilter(const QString &filter) { filter_ = filter; } QString selectedFilter() const { return selectedFilter_; } + void setselectedFilter(const QString &selectedFilter) { selectedFilter_ = selectedFilter; } void setCreateFile(bool createFile) { createFile_ = createFile; } bool createFile() { return createFile_; } signals: void fileSelected(const QString &fileName, bool precheck = false); + void fileTextEntered(const QString &fileName, bool precheck = false); private slots: void on_pushButton_clicked(); diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 6489b9c779..5dab101b84 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -84,6 +84,13 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) ui->lineEditSize->setValidator(new QIntValidator()); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + filters = QStringList({ tr("Raw image") % util::DlgFilter({ "img" }, true), + tr("HDI image") % util::DlgFilter({ "hdi" }, true), + tr("HDX image") % util::DlgFilter({ "hdx" }, true), + tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true), + tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true), + tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) }); + if (existing) { ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?", "im?", "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true)); @@ -99,24 +106,26 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) connect(ui->fileField, &FileField::fileSelected, this, &HarddiskDialog::onExistingFileSelected); } else { - QStringList filters({ tr("Raw image") % util::DlgFilter({ "img" }, true), - tr("HDI image") % util::DlgFilter({ "hdi" }, true), - tr("HDX image") % util::DlgFilter({ "hdx" }, true), - tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true), - tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true), - tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) }); - ui->fileField->setFilter(filters.join(";;")); setWindowTitle(tr("Add New Hard Disk")); ui->fileField->setCreateFile(true); - connect(ui->fileField, &FileField::fileSelected, this, [this, filters] { + // Enable the OK button as long as the filename length is non-zero + connect(ui->fileField, &FileField::fileTextEntered, this, [this] { + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled((this->fileName().length() > 0)); + }); + + connect(ui->fileField, &FileField::fileSelected, this, [this] { int filter = filters.indexOf(ui->fileField->selectedFilter()); if (filter > -1) ui->comboBoxFormat->setCurrentIndex(filter); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); }); + // Set the default format to Dynamic-size VHD. Do it last after everything is set up + // so the currentIndexChanged signal can do what is needed + ui->comboBoxFormat->setCurrentIndex(DEFAULT_DISK_FORMAT); + ui->fileField->setselectedFilter(filters.value(DEFAULT_DISK_FORMAT)); } } @@ -179,6 +188,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) ui->comboBoxBlockSize->show(); ui->labelBlockSize->show(); } + ui->fileField->setselectedFilter(filters.value(index)); } /* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry, @@ -311,16 +321,16 @@ HarddiskDialog::onCreateNewFile() ui->progressBar->setEnabled(true); setResult(QDialog::Rejected); - quint64 size = ui->lineEditSize->text().toULongLong() << 20U; + uint32_t sector_size = 512; + quint64 size = (static_cast(cylinders_) * static_cast(heads_) * static_cast(sectors_) * static_cast(sector_size)); if (size > 0x1FFFFFFE00LL) { QMessageBox::critical(this, tr("Disk image too large"), tr("Disk images cannot be larger than 127 GB.")); return; } - int img_format = ui->comboBoxFormat->currentIndex(); - uint32_t zero = 0; - uint32_t base = 0x1000; - uint32_t sector_size = 512; + int img_format = ui->comboBoxFormat->currentIndex(); + uint32_t zero = 0; + uint32_t base = 0x1000; auto fileName = ui->fileField->fileName(); QString expectedSuffix; @@ -501,24 +511,24 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) { // TODO : Over to non-existing file selected - /* +#if 0 if (!(existing & 1)) { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) { - fclose(f); + fp = _wfopen(wopenfilestring, L"rb"); + if (fp != NULL) { + fclose(fp); if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) / * yes * / return FALSE; } } - f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (f == NULL) { + fp = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); + if (fp == NULL) { hdd_add_file_open_error: - fclose(f); + fclose(fp); settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); return TRUE; } - */ +#endif uint64_t size = 0; uint32_t sector_size = 0; diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 0d5fa13bc0..9de61c51b6 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -52,6 +52,11 @@ private slots: bool disallowSizeModifications = false; + QStringList filters; + // "Dynamic-size VHD" is number 4 in the `filters` list and the + // comboBoxFormat model + const uint8_t DEFAULT_DISK_FORMAT = 4; + bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); bool checkAndAdjustSectors(); diff --git a/src/qt/qt_harddiskdialog.ui b/src/qt/qt_harddiskdialog.ui index 84c5576600..91499d2cbf 100644 --- a/src/qt/qt_harddiskdialog.ui +++ b/src/qt/qt_harddiskdialog.ui @@ -50,7 +50,11 @@ - + + + 30 + + @@ -106,7 +110,11 @@ - + + + 30 + + @@ -172,7 +180,11 @@ - + + + 30 + + @@ -182,10 +194,18 @@ - + + + 30 + + - + + + 30 + + @@ -207,7 +227,11 @@ - + + + 30 + + diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 55b7fa8205..dda36917f2 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -49,16 +49,24 @@ void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { model->removeRows(0, model->rowCount()); +#if 0 model->insertRows(0, 4); +#else + model->insertRows(0, 3); +#endif model->setData(model->index(0, 0), QObject::tr("Disabled")); model->setData(model->index(1, 0), QObject::tr("ATAPI")); model->setData(model->index(2, 0), QObject::tr("SCSI")); +#if 0 model->setData(model->index(3, 0), QObject::tr("Mitsumi")); +#endif model->setData(model->index(0, 0), HDD_BUS_DISABLED, Qt::UserRole); model->setData(model->index(1, 0), HDD_BUS_ATAPI, Qt::UserRole); model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); +#if 0 model->setData(model->index(3, 0), CDROM_BUS_MITSUMI, Qt::UserRole); +#endif } void @@ -67,8 +75,10 @@ Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) int num_preset; switch (bus) { - case HDD_BUS_IDE: case HDD_BUS_ESDI: + case HDD_BUS_IDE: + case HDD_BUS_ATAPI: + case HDD_BUS_SCSI: num_preset = hdd_preset_get_num(); break; diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index da23c4b058..f7861d2bdf 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -53,6 +53,7 @@ class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, publi { onResize(size().width(), size().height()); } + std::vector> getBuffers() override; HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index e91cb9086a..e03d57e09b 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -106,6 +106,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) auto label = new QLabel(joystick_get_axis_name(type, c), this); auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxAxis%1").arg(QString::number(c))); + cbox->setMaxVisibleItems(30); auto model = cbox->model(); for (int d = 0; d < plat_joystick_state[joystick].nr_axes; d++) { @@ -117,19 +118,12 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0); } - for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) { - Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0); - } - int nr_axes = plat_joystick_state[joystick].nr_axes; - int nr_povs = plat_joystick_state[joystick].nr_povs; int mapping = joystick_state[joystick_nr].axis_mapping[c]; if (mapping & POV_X) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); else if (mapping & POV_Y) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1); - else if (mapping & SLIDER) - cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3)); else cbox->setCurrentIndex(mapping); @@ -146,6 +140,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) auto label = new QLabel(joystick_get_button_name(type, c), this); auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxButton%1").arg(QString::number(c))); + cbox->setMaxVisibleItems(30); auto model = cbox->model(); for (int d = 0; d < plat_joystick_state[joystick].nr_buttons; d++) { @@ -172,6 +167,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) } auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxPov%1").arg(QString::number(c))); + cbox->setMaxVisibleItems(30); auto model = cbox->model(); for (int d = 0; d < plat_joystick_state[joystick].nr_povs; d++) { @@ -183,7 +179,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); } - int mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + int mapping = joystick_state[joystick_nr].pov_mapping[c / 2][c & 1]; int nr_povs = plat_joystick_state[joystick].nr_povs; if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); @@ -192,14 +188,6 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) else cbox->setCurrentIndex(mapping + nr_povs * 2); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - cbox->setCurrentIndex((mapping & 3) * 2); - else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3) * 2 + 1); - else - cbox->setCurrentIndex(mapping + nr_povs * 2); - ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); diff --git a/src/qt/qt_joystickconfiguration.ui b/src/qt/qt_joystickconfiguration.ui index 7789b48c40..139b99ca52 100644 --- a/src/qt/qt_joystickconfiguration.ui +++ b/src/qt/qt_joystickconfiguration.ui @@ -25,7 +25,11 @@ - + + + 30 + + diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index e667ae4ebd..d7b115a648 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -278,7 +278,7 @@ MachineStatus::hasIDE() bool MachineStatus::hasSCSI() { - return machine_has_flags(machine, MACHINE_SCSI_DUAL) > 0; + return machine_has_flags(machine, MACHINE_SCSI) > 0; } void @@ -429,11 +429,12 @@ MachineStatus::refresh(QStatusBar *sbar) bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; bool has_esdi = machine_has_flags(machine, MACHINE_ESDI) > 0; - int c_mfm = hdd_count(HDD_BUS_MFM); - int c_esdi = hdd_count(HDD_BUS_ESDI); - int c_xta = hdd_count(HDD_BUS_XTA); - int c_ide = hdd_count(HDD_BUS_IDE); - int c_scsi = hdd_count(HDD_BUS_SCSI); + int c_mfm = hdd_count(HDD_BUS_MFM); + int c_esdi = hdd_count(HDD_BUS_ESDI); + int c_xta = hdd_count(HDD_BUS_XTA); + int c_ide = hdd_count(HDD_BUS_IDE); + int c_atapi = hdd_count(HDD_BUS_ATAPI); + int c_scsi = hdd_count(HDD_BUS_SCSI); sbar->removeWidget(d->cassette.label.get()); for (int i = 0; i < 2; ++i) { @@ -597,12 +598,21 @@ MachineStatus::refresh(QStatusBar *sbar) d->hdds[HDD_BUS_XTA].label->setToolTip(tr("Hard disk (%s)").replace("%s", "XTA")); sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get()); } - if ((hasIDE() || hdc_name.left(5) == QStringLiteral("xtide") || hdc_name.left(3) == QStringLiteral("ide")) && c_ide > 0) { - d->hdds[HDD_BUS_IDE].label = std::make_unique(); - d->hdds[HDD_BUS_IDE].setActive(false); - d->hdds[HDD_BUS_IDE].refresh(); - d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); - sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); + if (hasIDE() || hdc_name.left(5) == QStringLiteral("xtide") || hdc_name.left(3) == QStringLiteral("ide")) { + if (c_ide > 0) { + d->hdds[HDD_BUS_IDE].label = std::make_unique(); + d->hdds[HDD_BUS_IDE].setActive(false); + d->hdds[HDD_BUS_IDE].refresh(); + d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); + sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); + } + if (c_atapi > 0) { + d->hdds[HDD_BUS_ATAPI].label = std::make_unique(); + d->hdds[HDD_BUS_ATAPI].setActive(false); + d->hdds[HDD_BUS_ATAPI].refresh(); + d->hdds[HDD_BUS_ATAPI].label->setToolTip(tr("Hard disk (%s)").replace("%s", "ATAPI")); + sbar->addWidget(d->hdds[HDD_BUS_ATAPI].label.get()); + } } if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { d->hdds[HDD_BUS_SCSI].label = std::make_unique(); diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index daf13f72d6..cafd4fd8e4 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #ifdef QT_STATIC /* Static builds need plugin imports */ @@ -92,6 +94,7 @@ main_thread_fn() int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); + plat_set_thread_name(NULL, "main_thread_fn"); framecountx = 0; // title_update = 1; old_time = elapsed_timer.elapsed(); @@ -135,6 +138,8 @@ main_thread_fn() } } else { /* Just so we dont overload the host OS. */ + if (dopause) + ack_pause(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } @@ -190,6 +195,23 @@ main(int argc, char *argv[]) QApplication::setFont(QFont(font_name, font_size.toInt())); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif + +#ifndef Q_OS_MACOS +# ifdef RELEASE_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); +# elif defined ALPHA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); +# elif defined BETA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); +# else + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); +# endif + +# ifdef Q_OS_UNIX + app.setDesktopFileName("net.86box.86Box"); +# endif +#endif + if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; @@ -204,6 +226,18 @@ main(int argc, char *argv[]) return 0; } + /* Warn the user about unsupported configs */ + if (cpu_override) { + QMessageBox warningbox(QMessageBox::Icon::Warning, QObject::tr("You are loading an unsupported configuration"), + QObject::tr("CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid."), + QMessageBox::NoButton); + warningbox.addButton(QObject::tr("Continue"), QMessageBox::AcceptRole); + warningbox.addButton(QObject::tr("Exit"), QMessageBox::RejectRole); + warningbox.exec(); + if (warningbox.result() == QDialog::Accepted) + return 0; + } + #ifdef DISCORD discord_load(); #endif @@ -256,7 +290,6 @@ main(int argc, char *argv[]) auto rawInputFilter = WindowsRawInputFilter::Register(main_window); if (rawInputFilter) { app.installNativeEventFilter(rawInputFilter.get()); - QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter *) rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); main_window->setSendKeyboardInput(false); } #endif @@ -275,10 +308,9 @@ main(int argc, char *argv[]) main_window->installEventFilter(&socket); socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); } + // pc_reset_hard_init(); - /* Set the PAUSE mode depending on the renderer. */ - // plat_pause(0); QTimer onesec; QObject::connect(&onesec, &QTimer::timeout, &app, [] { pc_onesec(); @@ -307,6 +339,14 @@ main(int argc, char *argv[]) QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); main_thread = new std::thread(main_thread_fn); + + /* Set the PAUSE mode depending on the renderer. */ +#ifdef USE_VNC + if (vnc_enabled && vid_api != 5) + plat_pause(1); + else +#endif + plat_pause(0); }); auto ret = app.exec(); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e7ced9c674..f24ab07887 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -70,6 +70,7 @@ extern int qt_nvr_save(void); #include #include #include +#include #include #include #include @@ -116,6 +117,11 @@ extern int qt_nvr_save(void); # undef KeyRelease #endif +#if defined Q_OS_UNIX && !defined Q_OS_HAIKU && !defined Q_OS_MACOS +#include +#include "x11_util.h" +#endif + #ifdef Q_OS_MACOS # include "cocoa_keyboard.hpp" // The namespace is required to avoid clashing typedefs; we only use this @@ -151,8 +157,6 @@ keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) static BMessageFilter *filter; #endif -std::atomic blitDummied { false }; - extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); @@ -190,15 +194,6 @@ MainWindow::MainWindow(QWidget *parent) auto toolbar_label = new QLabel(); ui->toolBar->addWidget(toolbar_label); -#ifdef RELEASE_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); -#elif defined ALPHA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); -#elif defined BETA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); -#else - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); -#endif this->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, vid_resize != 1); this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); @@ -210,7 +205,11 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::hardResetCompleted, this, [this]() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); QApplication::setOverrideCursor(Qt::ArrowCursor); - ui->menuTablet_tool->menuAction()->setVisible(mouse_mode >= 1); +#ifdef USE_WACOM + ui->menuTablet_tool->menuAction()->setVisible(mouse_input_mode >= 1); +#else + ui->menuTablet_tool->menuAction()->setVisible(false); +#endif }); connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); @@ -252,8 +251,6 @@ MainWindow::MainWindow(QWidget *parent) emit updateMenuResizeOptions(); - connect(this, &MainWindow::pollMouse, ui->stackedWidget, &RendererStack::mousePoll, Qt::DirectConnection); - connect(this, &MainWindow::setMouseCapture, this, [this](bool state) { mouse_capture = state ? 1 : 0; qt_mouse_capture(mouse_capture); @@ -269,8 +266,20 @@ MainWindow::MainWindow(QWidget *parent) }); connect(qApp, &QGuiApplication::applicationStateChanged, [this](Qt::ApplicationState state) { - if (mouse_capture && state != Qt::ApplicationState::ApplicationActive) - emit setMouseCapture(false); + if (state == Qt::ApplicationState::ApplicationActive) { + if (auto_paused) { + plat_pause(0); + auto_paused = 0; + } + } else { + if (mouse_capture) + emit setMouseCapture(false); + + if (do_auto_pause && !dopause) { + auto_paused = 1; + plat_pause(1); + } + } }); connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { @@ -294,7 +303,9 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) { if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { +#ifdef QT_RESIZE_DEBUG qDebug() << "Resize"; +#endif w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); @@ -332,6 +343,8 @@ MainWindow::MainWindow(QWidget *parent) #ifndef DISCORD ui->actionEnable_Discord_integration->setVisible(false); +#else + ui->actionEnable_Discord_integration->setEnabled(discord_loaded); #endif #if defined Q_OS_WINDOWS || defined Q_OS_MACOS @@ -353,14 +366,9 @@ MainWindow::MainWindow(QWidget *parent) ui->actionVulkan->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false); } -#if !defined Q_OS_WINDOWS - ui->actionDirect3D_9->setVisible(false); - if (vid_api == 5) - vid_api = 0; -#endif #ifndef USE_VNC - if (vid_api == 6) + if (vid_api == 5) vid_api = 0; ui->actionVNC->setVisible(false); #endif @@ -394,14 +402,13 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); - actGroup->addAction(ui->actionDirect3D_9); actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC - if (vnc_enabled && vid_api != 6) { + if (vnc_enabled && vid_api != 5) { startblit(); vnc_enabled = 0; vnc_close(); @@ -426,11 +433,8 @@ MainWindow::MainWindow(QWidget *parent) case 4: newVidApi = RendererStack::Renderer::Vulkan; break; - case 5: - newVidApi = RendererStack::Renderer::Direct3D9; - break; #ifdef USE_VNC - case 6: + case 5: { newVidApi = RendererStack::Renderer::Software; startblit(); @@ -527,12 +531,16 @@ MainWindow::MainWindow(QWidget *parent) case FULLSCR_SCALE_INT: ui->actionFullScreen_int->setChecked(true); break; + case FULLSCR_SCALE_INT43: + ui->actionFullScreen_int43->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionFullScreen_stretch); actGroup->addAction(ui->actionFullScreen_43); actGroup->addAction(ui->actionFullScreen_keepRatio); actGroup->addAction(ui->actionFullScreen_int); + actGroup->addAction(ui->actionFullScreen_int43); switch (video_grayscale) { case 0: ui->actionRGB_Color->setChecked(true); @@ -580,6 +588,9 @@ MainWindow::MainWindow(QWidget *parent) if (vid_cga_contrast > 0) { ui->actionChange_contrast_for_monochrome_display->setChecked(true); } + if (do_auto_pause > 0) { + ui->actionAuto_pause->setChecked(true); + } #ifdef Q_OS_MACOS ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); @@ -588,6 +599,15 @@ MainWindow::MainWindow(QWidget *parent) if (!vnc_enabled) video_setblit(qt_blit); + if (start_in_fullscreen) { + connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () { + if (start_in_fullscreen) { + QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); + start_in_fullscreen = 0; + } + }); + } + #ifdef MTR_ENABLED { ui->actionBegin_trace->setVisible(true); @@ -628,6 +648,8 @@ MainWindow::MainWindow(QWidget *parent) #endif setContextMenuPolicy(Qt::PreventContextMenu); + /* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */ + connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [](){}); connect(this, &MainWindow::initRendererMonitor, this, &MainWindow::initRendererMonitorSlot); connect(this, &MainWindow::initRendererMonitorForNonQtThread, this, &MainWindow::initRendererMonitorSlot, Qt::BlockingQueuedConnection); @@ -674,6 +696,20 @@ MainWindow::MainWindow(QWidget *parent) # endif {} #endif + +#if defined Q_OS_UNIX && !defined Q_OS_MACOS && !defined Q_OS_HAIKU + if (QApplication::platformName().contains("xcb")) { + QTimer::singleShot(0, this, [this] { + auto whandle = windowHandle(); + if (! whandle) { + qWarning() << "No window handle"; + } else { + QPlatformWindow *window = whandle->handle(); + set_wm_class(window->winId(), vm_name); + } + }); + } +#endif } void @@ -760,8 +796,15 @@ MainWindow::initRendererMonitorSlot(int monitor_index) } secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); secondaryRenderer->setMouseTracking(true); + + if (monitor_settings[monitor_index].mon_window_maximized) { + if (renderers[monitor_index]) + renderers[monitor_index]->onResize(renderers[monitor_index]->width(), + renderers[monitor_index]->height()); + + device_force_redraw(); + } } - connect(this, &MainWindow::pollMouse, secondaryRenderer.get(), &RendererStack::mousePoll, Qt::DirectConnection); } } @@ -813,10 +856,6 @@ MainWindow::showEvent(QShowEvent *event) QApplication::processEvents(); this->adjustSize(); } - if (start_in_fullscreen) { - start_in_fullscreen = 0; - QTimer::singleShot(0, ui->actionFullscreen, &QAction::trigger); - } } void @@ -887,20 +926,17 @@ MainWindow::on_actionSettings_triggered() Settings settings(this); settings.setModal(true); settings.setWindowModality(Qt::WindowModal); + settings.setWindowFlag(Qt::CustomizeWindowHint, true); + settings.setWindowFlag(Qt::WindowTitleHint, true); + settings.setWindowFlag(Qt::WindowSystemMenuHint, false); settings.exec(); switch (settings.result()) { case QDialog::Accepted: - /* pc_reset_hard_close(); settings.save(); config_changed = 2; pc_reset_hard_init(); - */ - settings.save(); - config_changed = 2; - pc_reset_hard(); - break; case QDialog::Rejected: break; @@ -942,11 +978,13 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) } break; + case 0x80 ... 0xff: /* regular break codes */ case 0x10b: /* Microsoft scroll up normal */ - case 0x18b: /* Microsoft scroll down normal */ - /* This abuses make/break codes. Send them manually, only on press. */ + case 0x180 ... 0x1ff: /* E0 break codes (including Microsoft scroll down normal) */ + /* This key uses a break code as make. Send it manually, only on press. */ if (down) { - keyboard_send(0xe0); + if (keycode & 0x100) + keyboard_send(0xe0); keyboard_send(keycode & 0xff); } return; @@ -1090,6 +1128,11 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) if (mac_iso_swap) nvk = (nvk == 0x0a) ? 0x32 : 0x0a; } + // Special case for command + forward delete to send insert. + if ((event->nativeModifiers() & NSEventModifierFlagCommand) && + ((event->nativeVirtualKey() == nvk_Delete) || event->key() == Qt::Key_Delete)) { + nvk = nvk_Insert; // Qt::Key_Help according to event->key() + } processKeyboardInput(down, nvk); } @@ -1101,8 +1144,6 @@ MainWindow::on_actionFullscreen_triggered() { if (video_fullscreen > 0) { showNormal(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); ui->menubar->show(); if (!hide_status_bar) ui->statusbar->show(); @@ -1138,8 +1179,6 @@ MainWindow::on_actionFullscreen_triggered() ui->toolBar->hide(); ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); - if (vid_api == 5) - QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); } ui->stackedWidget->onResize(width(), height()); } @@ -1242,11 +1281,7 @@ MainWindow::keyPressEvent(QKeyEvent *event) #endif } - if (!fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit()) - fs_off_signal = true; - - if (!fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter()) - fs_on_signal = true; + checkFullscreenHotkey(); if (keyboard_ismsexit()) plat_mouse_capture(0); @@ -1265,7 +1300,7 @@ void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) + if (renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); else video_blit_complete_monitor(monitor_index); @@ -1282,24 +1317,35 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) } } - if (fs_off_signal && (video_fullscreen > 0) && keyboard_isfsexit_down()) { - ui->actionFullscreen->trigger(); - fs_off_signal = false; + if (send_keyboard_input && !event->isAutoRepeat()) { +#ifdef Q_OS_MACOS + processMacKeyboardInput(false, event); +#else + processKeyboardInput(false, event->nativeScanCode()); +#endif } - if (fs_on_signal && (video_fullscreen == 0) && keyboard_isfsenter_down()) { + checkFullscreenHotkey(); +} + +void +MainWindow::checkFullscreenHotkey() +{ + if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { + /* Signal "exit fullscreen mode". */ + fs_off_signal = 1; + } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { ui->actionFullscreen->trigger(); - fs_on_signal = false; + fs_off_signal = 0; } - if (!send_keyboard_input) - return; - -#ifdef Q_OS_MACOS - processMacKeyboardInput(false, event); -#else - processKeyboardInput(false, event->nativeScanCode()); -#endif + if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { + /* Signal "enter fullscreen mode". */ + fs_on_signal = 1; + } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { + ui->actionFullscreen->trigger(); + fs_on_signal = 0; + } } QSize @@ -1325,12 +1371,12 @@ MainWindow::on_actionResizable_window_triggered(bool checked) { if (checked) { vid_resize = 1; - setWindowFlag(Qt::WindowMaximizeButtonHint); + setWindowFlag(Qt::WindowMaximizeButtonHint, true); setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); for (int i = 1; i < MONITORS_NUM; i++) { if (monitors[i].target_buffer) { - renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint); + renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint, true); renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } @@ -1491,10 +1537,11 @@ MainWindow::on_actionLinear_triggered() static void update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) { - ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); - ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); - ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); - ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); + ui->actionFullScreen_stretch->setChecked(selected == ui->actionFullScreen_stretch); + ui->actionFullScreen_43->setChecked(selected == ui->actionFullScreen_43); + ui->actionFullScreen_keepRatio->setChecked(selected == ui->actionFullScreen_keepRatio); + ui->actionFullScreen_int->setChecked(selected == ui->actionFullScreen_int); + ui->actionFullScreen_int43->setChecked(selected == ui->actionFullScreen_int43); { auto widget = ui->stackedWidget->currentWidget(); @@ -1503,7 +1550,8 @@ update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) for (int i = 1; i < MONITORS_NUM; i++) { if (main_window->renderers[i]) - main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + main_window->renderers[i]->onResize(main_window->renderers[i]->width(), + main_window->renderers[i]->height()); } device_force_redraw(); @@ -1538,6 +1586,13 @@ MainWindow::on_actionFullScreen_int_triggered() update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); } +void +MainWindow::on_actionFullScreen_int43_triggered() +{ + video_fullscreen_scale = FULLSCR_SCALE_INT43; + update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int43); +} + static void update_greyscale_checkboxes(Ui::MainWindow *ui, QAction *selected, int value) { @@ -1641,7 +1696,7 @@ MainWindow::on_actionAbout_86Box_triggered() #endif versioninfo.append(QString(" [%1, %2]").arg(QSysInfo::buildCpuArchitecture(), tr(DYNAREC_STR))); msgBox.setText(QString("%3%1%2").arg(EMU_VERSION_FULL, versioninfo, tr("86Box v"))); - msgBox.setInformativeText(tr("An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.")); + msgBox.setInformativeText(tr("An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.")); msgBox.setWindowTitle("About 86Box"); msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); @@ -1688,22 +1743,31 @@ MainWindow::on_actionForce_4_3_display_ratio_triggered() video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43); } +void +MainWindow::on_actionAuto_pause_triggered() +{ + do_auto_pause ^= 1; + ui->actionAuto_pause->setChecked(do_auto_pause > 0 ? true : false); +} + void MainWindow::on_actionRemember_size_and_position_triggered() { window_remember ^= 1; - window_w = ui->stackedWidget->width(); - window_h = ui->stackedWidget->height(); - if (!QApplication::platformName().contains("wayland")) { - window_x = geometry().x(); - window_y = geometry().y(); - } - for (int i = 1; i < MONITORS_NUM; i++) { - if (window_remember && renderers[i]) { - monitor_settings[i].mon_window_w = renderers[i]->geometry().width(); - monitor_settings[i].mon_window_h = renderers[i]->geometry().height(); - monitor_settings[i].mon_window_x = renderers[i]->geometry().x(); - monitor_settings[i].mon_window_y = renderers[i]->geometry().y(); + if (!video_fullscreen) { + window_w = ui->stackedWidget->width(); + window_h = ui->stackedWidget->height(); + if (!QApplication::platformName().contains("wayland")) { + window_x = geometry().x(); + window_y = geometry().y(); + } + for (int i = 1; i < MONITORS_NUM; i++) { + if (window_remember && renderers[i]) { + monitor_settings[i].mon_window_w = renderers[i]->geometry().width(); + monitor_settings[i].mon_window_h = renderers[i]->geometry().height(); + monitor_settings[i].mon_window_x = renderers[i]->geometry().x(); + monitor_settings[i].mon_window_y = renderers[i]->geometry().y(); + } } } ui->actionRemember_size_and_position->setChecked(window_remember); @@ -1896,8 +1960,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() { show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); - blitDummied = true; - if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { auto &secondaryRenderer = renderers[monitor_index]; @@ -1927,8 +1989,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered() } } } - - blitDummied = false; } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 79b5d9dda5..950d145c16 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -12,8 +12,6 @@ class MediaMenu; class RendererStack; -extern std::atomic blitDummied; - namespace Ui { class MainWindow; } @@ -32,13 +30,13 @@ class MainWindow : public QMainWindow { void blitToWidget(int x, int y, int w, int h, int monitor_index); QSize getRenderWidgetSize(); void setSendKeyboardInput(bool enabled); + void checkFullscreenHotkey(); std::array, 8> renderers; signals: void paint(const QImage &image); void resizeContents(int w, int h); void resizeContentsMonitor(int w, int h, int monitor_index); - void pollMouse(); void statusBarMessage(const QString &msg); void updateStatusBarPanes(); void updateStatusBarActivity(int tag, bool active); @@ -69,6 +67,7 @@ private slots: void on_actionFullscreen_triggered(); void on_actionSettings_triggered(); void on_actionExit_triggered(); + void on_actionAuto_pause_triggered(); void on_actionPause_triggered(); void on_actionCtrl_Alt_Del_triggered(); void on_actionCtrl_Alt_Esc_triggered(); @@ -90,6 +89,7 @@ private slots: void on_actionLinear_triggered(); void on_actionNearest_triggered(); void on_actionFullScreen_int_triggered(); + void on_actionFullScreen_int43_triggered(); void on_actionFullScreen_keepRatio_triggered(); void on_actionFullScreen_43_triggered(); void on_actionFullScreen_stretch_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index b61a974c62..08d8bbf63d 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -68,17 +68,19 @@ + + + + - - @@ -115,7 +117,6 @@ - @@ -148,6 +149,7 @@ + @@ -255,6 +257,7 @@ + @@ -262,6 +265,14 @@ + + + true + + + &Auto-pause on focus loss + + true @@ -585,6 +596,14 @@ &Integer scale + + + true + + + 4:&3 Integer scale + + true @@ -752,10 +771,10 @@ :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico - ACPI Shutdown + ACPI shutdown - ACPI Shutdown + ACPI shutdown true @@ -810,17 +829,6 @@ MCA devices... - - - true - - - Direct3D 9 - - - 5 - - true @@ -837,7 +845,7 @@ VNC - 6 + 5 diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 26169b0d09..541e31190f 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -456,6 +456,13 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); +#ifdef _WIN32 + if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) + fn.data()[strlen(fn.data()) - 1] = '\\'; +#else + if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) + fn.data()[strlen(fn.data()) - 1] = '/'; +#endif cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ if (cdrom[i].insert) diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 10c505e3b1..e24ad9aa1d 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -259,7 +259,7 @@ NewFloppyDialog::onCreate() bool NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode) { - FILE *f; + FILE *fp; uint32_t magic = 0x46423638; uint16_t version = 0x020C; @@ -326,13 +326,13 @@ NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size memset(tarray, 0, 2048); memset(empty, 0, array_size); - f = plat_fopen(filename.toUtf8().data(), "wb"); - if (!f) + fp = plat_fopen(filename.toUtf8().data(), "wb"); + if (!fp) return false; - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&dflags, 2, 1, f); + fwrite(&magic, 4, 1, fp); + fwrite(&version, 2, 1, fp); + fwrite(&dflags, 2, 1, fp); track_size = array_size + 6; @@ -344,17 +344,17 @@ NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) tarray[i] = track_base + (i * track_size); - fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); + fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, fp); for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, f); - fwrite(&index_hole_pos, 4, 1, f); - fwrite(empty, 1, array_size, f); + fwrite(&tflags, 2, 1, fp); + fwrite(&index_hole_pos, 4, 1, fp); + fwrite(empty, 1, array_size, fp); } free(empty); - fclose(f); + fclose(fp); return true; } diff --git a/src/qt/qt_newfloppydialog.ui b/src/qt/qt_newfloppydialog.ui index 7fb044fcc2..c0437d8102 100644 --- a/src/qt/qt_newfloppydialog.ui +++ b/src/qt/qt_newfloppydialog.ui @@ -52,6 +52,9 @@ + + 30 + 0 @@ -69,6 +72,9 @@ + + 30 + 0 diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 749be8b43b..356334baca 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -36,15 +36,21 @@ #include #include #include +#include +#include #include #include +#include + #include "qt_rendererstack.hpp" #include "qt_mainwindow.hpp" #include "qt_progsettings.hpp" +#include "qt_util.hpp" #ifdef Q_OS_UNIX +# include # include #endif @@ -299,6 +305,12 @@ path_slash(char *path) path_normalize(path); } +const char * +path_get_slash(char *path) +{ + return QString(path).endsWith("/") ? "" : "/"; +} + void path_append_filename(char *dest, const char *s1, const char *s2) { @@ -316,7 +328,7 @@ plat_tempfile(char *bufp, char *prefix, char *suffix) name.append(QString("%1-").arg(prefix)); } - name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); + name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzz")); if (suffix) name.append(suffix); strcpy(bufp, name.toUtf8().data()); @@ -360,7 +372,7 @@ plat_pause(int p) wchar_t title[1024]; wchar_t paused_msg[512]; - if (p == dopause) { + if ((!!p) == dopause) { #ifdef Q_OS_WINDOWS if (source_hwnd) PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); @@ -371,7 +383,7 @@ plat_pause(int p) if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) nvr_time_sync(); - dopause = p; + do_pause(p); if (p) { if (mouse_capture) plat_mouse_capture(0); @@ -397,9 +409,6 @@ plat_pause(int p) #endif } -// because we can't include nvr.h because it's got fields named new -extern int nvr_save(void); - void plat_power_off(void) { @@ -424,14 +433,16 @@ set_language(uint32_t id) extern "C++" { QMap> ProgSettings::lcid_langcode = { - {0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, + { 0x0403, { "ca-ES", "Catalan (Spain)" } }, + { 0x0804, { "zh-CN", "Chinese (Simplified)" } }, + { 0x0404, { "zh-TW", "Chinese (Traditional)" } }, + { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, + { 0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, { 0x0407, { "de-DE", "German (Germany)" } }, - { 0x0409, { "en-US", "English (United States)" } }, { 0x0809, { "en-GB", "English (United Kingdom)" }}, - { 0x0C0A, { "es-ES", "Spanish (Spain)" } }, + { 0x0409, { "en-US", "English (United States)" } }, { 0x040B, { "fi-FI", "Finnish (Finland)" } }, { 0x040C, { "fr-FR", "French (France)" } }, - { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, { 0x040E, { "hu-HU", "Hungarian (Hungary)" } }, { 0x0410, { "it-IT", "Italian (Italy)" } }, { 0x0411, { "ja-JP", "Japanese (Japan)" } }, @@ -440,11 +451,11 @@ QMap> ProgSettings::lcid_langcode = { { 0x0416, { "pt-BR", "Portuguese (Brazil)" } }, { 0x0816, { "pt-PT", "Portuguese (Portugal)" } }, { 0x0419, { "ru-RU", "Russian (Russia)" } }, + { 0x041B, { "sk-SK", "Slovak (Slovakia)" } }, { 0x0424, { "sl-SI", "Slovenian (Slovenia)" } }, + { 0x0C0A, { "es-ES", "Spanish (Spain, Modern Sort)" } }, { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, - { 0x0804, { "zh-CN", "Chinese (China)" } }, - { 0x0404, { "zh-TW", "Chinese (Taiwan)" } }, { 0xFFFF, { "system", "(System Default)" } }, }; } @@ -570,14 +581,10 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" # define LIB_NAME_GS "gsdll32.dll" -# define LIB_NAME_FREETYPE "freetype.dll" # define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else -# define LIB_NAME_FLUIDSYNTH "libfluidsynth" # define LIB_NAME_GS "libgs" -# define LIB_NAME_FREETYPE "libfreetype" # define MOUSE_CAPTURE_KEYSEQ "CTRL-END" #endif @@ -590,14 +597,11 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); translatedstrings[IDS_2078] = QCoreApplication::translate("", "Press F8+F12 to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); translatedstrings[IDS_2079] = QCoreApplication::translate("", "Press F8+F12 or middle button to release mouse").replace("F8+F12", MOUSE_CAPTURE_KEYSEQ).replace("CTRL-END", QLocale::system().name() == "de_DE" ? "Strg+Ende" : "CTRL-END").toStdWString(); - translatedstrings[IDS_2080] = QCoreApplication::translate("", "Failed to initialize FluidSynth").toStdWString(); translatedstrings[IDS_2131] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[IDS_4099] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); translatedstrings[IDS_2094] = QCoreApplication::translate("", "Failed to set up PCap").toStdWString(); translatedstrings[IDS_2095] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); translatedstrings[IDS_2096] = QCoreApplication::translate("", "Invalid PCap device").toStdWString(); - translatedstrings[IDS_2111] = QCoreApplication::translate("", "Unable to initialize FreeType").toStdWString(); - translatedstrings[IDS_2112] = QCoreApplication::translate("", "Unable to initialize SDL, libsdl2 is required").toStdWString(); translatedstrings[IDS_2130] = QCoreApplication::translate("", "Make sure libpcap is installed and that you are on a libpcap-compatible network connection.").toStdWString(); translatedstrings[IDS_2115] = QCoreApplication::translate("", "Unable to initialize Ghostscript").toStdWString(); translatedstrings[IDS_2063] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); @@ -610,24 +614,12 @@ ProgSettings::reloadStrings() translatedstrings[IDS_2167] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); translatedstrings[IDS_2168] = QCoreApplication::translate("", "The network configuration will be switched to the null driver").toStdWString(); - auto flsynthstr = QCoreApplication::translate("", " is required for FluidSynth MIDI output."); - if (flsynthstr.contains("libfluidsynth")) { - flsynthstr.replace("libfluidsynth", LIB_NAME_FLUIDSYNTH); - } else - flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); - translatedstrings[IDS_2134] = flsynthstr.toStdWString(); - auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); - if (gssynthstr.contains("libgs")) { - gssynthstr.replace("libgs", LIB_NAME_GS); + auto gsstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); + if (gsstr.contains("libgs")) { + gsstr.replace("libgs", LIB_NAME_GS); } else - gssynthstr.prepend(LIB_NAME_GS); - translatedstrings[IDS_2133] = gssynthstr.toStdWString(); - auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); - if (ftsynthstr.contains("libfreetype")) { - ftsynthstr.replace("libfreetype", LIB_NAME_FREETYPE); - } else - ftsynthstr.prepend(LIB_NAME_FREETYPE); - translatedstrings[IDS_2132] = ftsynthstr.toStdWString(); + gsstr.prepend(LIB_NAME_GS); + translatedstrings[IDS_2133] = gsstr.toStdWString(); } wchar_t * @@ -657,7 +649,7 @@ plat_get_global_config_dir(char* strptr) } void -plat_init_rom_paths() +plat_init_rom_paths(void) { auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); @@ -678,3 +670,120 @@ plat_init_rom_paths() #endif } } + +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + auto cpu_string = QString("Unknown"); + /* Write the default string now in case we have to exit early from an error */ + qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); + +#if defined(Q_OS_MACOS) + auto *process = new QProcess(nullptr); + QStringList arguments; + QString program = "/usr/sbin/sysctl"; + arguments << "machdep.cpu.brand_string"; + process->start(program, arguments); + if (!process->waitForStarted()) { + return; + } + if (!process->waitForFinished()) { + return; + } + QByteArray result = process->readAll(); + auto command_result = QString(result).split(": ").last(); + if(!command_result.isEmpty()) { + cpu_string = command_result; + } +#elif defined(Q_OS_WINDOWS) + const LPCSTR keyName = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; + const LPCSTR valueName = "ProcessorNameString"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + bufSize = 32768; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + cpu_string = reinterpret_cast(buf); + } + RegCloseKey(hKey); + } +#elif defined(Q_OS_LINUX) + auto cpuinfo = QString("/proc/cpuinfo"); + auto cpuinfo_fi = QFileInfo(cpuinfo); + if(!cpuinfo_fi.isReadable()) { + return; + } + QFile file(cpuinfo); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream textStream(&file); + while(true) { + QString line = textStream.readLine(); + if (line.isNull()) { + break; + } + if(QRegularExpression("model name.*:").match(line).hasMatch()) { + auto list = line.split(": "); + if(!list.last().isEmpty()) { + cpu_string = list.last(); + break; + } + } + + } + } +#endif + + qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); + +} + +double +plat_get_dpi(void) +{ + return util::screenOfWidget(main_window)->devicePixelRatio(); +} + +void +plat_set_thread_name(void *thread, const char *name) +{ +#ifdef Q_OS_WINDOWS + /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ + static void *kernel32_handle = NULL; + static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; + static dllimp_t kernel32_imports[] = { + // clang-format off + { "SetThreadDescription", &pSetThreadDescription }, + { NULL, NULL } + // clang-format on + }; + + if (!kernel32_handle) { + kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); + if (!kernel32_handle) { + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ + pSetThreadDescription = NULL; + } + } + + if (pSetThreadDescription) { + size_t len = strlen(name) + 1; + wchar_t wname[len + 1]; + mbstowcs(wname, name, len); + pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); + } +#else +# ifdef Q_OS_DARWIN + if (thread) /* Apple pthread can only set self's name */ + return; + char truncated[64]; +# else + char truncated[16]; +# endif + strncpy(truncated, name, sizeof(truncated) - 1); +# ifdef Q_OS_DARWIN + pthread_setname_np(truncated); +# else + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); +# endif +#endif +} diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index fa0818652d..16fb439be9 100644 --- a/src/qt/qt_progsettings.ui +++ b/src/qt/qt_progsettings.ui @@ -34,6 +34,9 @@ false + + 30 + (Default) @@ -109,6 +112,9 @@ + + 30 + (System Default) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index c2b38cd521..178134c9d6 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -27,6 +27,7 @@ extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> } @@ -51,62 +52,83 @@ integer_scale(double *d, double *g) void RendererCommon::onResize(int width, int height) { - if ((video_fullscreen == 0) && (video_fullscreen_scale_maximized ? ((parentWidget->isMaximized() == false) && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1)) { + /* This is needed so that the if below does not take like, 5 lines. */ + bool is_fs = (video_fullscreen == 0); + bool parent_max = (parentWidget->isMaximized() == false); + bool main_is_ancestor = main_window->isAncestorOf(parentWidget); + bool main_max = main_window->isMaximized(); + bool main_is_max = (main_is_ancestor && main_max == false); + + if (is_fs && (video_fullscreen_scale_maximized ? (parent_max && main_is_max) : 1)) destination.setRect(0, 0, width, height); - return; - } - double dx; - double dy; - double dw; - double dh; - double gsr; - - double hw = width; - double hh = height; - double gw = source.width(); - double gh = source.height(); - double hsr = hw / hh; - - switch (video_fullscreen_scale) { - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - integer_scale(&dw, &gw); - integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) { - gsr = 4.0 / 3.0; - } else { + else { + double dx; + double dy; + double dw; + double dh; + double gsr; + + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); + double hsr = hw / hh; + double r43 = 4.0 / 3.0; + + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_INT: + case FULLSCR_SCALE_INT43: gsr = gw / gh; - } - - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_FULL: - default: - destination.setRect(0, 0, hw, hh); - break; + + if (video_fullscreen_scale == FULLSCR_SCALE_INT43) { + gh = gw / r43; +// gw = gw; + + gsr = r43; + } + + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect((int) dx, (int) dy, (int) dw, (int) dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) + gsr = r43; + else + gsr = gw / gh; + + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect((int) dx, (int) dy, (int) dw, (int) dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, (int) hw, (int) hh); + break; + } } + + monitors[r_monitor_index].mon_res_x = (double) destination.width(); + monitors[r_monitor_index].mon_res_y = (double) destination.height(); } bool @@ -128,5 +150,4 @@ RendererCommon::eventDelegate(QEvent *event, bool &result) result = QApplication::sendEvent(parentWidget, event); return true; } - return false; } diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 34b28fb307..af72474c79 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -35,11 +35,11 @@ class RendererCommon { /* Reloads options of renderer */ virtual void reloadOptions() { } - virtual bool hasBlitFunc() { return false; } - virtual void blit(int x, int y, int w, int h) { } + int r_monitor_index = 0; protected: - bool eventDelegate(QEvent *event, bool &result); + bool eventDelegate(QEvent *event, bool &result); + void drawStatusBarIcons(QPainter* painter); QRect source { 0, 0, 0, 0 }; QRect destination; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ee87dccb8b..0f86e8ee64 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -25,9 +25,6 @@ #include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" -#ifdef Q_OS_WIN -# include "qt_d3d9renderer.hpp" -#endif #include "qt_mainwindow.hpp" #include "qt_util.hpp" @@ -49,37 +46,36 @@ extern "C" { #include <86box/86box.h> #include <86box/config.h> -#include <86box/mouse.h> #include <86box/plat.h> #include <86box/video.h> - -double mouse_sensitivity = 1.0; -double mouse_x_error = 0.0, mouse_y_error = 0.0; +#include <86box/mouse.h> } struct mouseinputdata { - atomic_int deltax; - atomic_int deltay; - atomic_int deltaz; - atomic_int mousebuttons; atomic_bool mouse_tablet_in_proximity; - std::atomic x_abs; - std::atomic y_abs; + + char *mouse_type; }; static mouseinputdata mousedata; -extern "C" void macos_poll_mouse(); extern MainWindow *main_window; RendererStack::RendererStack(QWidget *parent, int monitor_index) : QStackedWidget(parent) , ui(new Ui::RendererStack) { +#ifdef Q_OS_WINDOWS + int raw = 1; +#else + int raw = 0; +#endif + ui->setupUi(this); m_monitor_index = monitor_index; #if defined __unix__ && !defined __HAIKU__ - char *mouse_type = getenv("EMU86BOX_MOUSE"), auto_mouse_type[16]; - if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) { + char auto_mouse_type[16]; + mousedata.mouse_type = getenv("EMU86BOX_MOUSE"); + if (!mousedata.mouse_type || (mousedata.mouse_type[0] == '\0') || !stricmp(mousedata.mouse_type, "auto")) { if (QApplication::platformName().contains("wayland")) strcpy(auto_mouse_type, "wayland"); else if (QApplication::platformName() == "eglfs") @@ -88,35 +84,32 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) strcpy(auto_mouse_type, "xinput2"); else auto_mouse_type[0] = '\0'; - mouse_type = auto_mouse_type; + mousedata.mouse_type = auto_mouse_type; } # ifdef WAYLAND - if (!stricmp(mouse_type, "wayland")) { + if (!stricmp(mousedata.mouse_type, "wayland")) { wl_init(); - this->mouse_poll_func = wl_mouse_poll; this->mouse_capture_func = wl_mouse_capture; this->mouse_uncapture_func = wl_mouse_uncapture; } # endif # ifdef EVDEV_INPUT - if (!stricmp(mouse_type, "evdev")) { + if (!stricmp(mousedata.mouse_type, "evdev")) { evdev_init(); - this->mouse_poll_func = evdev_mouse_poll; + raw = 0; } # endif - if (!stricmp(mouse_type, "xinput2")) { + if (!stricmp(mousedata.mouse_type, "xinput2")) { extern void xinput2_init(); - extern void xinput2_poll(); extern void xinput2_exit(); xinput2_init(); - this->mouse_poll_func = xinput2_poll; this->mouse_exit_func = xinput2_exit; } #endif -#ifdef __APPLE__ - this->mouse_poll_func = macos_poll_mouse; -#endif + + if (monitor_index == 0) + mouse_set_raw(raw); } RendererStack::~RendererStack() @@ -144,61 +137,14 @@ qt_mouse_capture(int on) return; } -void -RendererStack::mousePoll() -{ - if (m_monitor_index >= 1) { - if (mouse_mode >= 1) { - mouse_x_abs = mousedata.x_abs; - mouse_y_abs = mousedata.y_abs; - if (!mouse_tablet_in_proximity) { - mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; - } - if (mousedata.mouse_tablet_in_proximity) { - mouse_buttons = mousedata.mousebuttons; - } - } - return; - } - -#ifdef Q_OS_WINDOWS - if (mouse_mode == 0) { - mouse_x_abs = mousedata.x_abs; - mouse_y_abs = mousedata.y_abs; - return; - } -#endif - -#ifndef __APPLE__ - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; - mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; - - if (this->mouse_poll_func) -#endif - this->mouse_poll_func(); - - mouse_x_abs = mousedata.x_abs; - mouse_y_abs = mousedata.y_abs; - mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; - - double scaled_x = mouse_x * mouse_sensitivity + mouse_x_error; - double scaled_y = mouse_y * mouse_sensitivity + mouse_y_error; - - mouse_x = static_cast(scaled_x); - mouse_y = static_cast(scaled_y); - - mouse_x_error = scaled_x - mouse_x; - mouse_y_error = scaled_y - mouse_y; -} - int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_mode == 0)) { + if (!dopause && this->geometry().contains(m_monitor_index >= 1 ? event->globalPos() : event->pos()) && + (event->button() == Qt::LeftButton) && !mouse_capture && + (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && + (mouse_input_mode == 0)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); if (!ignoreNextMouseEvent) @@ -212,8 +158,19 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event) isMouseDown &= ~1; return; } - if (mouse_capture || mouse_mode >= 1) { - mousedata.mousebuttons &= ~event->button(); + if (mouse_capture || (mouse_input_mode >= 1)) { +#ifdef Q_OS_WINDOWS + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_input_mode >= 1))) +#else +#ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + (m_monitor_index < 1)) +#else + if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) +#endif +#endif + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~event->button()); } isMouseDown &= ~1; } @@ -222,8 +179,19 @@ void RendererStack::mousePressEvent(QMouseEvent *event) { isMouseDown |= 1; - if (mouse_capture || mouse_mode >= 1) { - mousedata.mousebuttons |= event->button(); + if (mouse_capture || (mouse_input_mode >= 1)) { +#ifdef Q_OS_WINDOWS + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_input_mode >= 1))) +#else +#ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + (m_monitor_index < 1)) +#else + if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) +#endif +#endif + mouse_set_buttons_ex(mouse_get_buttons_ex() | event->button()); } event->accept(); } @@ -231,9 +199,7 @@ RendererStack::mousePressEvent(QMouseEvent *event) void RendererStack::wheelEvent(QWheelEvent *event) { - if (mouse_capture) { - mousedata.deltaz += event->pixelDelta().y(); - } + mouse_set_z(event->pixelDelta().y()); } void @@ -258,8 +224,12 @@ RendererStack::mouseMoveEvent(QMouseEvent *event) event->accept(); return; } - mousedata.deltax += event->pos().x() - oldPos.x(); - mousedata.deltay += event->pos().y() - oldPos.y(); + +#if defined __unix__ && !defined __HAIKU__ + if (!stricmp(mousedata.mouse_type, "wayland")) + mouse_scale(event->pos().x() - oldPos.x(), event->pos().y() - oldPos.y()); +#endif + if (QApplication::platformName() == "eglfs") { leaveEvent((QEvent *) event); ignoreNextMouseEvent--; @@ -270,7 +240,6 @@ RendererStack::mouseMoveEvent(QMouseEvent *event) #endif } - void #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) RendererStack::enterEvent(QEnterEvent *event) @@ -280,7 +249,7 @@ RendererStack::enterEvent(QEvent *event) { mousedata.mouse_tablet_in_proximity = 1; - if (mouse_mode == 1) + if (mouse_input_mode == 1) QApplication::setOverrideCursor(Qt::BlankCursor); } @@ -289,7 +258,7 @@ RendererStack::leaveEvent(QEvent *event) { mousedata.mouse_tablet_in_proximity = 0; - if (mouse_mode == 1 && QApplication::overrideCursor()) + if (mouse_input_mode == 1 && QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); if (QApplication::platformName().contains("wayland")) { event->accept(); @@ -307,40 +276,14 @@ RendererStack::switchRenderer(Renderer renderer) { startblit(); if (current) { - if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9) - || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { - rendererWindow->finalize(); - if (rendererWindow->hasBlitFunc()) { - while (directBlitting) { } - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon); - } - - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { - createRenderer(renderer); - disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); - blitDummied = false; - QTimer::singleShot(1000, this, []() { blitDummied = false; }); - }); - - rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); - } else { - rendererWindow->finalize(); - removeWidget(current.get()); - disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); + rendererWindow->finalize(); + removeWidget(current.get()); + disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr); - /* Create new renderer only after previous is destroyed! */ - connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); + /* Create new renderer only after previous is destroyed! */ + connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); }); - current.release()->deleteLater(); - } + current.release()->deleteLater(); } else { createRenderer(renderer); } @@ -349,7 +292,6 @@ RendererStack::switchRenderer(Renderer renderer) void RendererStack::createRenderer(Renderer renderer) { - current_vid_api = renderer; switch (renderer) { default: case Renderer::Software: @@ -402,27 +344,6 @@ RendererStack::createRenderer(Renderer renderer) current.reset(this->createWindowContainer(hw, this)); break; } -#ifdef Q_OS_WIN - case Renderer::Direct3D9: - { - this->createWinId(); - auto hw = new D3D9Renderer(this, m_monitor_index); - rendererWindow = hw; - connect(hw, &D3D9Renderer::error, this, [this](QString str) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - connect(hw, &D3D9Renderer::initialized, this, [this]() { - endblit(); - emit rendererChanged(); - }); - current.reset(hw); - break; - } -#endif #if QT_CONFIG(vulkan) case Renderer::Vulkan: { @@ -472,44 +393,18 @@ RendererStack::createRenderer(Renderer renderer) currentBuf = 0; - if (rendererWindow->hasBlitFunc()) { - connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection); - } else { - connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection); - } - - if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) { + if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) { imagebufs = rendererWindow->getBuffers(); endblit(); emit rendererChanged(); } } -void -RendererStack::blitDummy(int x, int y, int w, int h) -{ - video_blit_complete_monitor(m_monitor_index); - blitDummied = true; -} - -void -RendererStack::blitRenderer(int x, int y, int w, int h) -{ - if (blitDummied) { - blitDummied = false; - video_blit_complete_monitor(m_monitor_index); - return; - } - directBlitting = true; - rendererWindow->blit(x, y, w, h); - directBlitting = false; -} - // called from blitter thread void -RendererStack::blitCommon(int x, int y, int w, int h) +RendererStack::blit(int x, int y, int w, int h) { - if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } @@ -557,10 +452,45 @@ RendererStack::event(QEvent* event) { if (event->type() == QEvent::MouseMove) { QMouseEvent* mouse_event = (QMouseEvent*)event; - if (mouse_mode >= 1) { - mousedata.x_abs = (mouse_event->localPos().x()) / (long double)width(); - mousedata.y_abs = (mouse_event->localPos().y()) / (long double)height(); + + if (m_monitor_index >= 1) { + if (mouse_input_mode >= 1) { + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); + if (!mouse_tablet_in_proximity) + mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; + } + return QStackedWidget::event(event); + } + +#ifdef Q_OS_WINDOWS + if (mouse_input_mode == 0) { + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); + return QStackedWidget::event(event); } +#endif + + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); + mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; } + return QStackedWidget::event(event); } + +void +RendererStack::setFocusRenderer() +{ + if (current) + current->setFocus(); +} + +void +RendererStack::onResize(int width, int height) +{ + if (rendererWindow) { + rendererWindow->r_monitor_index = m_monitor_index; + rendererWindow->onResize(width, height); + } +} diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index df52a95420..5a08b351cb 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -59,7 +59,6 @@ class RendererStack : public QStackedWidget { OpenGLES, OpenGL3, Vulkan, - Direct3D9, None = -1 }; void switchRenderer(Renderer renderer); @@ -71,32 +70,20 @@ class RendererStack : public QStackedWidget { /* Returns options dialog for current renderer */ QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; } - void setFocusRenderer() - { - if (current) - current->setFocus(); - } - void onResize(int width, int height) - { - if (rendererWindow) - rendererWindow->onResize(width, height); - } + void setFocusRenderer(); + void onResize(int width, int height); - void (*mouse_poll_func)() = nullptr; void (*mouse_capture_func)(QWindow *window) = nullptr; void (*mouse_uncapture_func)() = nullptr; + void (*mouse_exit_func)() = nullptr; signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); - void blit(int x, int y, int w, int h); void rendererChanged(); public slots: - void blitCommon(int x, int y, int w, int h); - void blitRenderer(int x, int y, int w, int h); - void blitDummy(int x, int y, int w, int h); - void mousePoll(); + void blit(int x, int y, int w, int h); private: void createRenderer(Renderer renderer); @@ -116,13 +103,10 @@ public slots: int isMouseDown = 0; int m_monitor_index = 0; - Renderer current_vid_api = Renderer::None; - std::vector> imagebufs; RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting { false }; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 6d04acd255..15af4d7b68 100644 --- a/src/qt/qt_sdl.c +++ b/src/qt/qt_sdl.c @@ -198,12 +198,6 @@ static const uint16_t sdl_to_xt[0x200] = { [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, }; -typedef struct mouseinputdata { - int deltax, deltay, deltaz; - int mousebuttons; -} mouseinputdata; -static mouseinputdata mousedata; - // #define ENABLE_SDL_LOG 3 #ifdef ENABLE_SDL_LOG int sdl_do_log = ENABLE_SDL_LOG; @@ -620,22 +614,20 @@ sdl_main() event.wheel.x *= -1; event.wheel.y *= -1; } - mousedata.deltaz = event.wheel.y; + mouse_set_z(event.wheel.y); } break; } case SDL_MOUSEMOTION: { - if (mouse_capture || video_fullscreen) { - mousedata.deltax += event.motion.xrel; - mousedata.deltay += event.motion.yrel; - } + if (mouse_capture || video_fullscreen) + mouse_scale(event.motion.xrel, event.motion.yrel); break; } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { - if ((event.button.button == SDL_BUTTON_LEFT) + if (!dopause && (event.button.button == SDL_BUTTON_LEFT) && !(mouse_capture || video_fullscreen) && event.button.state == SDL_RELEASED && mouse_inside) { @@ -660,10 +652,10 @@ sdl_main() buttonmask = 4; break; } - if (event.button.state == SDL_PRESSED) { - mousedata.mousebuttons |= buttonmask; - } else - mousedata.mousebuttons &= ~buttonmask; + if (event.button.state == SDL_PRESSED) + mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); + else + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); } break; } @@ -714,13 +706,3 @@ sdl_mouse_capture(int on) { SDL_SetRelativeMouseMode((SDL_bool) on); } - -void -sdl_mouse_poll() -{ - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; - mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; -} diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h index 29804c278a..f9709c8576 100644 --- a/src/qt/qt_sdl.h +++ b/src/qt/qt_sdl.h @@ -68,6 +68,5 @@ enum sdl_main_status { extern enum sdl_main_status sdl_main(); extern void sdl_mouse_capture(int on); -extern void sdl_mouse_poll(); #endif /*WIN_SDL_H*/ diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index f9a6b8e14b..c7cb990868 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -113,7 +113,8 @@ Settings::Settings(QWidget *parent) , ui(new Ui::Settings) { ui->setupUi(this); - ui->listView->setModel(new SettingsModel(this)); + auto *model = new SettingsModel(this); + ui->listView->setModel(model); Harddrives::busTrackClass = new SettingsBusTracking; machine = new SettingsMachine(this); @@ -140,18 +141,27 @@ Settings::Settings(QWidget *parent) ui->stackedWidget->addWidget(otherRemovable); ui->stackedWidget->addWidget(otherPeripherals); - connect(machine, &SettingsMachine::currentMachineChanged, display, &SettingsDisplay::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, input, &SettingsInput::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, sound, &SettingsSound::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, network, &SettingsNetwork::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, &SettingsStorageControllers::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, display, + &SettingsDisplay::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, input, + &SettingsInput::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, sound, + &SettingsSound::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, network, + &SettingsNetwork::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, + &SettingsStorageControllers::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, + &SettingsOtherPeripherals::onCurrentMachineChanged); - connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { - ui->stackedWidget->setCurrentIndex(current.row()); - }); + connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, + [this](const QModelIndex ¤t, const QModelIndex &previous) { + ui->stackedWidget->setCurrentIndex(current.row()); }); - ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent)); + ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) + + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent)); + + ui->listView->setCurrentIndex(model->index(0, 0)); Settings::settings = this; } @@ -184,13 +194,15 @@ void Settings::accept() { if (confirm_save && !settings_only) { - QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this); + QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", + QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), + tr("This will hard reset the emulated machine.")), + QMessageBox::Save | QMessageBox::Cancel, this); 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); - }); + confirm_save = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); if (questionbox.result() == QMessageBox::Cancel) { confirm_save = true; diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index fb878b716f..3ec61dfb77 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -1,62 +1,62 @@ -#ifndef QT_SETTINGS_BUS_TRACKING_HPP -#define QT_SETTINGS_BUS_TRACKING_HPP - -#include - -#define TRACK_CLEAR 0 -#define TRACK_SET 1 - -#define DEV_HDD 0x01 -#define DEV_CDROM 0x02 -#define DEV_ZIP 0x04 -#define DEV_MO 0x08 - -#define BUS_MFM 0 -#define BUS_ESDI 1 -#define BUS_XTA 2 -#define BUS_IDE 3 -#define BUS_SCSI 4 - -#define CHANNEL_NONE 0xff - -namespace Ui { -class SettingsBusTracking; -} - -class SettingsBusTracking { -public: - explicit SettingsBusTracking(); - ~SettingsBusTracking() = default; - - /* These return 0xff is none is free. */ - uint8_t next_free_mfm_channel(); - uint8_t next_free_esdi_channel(); - uint8_t next_free_xta_channel(); - uint8_t next_free_ide_channel(); - uint8_t next_free_scsi_id(); - - int mfm_bus_full(); - int esdi_bus_full(); - int xta_bus_full(); - int ide_bus_full(); - int scsi_bus_full(); - - /* Set: 0 = Clear the device from the tracking, 1 = Set the device on the tracking. - Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = ZIP, 8 = Magneto-Optical. - Bus: 0 = MFM, 1 = ESDI, 2 = XTA, 3 = IDE, 4 = SCSI. */ - void device_track(int set, uint8_t dev_type, int bus, int channel); - -private: - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t mfm_tracking { 0 }; - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t esdi_tracking { 0 }; - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t xta_tracking { 0 }; - /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ - uint64_t ide_tracking[4] { 0, 0, 0, 0 }; - /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; -}; - -#endif // QT_SETTINGS_BUS_TRACKING_HPP +#ifndef QT_SETTINGS_BUS_TRACKING_HPP +#define QT_SETTINGS_BUS_TRACKING_HPP + +#include + +#define TRACK_CLEAR 0 +#define TRACK_SET 1 + +#define DEV_HDD 0x01 +#define DEV_CDROM 0x02 +#define DEV_ZIP 0x04 +#define DEV_MO 0x08 + +#define BUS_MFM 0 +#define BUS_ESDI 1 +#define BUS_XTA 2 +#define BUS_IDE 3 +#define BUS_SCSI 4 + +#define CHANNEL_NONE 0xff + +namespace Ui { +class SettingsBusTracking; +} + +class SettingsBusTracking { +public: + explicit SettingsBusTracking(); + ~SettingsBusTracking() = default; + + /* These return 0xff is none is free. */ + uint8_t next_free_mfm_channel(); + uint8_t next_free_esdi_channel(); + uint8_t next_free_xta_channel(); + uint8_t next_free_ide_channel(); + uint8_t next_free_scsi_id(); + + int mfm_bus_full(); + int esdi_bus_full(); + int xta_bus_full(); + int ide_bus_full(); + int scsi_bus_full(); + + /* Set: 0 = Clear the device from the tracking, 1 = Set the device on the tracking. + Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = ZIP, 8 = Magneto-Optical. + Bus: 0 = MFM, 1 = ESDI, 2 = XTA, 3 = IDE, 4 = SCSI. */ + void device_track(int set, uint8_t dev_type, int bus, int channel); + +private: + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t mfm_tracking { 0 }; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t esdi_tracking { 0 }; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t xta_tracking { 0 }; + /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ + uint64_t ide_tracking[4] { 0, 0, 0, 0 }; + /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ + uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; +}; + +#endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index e64dc74dd8..fcb70f8c51 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -36,7 +36,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent) { ui->setupUi(this); - videoCard[0] = gfxcard[0]; + videoCard[0] = gfxcard[0]; videoCard[1] = gfxcard[1]; onCurrentMachineChanged(machine); } @@ -49,11 +49,11 @@ SettingsDisplay::~SettingsDisplay() void SettingsDisplay::save() { - gfxcard[0] = ui->comboBoxVideo->currentData().toInt(); - gfxcard[1] = ui->comboBoxVideoSecondary->currentData().toInt(); - voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; - ibm8514_enabled = ui->checkBox8514->isChecked() ? 1 : 0; - xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; + gfxcard[0] = ui->comboBoxVideo->currentData().toInt(); + gfxcard[1] = ui->comboBoxVideoSecondary->currentData().toInt(); + voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; + ibm8514_standalone_enabled = ui->checkBox8514->isChecked() ? 1 : 0; + xga_standalone_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; } void @@ -110,7 +110,10 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) void SettingsDisplay::on_pushButtonConfigure_clicked() { - auto *device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); + int videoCard = ui->comboBoxVideo->currentData().toInt(); + auto *device = video_card_getdevice(videoCard); + if (videoCard == VID_INTERNAL) + device = machine_get_vid_device(machineId); DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } @@ -138,8 +141,11 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) } auto curVideoCard_2 = videoCard[1]; videoCard[0] = ui->comboBoxVideo->currentData().toInt(); - ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0); - + if (videoCard[0] == VID_INTERNAL) + ui->pushButtonConfigure->setEnabled(machine_has_flags(machineId, MACHINE_VIDEO) && + device_has_config(machine_get_vid_device(machineId))); + else + ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0); bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; ui->checkBoxVoodoo->setEnabled(machineHasPci); if (machineHasPci) { @@ -147,18 +153,21 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) } ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); - bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; - bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; - ui->checkBox8514->setEnabled(hasIsa16 || has_MCA); - if (hasIsa16 || has_MCA) { - ui->checkBox8514->setChecked(ibm8514_enabled); - } + bool machineHasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; + bool machineHasMca = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; + + bool videoCardHas8514 = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_8514A) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_8514)); + bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); + + ui->checkBox8514->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHas8514); + if (machineHasIsa16 || machineHasMca) + ui->checkBox8514->setChecked(ibm8514_standalone_enabled && !videoCardHas8514); - ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA); - if (hasIsa16 || has_MCA) - ui->checkBoxXga->setChecked(xga_enabled); + ui->checkBoxXga->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHasXga); + if (machineHasIsa16 || machineHasMca) + ui->checkBoxXga->setChecked(xga_standalone_enabled && !videoCardHasXga); - ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked()); + ui->pushButtonConfigureXga->setEnabled((machineHasIsa16 || machineHasMca) && ui->checkBoxXga->isChecked() && !videoCardHasXga); int c = 2; @@ -178,7 +187,13 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) break; } - if (video_card_available(c) && device_is_valid(video_dev, machineId) && !(video_card_get_flags(c) == video_card_get_flags(videoCard[0]) && (video_card_get_flags(c) != VIDEO_FLAG_TYPE_SPECIAL))) { + int primaryFlags = video_card_get_flags(videoCard[0]); + int secondaryFlags = video_card_get_flags(c); + if (video_card_available(c) + && device_is_valid(video_dev, machineId) + && !((secondaryFlags == primaryFlags) && (secondaryFlags != VIDEO_FLAG_TYPE_SPECIAL)) + && !(((primaryFlags == VIDEO_FLAG_TYPE_8514) || (primaryFlags == VIDEO_FLAG_TYPE_XGA)) && (secondaryFlags != VIDEO_FLAG_TYPE_MDA) && (secondaryFlags != VIDEO_FLAG_TYPE_SPECIAL)) + && !((primaryFlags != VIDEO_FLAG_TYPE_MDA) && (primaryFlags != VIDEO_FLAG_TYPE_SPECIAL) && ((secondaryFlags == VIDEO_FLAG_TYPE_8514) || (secondaryFlags == VIDEO_FLAG_TYPE_XGA)))) { ui->comboBoxVideoSecondary->addItem(name, c); if (c == curVideoCard_2) ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); @@ -187,7 +202,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) c++; } - if (videoCard[1] == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { + if ((videoCard[1] == 0) || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index c34c7aa386..5dd76287f2 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -42,7 +42,7 @@ - XGA + XGA Graphics @@ -61,6 +61,9 @@ + + 30 + 0 @@ -92,7 +95,7 @@ - 8514/A + IBM 8514/A Graphics @@ -119,6 +122,9 @@ + + 30 + 0 diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 4d2f6e9f93..988f9e8561 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -45,13 +45,12 @@ static void setFloppyType(QAbstractItemModel *model, const QModelIndex &idx, int type) { QIcon icon; - if (type == 0) { + if (type == 0) icon = ProgSettings::loadIcon("/floppy_disabled.ico"); - } else if (type >= 1 && type <= 6) { + else if (type >= 1 && type <= 6) icon = ProgSettings::loadIcon("/floppy_525.ico"); - } else { + else icon = ProgSettings::loadIcon("/floppy_35.ico"); - } model->setData(idx, QObject::tr(fdd_getname(type))); model->setData(idx, type, Qt::UserRole); @@ -62,6 +61,7 @@ static void setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) { QIcon icon; + switch (bus) { case CDROM_BUS_DISABLED: icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); @@ -94,11 +94,10 @@ static void setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type) { auto i = idx.siblingAtColumn(2); - if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == CDROM_BUS_DISABLED) { + if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == CDROM_BUS_DISABLED) model->setData(i, QCoreApplication::translate("", "None")); - } else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI) { + else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI) model->setData(i, QObject::tr(cdrom_getname(type))); - } model->setData(i, type, Qt::UserRole); } @@ -112,9 +111,8 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) int i = 0; while (true) { QString name = tr(fdd_getname(i)); - if (name.isEmpty()) { + if (name.isEmpty()) break; - } Models::AddEntry(model, name, i); ++i; @@ -139,26 +137,14 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) ui->tableViewFloppy->resizeColumnsToContents(); ui->tableViewFloppy->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onFloppyRowChanged); + connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, + this, &SettingsFloppyCDROM::onFloppyRowChanged); ui->tableViewFloppy->setCurrentIndex(model->index(0, 0)); Harddrives::populateRemovableBuses(ui->comboBoxBus->model()); model = ui->comboBoxSpeed->model(); - for (int i = 0; i < 72; i++) { + for (int i = 0; i < 72; i++) Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1); - } - - model = ui->comboBoxCDROMType->model(); - i = 0; - while (true) { - QString name = tr(cdrom_getname(i)); - if (name.isEmpty()) { - break; - } - - Models::AddEntry(model, name, i); - ++i; - } model = new QStandardItemModel(0, 3, this); ui->tableViewCDROM->setModel(model); @@ -175,15 +161,43 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) if (cdrom[i].bus_type == CDROM_BUS_ATAPI) Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].ide_channel); else if (cdrom[i].bus_type == CDROM_BUS_SCSI) - Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].scsi_device_id); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, + cdrom[i].scsi_device_id); else if (cdrom[i].bus_type == CDROM_BUS_MITSUMI) Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, 0); } ui->tableViewCDROM->resizeColumnsToContents(); ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - connect(ui->tableViewCDROM->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onCDROMRowChanged); + connect(ui->tableViewCDROM->selectionModel(), &QItemSelectionModel::currentRowChanged, + this, &SettingsFloppyCDROM::onCDROMRowChanged); ui->tableViewCDROM->setCurrentIndex(model->index(0, 0)); + + uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); + int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); + + auto *modelType = ui->comboBoxCDROMType->model(); + int removeRows = modelType->rowCount(); + + uint32_t j = 0; + int selectedTypeRow = 0; + int eligibleRows = 0; + while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { + if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && + ((cdrom_drive_types[j].bus_type == bus_type) || + (cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) { + QString name = tr(cdrom_getname(j)); + Models::AddEntry(modelType, name, j); + if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j)) + selectedTypeRow = eligibleRows; + ++eligibleRows; + } + ++j; + } + modelType->removeRows(0, removeRows); + ui->comboBoxCDROMType->setEnabled(eligibleRows > 1); + ui->comboBoxCDROMType->setCurrentIndex(-1); + ui->comboBoxCDROMType->setCurrentIndex(selectedTypeRow); } SettingsFloppyCDROM::~SettingsFloppyCDROM() @@ -234,20 +248,18 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); - int type = current.siblingAtColumn(2).data(Qt::UserRole).toInt(); + int type = current.siblingAtColumn(2).data(Qt::UserRole).toInt(); ui->comboBoxBus->setCurrentIndex(-1); auto* model = ui->comboBoxBus->model(); auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + if (! match.isEmpty()) ui->comboBoxBus->setCurrentIndex(match.first().row()); - } model = ui->comboBoxChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (!match.isEmpty()) { + if (!match.isEmpty()) ui->comboBoxChannel->setCurrentIndex(match.first().row()); - } ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); ui->comboBoxCDROMType->setCurrentIndex(type); @@ -257,36 +269,37 @@ void SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) { auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); - ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ? tr("On") : tr("Off")); + ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ? + tr("On") : tr("Off")); } void SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) { auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); - ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ? tr("On") : tr("Off")); + ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ? + tr("On") : tr("Off")); } void SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) { - setFloppyType(ui->tableViewFloppy->model(), ui->tableViewFloppy->selectionModel()->currentIndex(), index); + setFloppyType(ui->tableViewFloppy->model(), + ui->tableViewFloppy->selectionModel()->currentIndex(), index); } void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { - if (index < 0) { - return; + if (index >= 0) { + int bus = ui->comboBoxBus->currentData().toInt(); + bool enabled = (bus != CDROM_BUS_DISABLED); + ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); + ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); + ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); + + Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); } - - int bus = ui->comboBoxBus->currentData().toInt(); - bool enabled = (bus != CDROM_BUS_DISABLED); - ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled); - - Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); } void @@ -299,10 +312,13 @@ SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { - auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); - uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); + auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); + uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); + int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); - Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, + Qt::UserRole + 1).toInt()); if (bus_type == CDROM_BUS_ATAPI) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_ide_channel()); else if (bus_type == CDROM_BUS_SCSI) @@ -310,38 +326,64 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) else if (bus_type == CDROM_BUS_MITSUMI) ui->comboBoxChannel->setCurrentIndex(0); - setCDROMBus( - ui->tableViewCDROM->model(), - ui->tableViewCDROM->selectionModel()->currentIndex(), - bus_type, - ui->comboBoxChannel->currentData().toUInt()); - setCDROMType( - ui->tableViewCDROM->model(), - ui->tableViewCDROM->selectionModel()->currentIndex(), - ui->comboBoxCDROMType->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + setCDROMBus(ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + bus_type, + ui->comboBoxChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, + Qt::UserRole + 1).toInt()); + + auto *modelType = ui->comboBoxCDROMType->model(); + int removeRows = modelType->rowCount(); + + uint32_t j = 0; + int selectedTypeRow = 0; + int eligibleRows = 0; + while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { + if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && + ((cdrom_drive_types[j].bus_type == bus_type) || + (cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) { + QString name = tr(cdrom_getname(j)); + Models::AddEntry(modelType, name, j); + if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j)) + selectedTypeRow = eligibleRows; + ++eligibleRows; + } + ++j; + } + modelType->removeRows(0, removeRows); + ui->comboBoxCDROMType->setEnabled(eligibleRows > 1); + ui->comboBoxCDROMType->setCurrentIndex(-1); + ui->comboBoxCDROMType->setCurrentIndex(selectedTypeRow); + + setCDROMType(ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + ui->comboBoxCDROMType->currentData().toUInt()); } void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); - setCDROMBus( - ui->tableViewCDROM->model(), - ui->tableViewCDROM->selectionModel()->currentIndex(), - ui->comboBoxBus->currentData().toUInt(), - ui->comboBoxChannel->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, + Qt::UserRole + 1).toInt()); + setCDROMBus(ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + ui->comboBoxBus->currentData().toUInt(), + ui->comboBoxChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, + Qt::UserRole + 1).toInt()); } void SettingsFloppyCDROM::on_comboBoxCDROMType_activated(int) { - setCDROMType( - ui->tableViewCDROM->model(), - ui->tableViewCDROM->selectionModel()->currentIndex(), - ui->comboBoxCDROMType->currentData().toUInt()); + setCDROMType(ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + ui->comboBoxCDROMType->currentData().toUInt()); ui->tableViewCDROM->resizeColumnsToContents(); ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } diff --git a/src/qt/qt_settingsfloppycdrom.ui b/src/qt/qt_settingsfloppycdrom.ui index 7a025e7a67..d7ad853b38 100644 --- a/src/qt/qt_settingsfloppycdrom.ui +++ b/src/qt/qt_settingsfloppycdrom.ui @@ -62,7 +62,11 @@ - + + + 30 + + @@ -150,16 +154,32 @@ - + + + 30 + + - + + + 30 + + - + + + 30 + + - + + + 30 + + diff --git a/src/qt/qt_settingsharddisks.ui b/src/qt/qt_settingsharddisks.ui index ef351e5e7c..3ae20fee1f 100644 --- a/src/qt/qt_settingsharddisks.ui +++ b/src/qt/qt_settingsharddisks.ui @@ -55,7 +55,11 @@ - + + + 30 + + @@ -65,7 +69,11 @@ - + + + 30 + + @@ -75,7 +83,11 @@ - + + + 30 + + diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 630fc705db..05e44c2c01 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -87,9 +87,9 @@ SettingsInput::onCurrentMachineChanged(int machineId) mouseModel->removeRows(0, removeRows); ui->comboBoxMouse->setCurrentIndex(selectedRow); - int i = 0; - char *joyName = joystick_get_name(i); - auto *joystickModel = ui->comboBoxJoystick->model(); + int i = 0; + const char *joyName = joystick_get_name(i); + auto *joystickModel = ui->comboBoxJoystick->model(); removeRows = joystickModel->rowCount(); selectedRow = 0; while (joyName) { @@ -116,7 +116,7 @@ void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { int joystickId = ui->comboBoxJoystick->currentData().toInt(); - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < MAX_JOYSTICKS; ++i) { auto *btn = findChild(QString("pushButtonJoystick%1").arg(i + 1)); if (btn == nullptr) { continue; @@ -137,22 +137,16 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) { int axis_sel = jc.selectedAxis(axis); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) { return axis_sel; } axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int @@ -190,9 +184,9 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent) for (int c = 0; c < joystick_get_button_count(type); c++) { joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c); } - for (int c = 0; c < joystick_get_button_count(type); c++) { + for (int c = 0; c < joystick_get_pov_count(type) * 2; c += 2) { joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c, joystick_nr); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c + 1, joystick_nr); } } } diff --git a/src/qt/qt_settingsinput.ui b/src/qt/qt_settingsinput.ui index 8f4f461676..8394611192 100644 --- a/src/qt/qt_settingsinput.ui +++ b/src/qt/qt_settingsinput.ui @@ -96,6 +96,9 @@ + + 30 + 0 @@ -105,7 +108,11 @@ - + + + 30 + + diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index fead5d5596..475730db9a 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -72,6 +72,21 @@ SettingsMachine::SettingsMachine(QWidget *parent) waitStatesModel->setData(idx, i + 1, Qt::UserRole); } + auto *pitModeModel = ui->comboBoxPitMode->model(); + pitModeModel->insertRows(0, 3); + idx = pitModeModel->index(0, 0); + pitModeModel->setData(idx, tr("Auto"), Qt::DisplayRole); + pitModeModel->setData(idx, -1, Qt::UserRole); + idx = pitModeModel->index(1, 0); + pitModeModel->setData(idx, tr("Slow"), Qt::DisplayRole); + pitModeModel->setData(idx, 0, Qt::UserRole); + idx = pitModeModel->index(2, 0); + pitModeModel->setData(idx, tr("Fast"), Qt::DisplayRole); + pitModeModel->setData(idx, 1, Qt::UserRole); + + ui->comboBoxPitMode->setCurrentIndex(-1); + ui->comboBoxPitMode->setCurrentIndex(pit_mode + 1); + int selectedMachineType = 0; auto *machineTypesModel = ui->comboBoxMachineType->model(); for (int i = 1; i < MACHINE_TYPE_MAX; ++i) { @@ -79,9 +94,8 @@ SettingsMachine::SettingsMachine(QWidget *parent) while (machine_get_internal_name_ex(j) != nullptr) { if (machine_available(j) && (machine_get_type(j) == i)) { int row = Models::AddEntry(machineTypesModel, machine_types[i].name, machine_types[i].id); - if (machine_types[i].id == machine_get_type(machine)) { + if (machine_types[i].id == machine_get_type(machine)) selectedMachineType = row; - } break; } j++; @@ -90,6 +104,11 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->comboBoxMachineType->setCurrentIndex(-1); ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); + +#ifndef USE_DYNAREC + ui->checkBoxDynamicRecompiler->setEnabled(false); + ui->checkBoxDynamicRecompiler->setVisible(false); +#endif } SettingsMachine::~SettingsMachine() @@ -105,213 +124,209 @@ SettingsMachine::save() cpu = ui->comboBoxSpeed->currentData().toInt(); fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; - fpu_softfloat = (ui->checkBoxFPUSoftfloat->isChecked() && !cpu_use_dynarec) ? 1 : 0; - if (!strcmp(machines[machine].internal_name, "ibmps2_m70_type4")) { - cpu_use_dynarec = 0; - fpu_softfloat = 1; - } + fpu_softfloat = ui->checkBoxFPUSoftfloat->isChecked() ? 1 : 0; int64_t temp_mem_size; - if (machine_get_ram_granularity(machine) < 1024) { + if (machine_get_ram_granularity(machine) < 1024) temp_mem_size = ui->spinBoxRAM->value(); - } else { + else temp_mem_size = ui->spinBoxRAM->value() * 1024; - } temp_mem_size &= ~(machine_get_ram_granularity(machine) - 1); - if (temp_mem_size < machine_get_min_ram(machine)) { + if (temp_mem_size < machine_get_min_ram(machine)) temp_mem_size = machine_get_min_ram(machine); - } else if (temp_mem_size > machine_get_max_ram(machine)) { + else if (temp_mem_size > machine_get_max_ram(machine)) temp_mem_size = machine_get_max_ram(machine); - } mem_size = static_cast(temp_mem_size); - if (ui->comboBoxWaitStates->isEnabled()) { + if (ui->comboBoxWaitStates->isEnabled()) cpu_waitstates = ui->comboBoxWaitStates->currentData().toInt(); - } else { + else cpu_waitstates = 0; - } + + pit_mode = ui->comboBoxPitMode->currentData().toInt(); time_sync = 0; - if (ui->radioButtonLocalTime->isChecked()) { + if (ui->radioButtonLocalTime->isChecked()) time_sync = TIME_SYNC_ENABLED; - } - if (ui->radioButtonUTC->isChecked()) { + if (ui->radioButtonUTC->isChecked()) time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; - } } void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { - if (index < 0) { - return; - } - - auto *model = ui->comboBoxMachine->model(); - int removeRows = model->rowCount(); - - int selectedMachineRow = 0; - for (int i = 0; i < machine_count(); ++i) { - if ((machine_get_type(i) == ui->comboBoxMachineType->currentData().toInt()) && machine_available(i)) { - int row = Models::AddEntry(model, machines[i].name, i); - if (i == machine) { - selectedMachineRow = row - removeRows; + if (index >= 0) { + auto *model = ui->comboBoxMachine->model(); + int removeRows = model->rowCount(); + + int selectedMachineRow = 0; + for (int i = 0; i < machine_count(); ++i) { + if ((machine_get_type(i) == ui->comboBoxMachineType->currentData().toInt()) && + machine_available(i)) { + int row = Models::AddEntry(model, machines[i].name, i); + if (i == machine) + selectedMachineRow = row - removeRows; } } - } - model->removeRows(0, removeRows); + model->removeRows(0, removeRows); - ui->comboBoxMachine->setCurrentIndex(-1); - ui->comboBoxMachine->setCurrentIndex(selectedMachineRow); + ui->comboBoxMachine->setCurrentIndex(-1); + ui->comboBoxMachine->setCurrentIndex(selectedMachineRow); + } } void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { // win_settings_machine_recalc_machine - if (index < 0) { - return; - } - - int machineId = ui->comboBoxMachine->currentData().toInt(); - const auto *device = machine_get_device(machineId); - ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); - - auto *modelCpu = ui->comboBoxCPU->model(); - int removeRows = modelCpu->rowCount(); - - int i = 0; - int eligibleRows = 0; - int selectedCpuFamilyRow = 0; - while (cpu_families[i].package != 0) { - if (cpu_family_is_eligible(&cpu_families[i], machineId)) { - Models::AddEntry(modelCpu, QString("%1 %2").arg(cpu_families[i].manufacturer, cpu_families[i].name), i); - if (&cpu_families[i] == cpu_f) { - selectedCpuFamilyRow = eligibleRows; + if (index >= 0) { + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_get_device(machineId); + ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); + + auto *modelCpu = ui->comboBoxCPU->model(); + int removeRows = modelCpu->rowCount(); + + int i = 0; + int eligibleRows = 0; + int selectedCpuFamilyRow = 0; + while (cpu_families[i].package != 0) { + if (cpu_family_is_eligible(&cpu_families[i], machineId)) { + Models::AddEntry(modelCpu, QString("%1 %2").arg(cpu_families[i].manufacturer, + cpu_families[i].name), i); + if (&cpu_families[i] == cpu_f) + selectedCpuFamilyRow = eligibleRows; + ++eligibleRows; } - ++eligibleRows; + ++i; } - ++i; - } - modelCpu->removeRows(0, removeRows); - ui->comboBoxCPU->setEnabled(eligibleRows > 1); - ui->comboBoxCPU->setCurrentIndex(-1); - ui->comboBoxCPU->setCurrentIndex(selectedCpuFamilyRow); - - int divisor; - if (machine_get_ram_granularity(machineId) < 1024) { - divisor = 1; - ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "KB").prepend(' ')); - } else { - divisor = 1024; - ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "MB").prepend(' ')); - } - ui->spinBoxRAM->setMinimum(machine_get_min_ram(machineId) / divisor); - ui->spinBoxRAM->setMaximum(machine_get_max_ram(machineId) / divisor); - ui->spinBoxRAM->setSingleStep(machine_get_ram_granularity(machineId) / divisor); - ui->spinBoxRAM->setValue(mem_size / divisor); - ui->spinBoxRAM->setEnabled(machine_get_min_ram(machineId) != machine_get_max_ram(machineId)); + modelCpu->removeRows(0, removeRows); + ui->comboBoxCPU->setEnabled(eligibleRows > 1); + ui->comboBoxCPU->setCurrentIndex(-1); + ui->comboBoxCPU->setCurrentIndex(selectedCpuFamilyRow); + + int divisor; + if (machine_get_ram_granularity(machineId) < 1024) { + divisor = 1; + ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "KB").prepend(' ')); + } else { + divisor = 1024; + ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "MB").prepend(' ')); + } + ui->spinBoxRAM->setMinimum(machine_get_min_ram(machineId) / divisor); + ui->spinBoxRAM->setMaximum(machine_get_max_ram(machineId) / divisor); + ui->spinBoxRAM->setSingleStep(machine_get_ram_granularity(machineId) / divisor); + ui->spinBoxRAM->setValue(mem_size / divisor); + ui->spinBoxRAM->setEnabled(machine_get_min_ram(machineId) != machine_get_max_ram(machineId)); - emit currentMachineChanged(machineId); + emit currentMachineChanged(machineId); + } } void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { - if (index < 0) { - return; - } - - int machineId = ui->comboBoxMachine->currentData().toInt(); - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto *cpuFamily = &cpu_families[cpuFamilyId]; - - auto *modelSpeed = ui->comboBoxSpeed->model(); - int removeRows = modelSpeed->rowCount(); - - // win_settings_machine_recalc_cpu_m - int i = 0; - int eligibleRows = 0; - int selectedSpeedRow = 0; - while (cpuFamily->cpus[i].cpu_type != 0) { - if (cpu_is_eligible(cpuFamily, i, machineId)) { - Models::AddEntry(modelSpeed, QString("%1").arg(cpuFamily->cpus[i].name), i); - if (cpu == i) { - selectedSpeedRow = eligibleRows; + if (index >= 0) { + int machineId = ui->comboBoxMachine->currentData().toInt(); + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; + + auto *modelSpeed = ui->comboBoxSpeed->model(); + int removeRows = modelSpeed->rowCount(); + + // win_settings_machine_recalc_cpu_m + int i = 0; + int eligibleRows = 0; + int selectedSpeedRow = 0; + while (cpuFamily->cpus[i].cpu_type != 0) { + if (cpu_is_eligible(cpuFamily, i, machineId)) { + Models::AddEntry(modelSpeed, QString("%1").arg(cpuFamily->cpus[i].name), i); + if (cpu == i) + selectedSpeedRow = eligibleRows; + ++eligibleRows; } - ++eligibleRows; + ++i; } - ++i; + modelSpeed->removeRows(0, removeRows); + ui->comboBoxSpeed->setEnabled(eligibleRows > 1); + ui->comboBoxSpeed->setCurrentIndex(-1); + ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow); } - modelSpeed->removeRows(0, removeRows); - ui->comboBoxSpeed->setEnabled(eligibleRows > 1); - ui->comboBoxSpeed->setCurrentIndex(-1); - ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow); } void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { - if (index < 0) { - return; - } - - // win_settings_machine_recalc_cpu - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto *cpuFamily = &cpu_families[cpuFamilyId]; - int cpuId = ui->comboBoxSpeed->currentData().toInt(); - uint cpuType = cpuFamily->cpus[cpuId].cpu_type; - - if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { - ui->comboBoxWaitStates->setEnabled(true); - ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); - } else { - ui->comboBoxWaitStates->setCurrentIndex(0); - ui->comboBoxWaitStates->setEnabled(false); - } + if (index >= 0) { + // win_settings_machine_recalc_cpu + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; + int cpuId = ui->comboBoxSpeed->currentData().toInt(); + uint cpuType = cpuFamily->cpus[cpuId].cpu_type; + + if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { + ui->comboBoxWaitStates->setEnabled(true); + ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); + } else { + ui->comboBoxWaitStates->setCurrentIndex(0); + ui->comboBoxWaitStates->setEnabled(false); + } #ifdef USE_DYNAREC - uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags; - if (!(flags & CPU_SUPPORTS_DYNAREC)) { - ui->checkBoxDynamicRecompiler->setChecked(false); - ui->checkBoxDynamicRecompiler->setEnabled(false); - ui->checkBoxFPUSoftfloat->setChecked(fpu_softfloat); - ui->checkBoxFPUSoftfloat->setEnabled(cpu_use_dynarec ? false : true); - } else if (flags & CPU_REQUIRES_DYNAREC) { - ui->checkBoxDynamicRecompiler->setChecked(true); - ui->checkBoxDynamicRecompiler->setEnabled(false); - ui->checkBoxFPUSoftfloat->setChecked(false); - ui->checkBoxFPUSoftfloat->setEnabled(false); - } else { - ui->checkBoxDynamicRecompiler->setChecked(cpu_use_dynarec); - ui->checkBoxDynamicRecompiler->setEnabled(true); - ui->checkBoxFPUSoftfloat->setChecked(fpu_softfloat); - ui->checkBoxFPUSoftfloat->setEnabled(cpu_use_dynarec ? false : true); - } -#else - ui->checkBoxFPUSoftfloat->setChecked(fpu_softfloat); - ui->checkBoxFPUSoftfloat->setEnabled(true); + uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags; + if (!(flags & CPU_SUPPORTS_DYNAREC)) { + ui->checkBoxDynamicRecompiler->setChecked(false); + ui->checkBoxDynamicRecompiler->setEnabled(false); + } else if ((flags & CPU_REQUIRES_DYNAREC) && !cpu_override) { + ui->checkBoxDynamicRecompiler->setChecked(true); + ui->checkBoxDynamicRecompiler->setEnabled(false); + } else { + ui->checkBoxDynamicRecompiler->setChecked(cpu_use_dynarec); + ui->checkBoxDynamicRecompiler->setEnabled(true); + } #endif - // win_settings_machine_recalc_fpu - auto *modelFpu = ui->comboBoxFPU->model(); - int removeRows = modelFpu->rowCount(); - - int i = 0; - int selectedFpuRow = 0; - for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { - auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i); - Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType); - if (fpu_type == fpuType) { - selectedFpuRow = i; + // win_settings_machine_recalc_fpu + auto *modelFpu = ui->comboBoxFPU->model(); + int removeRows = modelFpu->rowCount(); + + int i = 0; + int selectedFpuRow = 0; + for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); + fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { + auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i); + Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType); + if (fpu_type == fpuType) + selectedFpuRow = i; } + + modelFpu->removeRows(0, removeRows); + ui->comboBoxFPU->setEnabled(modelFpu->rowCount() > 1); + ui->comboBoxFPU->setCurrentIndex(-1); + ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); } +} - modelFpu->removeRows(0, removeRows); - ui->comboBoxFPU->setEnabled(modelFpu->rowCount() > 1); - ui->comboBoxFPU->setCurrentIndex(-1); - ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); +void +SettingsMachine::on_comboBoxFPU_currentIndexChanged(int index) +{ + if (index >= 0) { + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; + int cpuId = ui->comboBoxSpeed->currentData().toInt(); + int machineId = ui->comboBoxMachine->currentData().toInt(); + + if (fpu_get_type_from_index(cpuFamily, cpuId, index) == FPU_NONE) { + ui->checkBoxFPUSoftfloat->setChecked(false); + ui->checkBoxFPUSoftfloat->setEnabled(false); + } else { + ui->checkBoxFPUSoftfloat->setChecked(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? + true : fpu_softfloat); + ui->checkBoxFPUSoftfloat->setEnabled(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? + false : true); + } + } } void diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index abb4f3014d..9d0ec62ffb 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -21,6 +21,9 @@ class SettingsMachine : public QWidget { private slots: void on_pushButtonConfigure_clicked(); +private slots: + void on_comboBoxFPU_currentIndexChanged(int index); + private slots: void on_comboBoxSpeed_currentIndexChanged(int index); diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index ee8a048f48..54bc06f5c8 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -7,7 +7,7 @@ 0 0 458 - 391 + 434 @@ -41,26 +41,37 @@ 0 - - + + - Machine type: + Wait states: - + + + 30 + + - - + + - Machine: + Memory: - - - + + + + 30 + + + + + + 0 @@ -74,18 +85,35 @@ 0 - - - - + + + 30 + - + 0 0 + + + + - Configure + PIT mode: + + + + + + + 30 + + + + 0 + 0 + @@ -116,6 +144,9 @@ + + 30 + 0 @@ -127,7 +158,7 @@ - Speed: + Frequency: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -136,6 +167,9 @@ + + 30 + 0 @@ -147,40 +181,72 @@ - - - - FPU: + + + + + 0 + 0 + - - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 30 + + + + + + + + 0 + 0 + + + + Configure + + + + + - - + + - Wait states: + Machine type: - - - - - + + - Memory: + Machine: - - - - - 0 - 0 - + + + + FPU: diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 5b5d1b1ee5..2aa3705fd5 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -47,7 +47,12 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP); nic_cbox->setEnabled(adaptersEnabled); - conf_btn->setEnabled(adaptersEnabled && network_card_has_config(nic_cbox->currentData().toInt())); + int netCard = nic_cbox->currentData().toInt(); + if ((i == 0) && (netCard == NET_INTERNAL)) + conf_btn->setEnabled(adaptersEnabled && machine_has_flags(machineId, MACHINE_NIC) && + device_has_config(machine_get_net_device(machineId))); + else + conf_btn->setEnabled(adaptersEnabled && network_card_has_config(nic_cbox->currentData().toInt())); socket_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_VDE); } } @@ -110,6 +115,12 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) selectedRow = 0; while (true) { + /* Skip "internal" if machine doesn't have it or this is not the primary card. */ + if ((c == 1) && ((i > 0) || (machine_has_flags(machineId, MACHINE_NIC) == 0))) { + c++; + continue; + } + auto name = DeviceConfig::DeviceName(network_card_getdevice(c), network_card_get_internal_name(c), 1); if (name.isEmpty()) { break; @@ -182,23 +193,33 @@ SettingsNetwork::on_comboIndexChanged(int index) void SettingsNetwork::on_pushButtonConf1_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC1->currentData().toInt()), 1, qobject_cast(Settings::settings)); + int netCard = ui->comboBoxNIC1->currentData().toInt(); + auto *device = network_card_getdevice(netCard); + if (netCard == NET_INTERNAL) + device = machine_get_net_device(machineId); + DeviceConfig::ConfigureDevice(device, 1, qobject_cast(Settings::settings)); } void SettingsNetwork::on_pushButtonConf2_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC2->currentData().toInt()), 2, qobject_cast(Settings::settings)); + int netCard = ui->comboBoxNIC2->currentData().toInt(); + auto *device = network_card_getdevice(netCard); + DeviceConfig::ConfigureDevice(device, 2, qobject_cast(Settings::settings)); } void SettingsNetwork::on_pushButtonConf3_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC3->currentData().toInt()), 3, qobject_cast(Settings::settings)); + int netCard = ui->comboBoxNIC3->currentData().toInt(); + auto *device = network_card_getdevice(netCard); + DeviceConfig::ConfigureDevice(device, 3, qobject_cast(Settings::settings)); } void SettingsNetwork::on_pushButtonConf4_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC4->currentData().toInt()), 4, qobject_cast(Settings::settings)); + int netCard = ui->comboBoxNIC4->currentData().toInt(); + auto *device = network_card_getdevice(netCard); + DeviceConfig::ConfigureDevice(device, 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsnetwork.ui b/src/qt/qt_settingsnetwork.ui index d6f77a0a2c..8f1eb5a795 100644 --- a/src/qt/qt_settingsnetwork.ui +++ b/src/qt/qt_settingsnetwork.ui @@ -36,8 +36,8 @@ Network Card #1 - - + + 0 @@ -45,34 +45,21 @@ - Adapter + Mode - - - - - 0 - 0 - - - - QComboBox::AdjustToContents + + + + 30 - - - - - + 0 0 - - Configure - @@ -88,8 +75,11 @@ - - + + + + 30 + 0 @@ -98,46 +88,45 @@ - - + + - + 0 0 + + Adapter + - - - - Qt::Vertical - - - - 20 - 40 - + + + + 30 - - - - - + 0 0 - - Mode + + QComboBox::AdjustToContents - - - - 127 + + + + + 0 + 0 + + + + Configure @@ -148,14 +137,14 @@ - - - - - Network Card #2 - - - + + + + 127 + + + + Qt::Vertical @@ -168,20 +157,36 @@ - - + + + + + Network Card #2 + + + + - + 0 0 + + Mode + - - - - Configure + + + + 30 + + + + 0 + 0 + @@ -198,6 +203,19 @@ + + + + 30 + + + + 0 + 0 + + + + @@ -213,6 +231,9 @@ + + 30 + 0 @@ -224,26 +245,10 @@ - - - - - 0 - 0 - - + + - Mode - - - - - - - - 0 - 0 - + Configure @@ -255,20 +260,14 @@ - - - - - - - Network Card #3 - - - - + + + 127 + + - + Qt::Vertical @@ -280,8 +279,15 @@ - - + + + + + Network Card #3 + + + + 0 @@ -289,12 +295,15 @@ - Adapter + Mode + + 30 + 0 @@ -318,6 +327,9 @@ + + 30 + 0 @@ -326,8 +338,24 @@ + + + + + 0 + 0 + + + + Adapter + + + + + 30 + 0 @@ -355,23 +383,30 @@ - VDE Socket + VDE Socket - - - - - 0 - 0 - - - - Mode + + + + 127 + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -379,8 +414,8 @@ Network Card #4 - - + + 0 @@ -388,7 +423,20 @@ - Adapter + Mode + + + + + + + 30 + + + + 0 + 0 + @@ -405,40 +453,46 @@ - - + + + + 30 + - + 0 0 - - Mode - - - + + - + 0 0 - - QComboBox::AdjustToContents + + Adapter - - + + + + 30 + 0 0 + + QComboBox::AdjustToContents + @@ -454,6 +508,20 @@ + + + + 127 + + + + + + + VDE Socket + + + @@ -467,26 +535,6 @@ - - - - - 0 - 0 - - - - - - - - - - - VDE Socket - - - diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index e0edd7358d..f662b644c4 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -23,6 +23,7 @@ extern "C" { #include <86box/machine.h> #include <86box/isamem.h> #include <86box/isartc.h> +#include <86box/unittester.h> } #include "qt_deviceconfig.hpp" @@ -41,11 +42,14 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) { this->machineId = machineId; - ui->checkBoxISABugger->setChecked(bugger_enabled > 0 ? true : false); + bool machineHasIsa = (machine_has_bus(machineId, MACHINE_BUS_ISA) > 0); + ui->checkBoxISABugger->setChecked((machineHasIsa && (bugger_enabled > 0)) ? true : false); ui->checkBoxPOSTCard->setChecked(postcard_enabled > 0 ? true : false); - ui->checkBoxISABugger->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); - ui->comboBoxRTC->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); - ui->pushButtonConfigureRTC->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); + ui->checkBoxUnitTester->setChecked(unittester_enabled > 0 ? true : false); + ui->checkBoxISABugger->setEnabled(machineHasIsa); + ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); + ui->comboBoxRTC->setEnabled(machineHasIsa); + ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); ui->comboBoxCard1->clear(); ui->comboBoxCard2->clear(); @@ -97,8 +101,8 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) } cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); - cbox->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); - findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + cbox->setEnabled(machineHasIsa); + findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machineHasIsa); } } @@ -111,9 +115,10 @@ void SettingsOtherPeripherals::save() { /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; - postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; + unittester_enabled = ui->checkBoxUnitTester->isChecked() ? 1 : 0; + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { @@ -196,3 +201,15 @@ SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() { DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } + +void +SettingsOtherPeripherals::on_checkBoxUnitTester_stateChanged(int arg1) +{ + ui->pushButtonConfigureUT->setEnabled(arg1 != 0); +} + +void +SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() +{ + DeviceConfig::ConfigureDevice(&unittester_device); +} diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index 97e47c90e3..feaa7a0012 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -30,6 +30,8 @@ private slots: void on_comboBoxCard1_currentIndexChanged(int index); void on_pushButtonConfigureRTC_clicked(); void on_comboBoxRTC_currentIndexChanged(int index); + void on_checkBoxUnitTester_stateChanged(int arg1); + void on_pushButtonConfigureUT_clicked(); private: Ui::SettingsOtherPeripherals *ui; diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index 62a4b93082..af953a9842 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -37,6 +37,9 @@ + + 30 + 0 @@ -68,7 +71,17 @@ - + + + 30 + + + + 0 + 0 + + + @@ -100,6 +113,9 @@ + + 30 + 0 @@ -116,10 +132,30 @@ - + + + 30 + + + + 0 + 0 + + + - + + + 30 + + + + 0 + 0 + + + @@ -156,6 +192,30 @@ + + + + + + 86Box Unit Tester + + + + 0 + 0 + + + + + + + + Configure + + + + + diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index bb77046d26..f8b29dac59 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -36,7 +36,8 @@ extern "C" { static QString moDriveTypeName(int i) { - return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, mo_drive_types[i].revision); + return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, + mo_drive_types[i].revision); } static void @@ -51,6 +52,9 @@ setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t case MO_BUS_SCSI: icon = ProgSettings::loadIcon("/mo.ico"); break; + + default: + break; } auto i = idx.siblingAtColumn(0); @@ -64,11 +68,10 @@ static void setMOType(QAbstractItemModel *model, const QModelIndex &idx, uint32_t type) { auto i = idx.siblingAtColumn(1); - if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) { + if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) model->setData(i, QCoreApplication::translate("", "None")); - } else { + else model->setData(i, moDriveTypeName(type)); - } model->setData(i, type, Qt::UserRole); } @@ -84,6 +87,9 @@ setZIPBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_ case ZIP_BUS_SCSI: icon = ProgSettings::loadIcon("/zip.ico"); break; + + default: + break; } auto i = idx.siblingAtColumn(0); @@ -158,9 +164,9 @@ SettingsOtherRemovable::~SettingsOtherRemovable() void SettingsOtherRemovable::save() { - auto *model = ui->tableViewMO->model(); - for (int i = 0; i < MO_NUM; i++) { - mo_drives[i].f = NULL; + const auto *model = ui->tableViewMO->model(); + for (uint8_t i = 0; i < MO_NUM; i++) { + mo_drives[i].fp = NULL; mo_drives[i].priv = NULL; mo_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); @@ -168,8 +174,8 @@ SettingsOtherRemovable::save() } model = ui->tableViewZIP->model(); - for (int i = 0; i < ZIP_NUM; i++) { - zip_drives[i].f = NULL; + for (uint8_t i = 0; i < ZIP_NUM; i++) { + zip_drives[i].fp = NULL; zip_drives[i].priv = NULL; zip_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); @@ -185,17 +191,15 @@ SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); ui->comboBoxMOBus->setCurrentIndex(-1); - auto *model = ui->comboBoxMOBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (!match.isEmpty()) { + const auto *model = ui->comboBoxMOBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) ui->comboBoxMOBus->setCurrentIndex(match.first().row()); - } model = ui->comboBoxMOChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (!match.isEmpty()) { + if (!match.isEmpty()) ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); - } ui->comboBoxMOType->setCurrentIndex(type); } @@ -207,75 +211,77 @@ SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); ui->comboBoxZIPBus->setCurrentIndex(-1); - auto *model = ui->comboBoxZIPBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (!match.isEmpty()) { + const auto *model = ui->comboBoxZIPBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) ui->comboBoxZIPBus->setCurrentIndex(match.first().row()); - } model = ui->comboBoxZIPChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (!match.isEmpty()) { + if (!match.isEmpty()) ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); - } ui->checkBoxZIP250->setChecked(is250); } void SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) { - if (index < 0) { - return; + if (index >= 0) { + int bus = ui->comboBoxMOBus->currentData().toInt(); + bool enabled = (bus != MO_BUS_DISABLED); + ui->comboBoxMOChannel->setEnabled(enabled); + ui->comboBoxMOType->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); } - - int bus = ui->comboBoxMOBus->currentData().toInt(); - bool enabled = (bus != MO_BUS_DISABLED); - ui->comboBoxMOChannel->setEnabled(enabled); - ui->comboBoxMOType->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); } void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); - ui->comboBoxMOChannel->setCurrentIndex(ui->comboBoxMOBus->currentData().toUInt() == MO_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); + Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, + Qt::UserRole + 1).toInt()); + ui->comboBoxMOChannel->setCurrentIndex(ui->comboBoxMOBus->currentData().toUInt() == + MO_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : + Harddrives::busTrackClass->next_free_scsi_id()); ui->tableViewMO->model()->data(i, Qt::UserRole + 1); - setMOBus( - ui->tableViewMO->model(), - ui->tableViewMO->selectionModel()->currentIndex(), - ui->comboBoxMOBus->currentData().toUInt(), - ui->comboBoxMOChannel->currentData().toUInt()); - setMOType( - ui->tableViewMO->model(), - ui->tableViewMO->selectionModel()->currentIndex(), - ui->comboBoxMOType->currentData().toUInt()); + setMOBus(ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOBus->currentData().toUInt(), + ui->comboBoxMOChannel->currentData().toUInt()); + setMOType(ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOType->currentData().toUInt()); ui->tableViewMO->resizeColumnsToContents(); ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, + Qt::UserRole + 1).toInt()); } void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); - setMOBus( - ui->tableViewMO->model(), - ui->tableViewMO->selectionModel()->currentIndex(), - ui->comboBoxMOBus->currentData().toUInt(), - ui->comboBoxMOChannel->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, + Qt::UserRole + 1).toInt()); + setMOBus(ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOBus->currentData().toUInt(), + ui->comboBoxMOChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, + Qt::UserRole + 1).toInt()); } void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { - setMOType( - ui->tableViewMO->model(), - ui->tableViewMO->selectionModel()->currentIndex(), - ui->comboBoxMOType->currentData().toUInt()); + setMOType(ui->tableViewMO->model(), + ui->tableViewMO->selectionModel()->currentIndex(), + ui->comboBoxMOType->currentData().toUInt()); ui->tableViewMO->resizeColumnsToContents(); ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } @@ -283,49 +289,54 @@ SettingsOtherRemovable::on_comboBoxMOType_activated(int) void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { - if (index < 0) { - return; + if (index >= 0) { + int bus = ui->comboBoxZIPBus->currentData().toInt(); + bool enabled = (bus != ZIP_BUS_DISABLED); + ui->comboBoxZIPChannel->setEnabled(enabled); + ui->checkBoxZIP250->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); } - - int bus = ui->comboBoxZIPBus->currentData().toInt(); - bool enabled = (bus != ZIP_BUS_DISABLED); - ui->comboBoxZIPChannel->setEnabled(enabled); - ui->checkBoxZIP250->setEnabled(enabled); - Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); } void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); - ui->comboBoxZIPChannel->setCurrentIndex(ui->comboBoxZIPBus->currentData().toUInt() == ZIP_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); - setZIPBus( - ui->tableViewZIP->model(), - ui->tableViewZIP->selectionModel()->currentIndex(), - ui->comboBoxZIPBus->currentData().toUInt(), - ui->comboBoxZIPChannel->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, + Qt::UserRole + 1).toInt()); + ui->comboBoxZIPChannel->setCurrentIndex(ui->comboBoxZIPBus->currentData().toUInt() == ZIP_BUS_ATAPI ? + Harddrives::busTrackClass->next_free_ide_channel() : + Harddrives::busTrackClass->next_free_scsi_id()); + setZIPBus(ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + ui->comboBoxZIPBus->currentData().toUInt(), + ui->comboBoxZIPChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, + Qt::UserRole + 1).toInt()); } void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); - setZIPBus( - ui->tableViewZIP->model(), - ui->tableViewZIP->selectionModel()->currentIndex(), - ui->comboBoxZIPBus->currentData().toUInt(), - ui->comboBoxZIPChannel->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, + Qt::UserRole + 1).toInt()); + setZIPBus(ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + ui->comboBoxZIPBus->currentData().toUInt(), + ui->comboBoxZIPChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, + Qt::UserRole).toInt(), + ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); } void SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) { - setZIPType( - ui->tableViewZIP->model(), - ui->tableViewZIP->selectionModel()->currentIndex(), - state == Qt::Checked); + setZIPType(ui->tableViewZIP->model(), + ui->tableViewZIP->selectionModel()->currentIndex(), + state == Qt::Checked); } diff --git a/src/qt/qt_settingsotherremovable.ui b/src/qt/qt_settingsotherremovable.ui index c57dd3ca2b..219333376c 100644 --- a/src/qt/qt_settingsotherremovable.ui +++ b/src/qt/qt_settingsotherremovable.ui @@ -69,10 +69,18 @@ - + + + 30 + + - + + + 30 + + @@ -82,7 +90,11 @@ - + + + 30 + + @@ -135,7 +147,11 @@ - + + + 30 + + @@ -145,7 +161,11 @@ - + + + 30 + + diff --git a/src/qt/qt_settingsports.ui b/src/qt/qt_settingsports.ui index 7a338aff5c..bca870e5de 100644 --- a/src/qt/qt_settingsports.ui +++ b/src/qt/qt_settingsports.ui @@ -36,7 +36,11 @@ - + + + 30 + + @@ -46,7 +50,11 @@ - + + + 30 + + @@ -56,7 +64,11 @@ - + + + 30 + + @@ -66,7 +78,11 @@ - + + + 30 + + diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index f792791c1e..b4df4ff694 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -82,8 +82,8 @@ SettingsSound::onCurrentMachineChanged(int machineId) selectedRow = 0; while (true) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && (machine_has_flags(machineId, MACHINE_SOUND) == 0)) { + /* Skip "internal" if machine doesn't have it or this is not the primary card. */ + if ((c == 1) && ((i > 0) || (machine_has_flags(machineId, MACHINE_SOUND) == 0))) { c++; continue; } @@ -192,13 +192,22 @@ SettingsSound::on_comboBoxSoundCard1_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureSoundCard1->setEnabled(sound_card_has_config(ui->comboBoxSoundCard1->currentData().toInt())); + int sndCard = ui->comboBoxSoundCard1->currentData().toInt(); + if (sndCard == SOUND_INTERNAL) + ui->pushButtonConfigureSoundCard1->setEnabled(machine_has_flags(machineId, MACHINE_SOUND) && + device_has_config(machine_get_snd_device(machineId))); + else + ui->pushButtonConfigureSoundCard1->setEnabled(sound_card_has_config(sndCard)); } void SettingsSound::on_pushButtonConfigureSoundCard1_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard1->currentData().toInt()), 0, qobject_cast(Settings::settings)); + int sndCard = ui->comboBoxSoundCard1->currentData().toInt(); + auto *device = sound_card_getdevice(sndCard); + if (sndCard == SOUND_INTERNAL) + device = machine_get_snd_device(machineId); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } void @@ -207,13 +216,16 @@ SettingsSound::on_comboBoxSoundCard2_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureSoundCard2->setEnabled(sound_card_has_config(ui->comboBoxSoundCard2->currentData().toInt())); + int sndCard = ui->comboBoxSoundCard2->currentData().toInt(); + ui->pushButtonConfigureSoundCard2->setEnabled(sound_card_has_config(sndCard)); } void SettingsSound::on_pushButtonConfigureSoundCard2_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard2->currentData().toInt()), 0, qobject_cast(Settings::settings)); + int sndCard = ui->comboBoxSoundCard2->currentData().toInt(); + auto *device = sound_card_getdevice(sndCard); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } void @@ -222,13 +234,16 @@ SettingsSound::on_comboBoxSoundCard3_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureSoundCard3->setEnabled(sound_card_has_config(ui->comboBoxSoundCard3->currentData().toInt())); + int sndCard = ui->comboBoxSoundCard3->currentData().toInt(); + ui->pushButtonConfigureSoundCard3->setEnabled(sound_card_has_config(sndCard)); } void SettingsSound::on_pushButtonConfigureSoundCard3_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard3->currentData().toInt()), 0, qobject_cast(Settings::settings)); + int sndCard = ui->comboBoxSoundCard3->currentData().toInt(); + auto *device = sound_card_getdevice(sndCard); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } void @@ -237,13 +252,16 @@ SettingsSound::on_comboBoxSoundCard4_currentIndexChanged(int index) if (index < 0) { return; } - ui->pushButtonConfigureSoundCard4->setEnabled(sound_card_has_config(ui->comboBoxSoundCard4->currentData().toInt())); + int sndCard = ui->comboBoxSoundCard4->currentData().toInt(); + ui->pushButtonConfigureSoundCard4->setEnabled(sound_card_has_config(sndCard)); } void SettingsSound::on_pushButtonConfigureSoundCard4_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard4->currentData().toInt()), 0, qobject_cast(Settings::settings)); + int sndCard = ui->comboBoxSoundCard4->currentData().toInt(); + auto *device = sound_card_getdevice(sndCard); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } void diff --git a/src/qt/qt_settingssound.ui b/src/qt/qt_settingssound.ui index f85a09a0d7..1d5ab00508 100644 --- a/src/qt/qt_settingssound.ui +++ b/src/qt/qt_settingssound.ui @@ -94,6 +94,9 @@ + + 30 + 0 @@ -132,6 +135,9 @@ + + 30 + 0 @@ -198,6 +204,9 @@ + + 30 + 0 @@ -208,6 +217,9 @@ + + 30 + 0 @@ -218,6 +230,9 @@ + + 30 + 0 @@ -228,6 +243,9 @@ + + 30 + 0 diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index a732e98200..30949de3ad 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -40,8 +40,6 @@ SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) { ui->setupUi(this); - ui->checkBoxCassette->setChecked(cassette_enable > 0); - onCurrentMachineChanged(machine); } @@ -58,12 +56,12 @@ SettingsStorageControllers::save() auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } - hdc_current = ui->comboBoxHD->currentData().toInt(); - fdc_type = ui->comboBoxFD->currentData().toInt(); - cdrom_interface_current = ui->comboBoxCDInterface->currentData().toInt(); - ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; - ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; - cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; + hdc_current = ui->comboBoxHD->currentData().toInt(); + fdc_type = ui->comboBoxFD->currentData().toInt(); + cdrom_interface_current = ui->comboBoxCDInterface->currentData().toInt(); + ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; + ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; + cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; } void @@ -134,9 +132,9 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxFD->setCurrentIndex(selectedRow); /*CD interface controller config*/ - model = ui->comboBoxCDInterface->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxCDInterface->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ @@ -198,6 +196,14 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxQuaternaryIDE->setEnabled(is_at > 0); ui->checkBoxTertiaryIDE->setChecked(ui->checkBoxTertiaryIDE->isEnabled() && ide_ter_enabled); ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); + + if (machine_has_bus(machineId, MACHINE_BUS_CASSETTE)) { + ui->checkBoxCassette->setChecked(cassette_enable > 0); + ui->checkBoxCassette->setEnabled(true); + } else { + ui->checkBoxCassette->setChecked(false); + ui->checkBoxCassette->setEnabled(false); + } } void diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index 9fc0ea5190..d67127e2d4 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -61,6 +61,9 @@ + + 30 + false @@ -78,6 +81,9 @@ + + 30 + 0 @@ -94,7 +100,11 @@ - + + + 30 + + @@ -161,6 +171,9 @@ + + 30 + 0 @@ -177,13 +190,43 @@ - + + + 30 + + + + 0 + 0 + + + - + + + 30 + + + + 0 + 0 + + + - + + + 30 + + + + 0 + 0 + + + diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 8450994369..017354f820 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc @@ -1,5 +1,6 @@ + 86box_ca-ES.qm 86box_cs-CZ.qm 86box_de-DE.qm 86box_en-US.qm @@ -16,6 +17,7 @@ 86box_pt-BR.qm 86box_pt-PT.qm 86box_ru-RU.qm + 86box_sk-SK.qm 86box_sl-SI.qm 86box_tr-TR.qm 86box_uk-UA.qm diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 22dad3fa10..47e6b48a2e 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -88,12 +88,6 @@ qt_blit(int x, int y, int w, int h, int monitor_index) main_window->blitToWidget(x, y, w, h, monitor_index); } -void -mouse_poll() -{ - main_window->pollMouse(); -} - extern "C" int vid_resize; void plat_resize_request(int w, int h, int monitor_index) diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index 73594ea9ee..9227cdcb3b 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -938,9 +938,6 @@ VulkanRenderer2::startNextFrame() if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); QMatrix4x4 m = m_proj; -#if 0 - m.rotate(m_rotation, 0, 0, 1); -#endif memcpy(p, m.constData(), 16 * sizeof(float)); m_devFuncs->vkUnmapMemory(dev, m_bufMem); p = nullptr; diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index 7961dd7f99..d4580d8485 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -1,94 +1,93 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2022 Cacodemon345 -** Copyright (C) 2017 The Qt Company Ltd. -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -****************************************************************************/ - -#include -#include - -#if QT_CONFIG(vulkan) -# include "qt_vulkanwindowrenderer.hpp" - -class VulkanRenderer2 : public QVulkanWindowRenderer { -public: - void *mappedPtr = nullptr; - size_t imagePitch = 2048 * 4; - VulkanRenderer2(QVulkanWindow *w); - - void initResources() override; - void initSwapChainResources() override; - void releaseSwapChainResources() override; - void releaseResources() override; - - void startNextFrame() override; - -private: - VkShaderModule createShader(const QString &name); - bool createTexture(); - bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); - bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); - void ensureTexture(); - void updateSamplers(); - - QVulkanWindow *m_window; - QVulkanDeviceFunctions *m_devFuncs; - - VkDeviceMemory m_bufMem = VK_NULL_HANDLE; - VkBuffer m_buf = VK_NULL_HANDLE; - VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - - VkDescriptorPool m_descPool = VK_NULL_HANDLE; - VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; - VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - - VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; - VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; - VkPipeline m_pipeline = VK_NULL_HANDLE; - - VkSampler m_sampler = VK_NULL_HANDLE; - VkSampler m_linearSampler = VK_NULL_HANDLE; - VkImage m_texImage = VK_NULL_HANDLE; - VkDeviceMemory m_texMem = VK_NULL_HANDLE; - bool m_texLayoutPending = false; - VkImageView m_texView = VK_NULL_HANDLE; - VkImage m_texStaging = VK_NULL_HANDLE; - VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; - bool m_texStagingPending = false; - bool m_texStagingTransferLayout = false; - QSize m_texSize; - VkFormat m_texFormat; - - QMatrix4x4 m_proj; - float m_rotation = 0.0f; -}; -#endif +#pragma once +/**************************************************************************** +** +** Copyright (C) 2022 Cacodemon345 +** Copyright (C) 2017 The Qt Company Ltd. +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +#include +#include + +#if QT_CONFIG(vulkan) +# include "qt_vulkanwindowrenderer.hpp" + +class VulkanRenderer2 : public QVulkanWindowRenderer { +public: + void *mappedPtr = nullptr; + size_t imagePitch = 2048 * 4; + VulkanRenderer2(QVulkanWindow *w); + + void initResources() override; + void initSwapChainResources() override; + void releaseSwapChainResources() override; + void releaseResources() override; + + void startNextFrame() override; + +private: + VkShaderModule createShader(const QString &name); + bool createTexture(); + bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); + bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); + void ensureTexture(); + void updateSamplers(); + + QVulkanWindow *m_window; + QVulkanDeviceFunctions *m_devFuncs; + + VkDeviceMemory m_bufMem = VK_NULL_HANDLE; + VkBuffer m_buf = VK_NULL_HANDLE; + VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + + VkDescriptorPool m_descPool = VK_NULL_HANDLE; + VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; + VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + + VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; + VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + VkPipeline m_pipeline = VK_NULL_HANDLE; + + VkSampler m_sampler = VK_NULL_HANDLE; + VkSampler m_linearSampler = VK_NULL_HANDLE; + VkImage m_texImage = VK_NULL_HANDLE; + VkDeviceMemory m_texMem = VK_NULL_HANDLE; + bool m_texLayoutPending = false; + VkImageView m_texView = VK_NULL_HANDLE; + VkImage m_texStaging = VK_NULL_HANDLE; + VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; + bool m_texStagingPending = false; + bool m_texStagingTransferLayout = false; + QSize m_texSize; + VkFormat m_texFormat; + + QMatrix4x4 m_proj; +}; +#endif diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index bac049391b..3ca091ae64 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -35,6 +35,8 @@ #include +#include + #include #include <86box/keyboard.h> @@ -51,17 +53,15 @@ extern "C" void win_joystick_handle(PRAWINPUT); std::unique_ptr WindowsRawInputFilter::Register(MainWindow *window) { - HWND wnd = (HWND) window->winId(); - RAWINPUTDEVICE rid[2] = { {.usUsagePage = 0x01, .usUsage = 0x06, .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = wnd}, + .hwndTarget = nullptr}, { .usUsagePage = 0x01, .usUsage = 0x02, .dwFlags = 0, - .hwndTarget = wnd} + .hwndTarget = nullptr} }; if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) @@ -172,9 +172,6 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0; - static int recv_ralt = 0; - static int recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -183,7 +180,18 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) return; /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { + if ((rawKB.Flags & RI_KEY_E1)) { + if (rawKB.MakeCode == 0x1D) { + scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + } else + scancode = 0xFFFF; + if (scancode != 0xFFFF) + keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + } else { if (rawKB.Flags & RI_KEY_E0) scancode |= 0x100; @@ -196,68 +204,22 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) scancode = scancode_map[scancode]; /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00f); - recv_tab = 0; - } else { - switch (scancode) { - case 0x00f: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; - } + keyboard. + We use scan code 0xFFFF to mean a mapping that + has a prefix other than E0 and that is not E1 1D, + which is, for our purposes, invalid. */ - /* Translate right CTRL to left ALT if the user has so + /* Translate right CTRL to left ALT if the user has so chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; + if ((scancode == 0x11d) && rctrl_is_lalt) + scancode = 0x038; - /* Normal scan code pass through, pass it through as is if + /* Normal scan code pass through, pass it through as is if it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } - } else { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + + window->checkFullscreenHotkey(); } } @@ -336,85 +298,71 @@ void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) { RAWMOUSE state = raw->data.mouse; - static int x; - static int y; + static int x, delta_x; + static int y, delta_y; + static int b, delta_z; + + b = mouse_get_buttons_ex(); /* read mouse buttons and wheel */ if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - buttons |= 1; + b |= 1; else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - buttons &= ~1; + b &= ~1; if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - buttons |= 4; + b |= 4; else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - buttons &= ~4; + b &= ~4; if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - buttons |= 2; + b |= 2; else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - buttons &= ~2; + b &= ~2; if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - buttons |= 8; + b |= 8; else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - buttons &= ~8; + b &= ~8; if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - buttons |= 16; + b |= 16; else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - buttons &= ~16; - + b &= ~16; + + mouse_set_buttons_ex(b); + if (state.usButtonFlags & RI_MOUSE_WHEEL) { - dwheel += (SHORT) state.usButtonData / 120; - } + delta_z = (SHORT) state.usButtonData / 120; + mouse_set_z(delta_z); + } else + delta_z = 0; if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { /* absolute mouse, i.e. RDP or VNC * seems to work fine for RDP on Windows 10 * Not sure about other environments. */ - dx += (state.lLastX - x) / 25; - dy += (state.lLastY - y) / 25; + delta_x = (state.lLastX - x) / 25; + delta_y = (state.lLastY - y) / 25; x = state.lLastX; y = state.lLastY; } else { /* relative mouse, i.e. regular mouse */ - dx += state.lLastX; - dy += state.lLastY; + delta_x = state.lLastX; + delta_y = state.lLastY; } - HWND wnd = (HWND) window->winId(); + + mouse_scale(delta_x, delta_y); + + HWND wnd = (HWND)window->winId(); RECT rect; GetWindowRect(wnd, &rect); int left = rect.left + (rect.right - rect.left) / 2; - int top = rect.top + (rect.bottom - rect.top) / 2; + int top = rect.top + (rect.bottom - rect.top) / 2; SetCursorPos(left, top); } - -void -WindowsRawInputFilter::mousePoll() -{ - if (mouse_mode >= 1) return; - if (mouse_capture || video_fullscreen) { - static int b = 0; - - if (dx != 0 || dy != 0 || dwheel != 0) { - mouse_x += dx; - mouse_y += dy; - mouse_z = dwheel; - - dx = 0; - dy = 0; - dwheel = 0; - } - - if (b != buttons) { - mouse_buttons = buttons; - b = buttons; - } - } -} diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index 81b2c0d483..f687164ca3 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -59,9 +59,6 @@ class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter ~WindowsRawInputFilter(); -public slots: - void mousePoll(); - private: MainWindow *window; uint16_t scancode_map[768]; diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index bc540fcf61..4437bb6969 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -36,20 +36,20 @@ joystick_init() int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); - plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); + plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); + plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); - for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { - sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); + for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { + snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { - sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); + for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) { + snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d); plat_joystick_state[c].button[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { - sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); + for (d = 0; d < plat_joystick_state[c].nr_povs; d++) { + snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d); plat_joystick_state[c].pov[d].id = d; } } @@ -116,17 +116,13 @@ joystick_process() for (c = 0; c < joysticks_present; c++) { int b; - plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); - plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); - plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); - plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); - plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); - plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + for (b = 0; b < plat_joystick_state[c].nr_axes; b++) + plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b); - for (b = 0; b < 16; b++) + for (b = 0; b < plat_joystick_state[c].nr_buttons; b++) plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); - for (b = 0; b < 4; b++) + for (b = 0; b < plat_joystick_state[c].nr_povs; b++) plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index e5d4772966..bb05c3f5c6 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -10,13 +10,13 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * GH Cao, + * Jasmine Iwanek, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. * Copyright 2020 GH Cao. + * Copyright 2021-2023 Jasmine Iwanek. */ #include #include @@ -35,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -65,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -85,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -98,9 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - LONG center; - - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -122,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -139,20 +196,17 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS * Some joysticks will send -1 in LogicalMax, like Xbox Controllers * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1ULL << prop->BitSize) - 1); } rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - center = (rawjoy->axis[joy->nr_axes].max - rawjoy->axis[joy->nr_axes].min + 1) / 2; - - if (center != 0x00) - joy->nr_axes++; + joy->nr_axes++; } void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); @@ -372,10 +426,10 @@ win_joystick_handle(PRAWINPUT raw) /* Read axes */ for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; + const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -400,14 +454,16 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; + const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -420,9 +476,13 @@ win_joystick_handle(PRAWINPUT raw) plat_joystick_state[j].p[p] = value; - // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#if 0 + joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#endif } - // joystick_log("\n"); +#if 0 + joystick_log("\n"); +#endif } static int @@ -450,7 +510,7 @@ joystick_process(void) { int d; - if (joystick_type == 7) + if (joystick_type == JS_TYPE_NONE) return; for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp index 789712de55..5d6d95a0a4 100644 --- a/src/qt/wl_mouse.cpp +++ b/src/qt/wl_mouse.cpp @@ -26,6 +26,7 @@ #include extern "C" { +#include <86box/mouse.h> #include <86box/plat.h> } @@ -34,28 +35,12 @@ static zwp_relative_pointer_v1 *rel_pointer = nullptr; static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr; static zwp_locked_pointer_v1 *conf_pointer = nullptr; -static int rel_mouse_x = 0; -static int rel_mouse_y = 0; static bool wl_init_ok = false; void rel_mouse_event(void *data, zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) { - rel_mouse_x += wl_fixed_to_int(dx_real); - rel_mouse_y += wl_fixed_to_int(dy_real); -} - -extern "C" { -extern int mouse_x, mouse_y; -} - -void -wl_mouse_poll() -{ - mouse_x = rel_mouse_x; - mouse_y = rel_mouse_y; - rel_mouse_x = 0; - rel_mouse_y = 0; + mouse_scale(wl_fixed_to_int(dx_real), wl_fixed_to_int(dy_real)); } static struct zwp_relative_pointer_v1_listener rel_listener = { diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp index 25d4de66c5..e1751fd82c 100644 --- a/src/qt/wl_mouse.hpp +++ b/src/qt/wl_mouse.hpp @@ -1,5 +1,4 @@ class QWindow; void wl_mouse_capture(QWindow *window); void wl_mouse_uncapture(); -void wl_mouse_poll(); void wl_init(); diff --git a/src/qt/x11_util.c b/src/qt/x11_util.c new file mode 100644 index 0000000000..e550331724 --- /dev/null +++ b/src/qt/x11_util.c @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "x11_util.h" + +void set_wm_class(unsigned long window, char *res_name) { + Display* display = XOpenDisplay(NULL); + if (display == NULL) { + return; + } + + XClassHint hint; + XGetClassHint(display, window, &hint); + + hint.res_name = res_name; + XSetClassHint(display, window, &hint); + + // During testing, I've had to issue XGetClassHint after XSetClassHint + // to get the window manager to recognize the change. + XGetClassHint(display, window, &hint); +} diff --git a/src/qt/x11_util.h b/src/qt/x11_util.h new file mode 100644 index 0000000000..f06db94197 --- /dev/null +++ b/src/qt/x11_util.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void set_wm_class(unsigned long window, char *res_name); + +#ifdef __cplusplus +} +#endif diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index dafa4ffdaa..1be6ec8261 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -48,7 +48,7 @@ static Display *disp = nullptr; static QThread *procThread = nullptr; static XIEventMask ximask; static std::atomic exitfromthread = false; -static std::atomic xi2_mouse_x = 0, xi2_mouse_y = 0, xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; +static std::atomic xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; static int xi2opcode = 0; static double prev_coords[2] = { 0.0 }; static Time prev_time = 0; @@ -168,9 +168,9 @@ xinput2_proc() if ((v->mode == XIModeRelative) && (rawev->sourceid != xtest_pointer)) { /* Set relative coordinates. */ if (axis == 0) - xi2_mouse_x = xi2_mouse_x + coords[axis]; + mouse_scale_x(coords[axis]); else - xi2_mouse_y = xi2_mouse_y + coords[axis]; + mouse_scale_y(coords[axis]); } else { /* Convert absolute value range to pixel granularity, then to relative coordinates. */ int disp_screen = XDefaultScreen(disp); @@ -188,7 +188,7 @@ xinput2_proc() } if (xi2_mouse_abs_x != 0) - xi2_mouse_x = xi2_mouse_x + (abs_div - xi2_mouse_abs_x); + mouse_scale_x(abs_div - xi2_mouse_abs_x); xi2_mouse_abs_x = abs_div; } else { if (v->mode == XIModeRelative) { @@ -202,7 +202,7 @@ xinput2_proc() } if (xi2_mouse_abs_y != 0) - xi2_mouse_y = xi2_mouse_y + (abs_div - xi2_mouse_abs_y); + mouse_scale_y(abs_div - xi2_mouse_abs_y); xi2_mouse_abs_y = abs_div; } } @@ -273,14 +273,3 @@ xinput2_init() } } } - -void -xinput2_poll() -{ - if (procThread && mouse_capture) { - mouse_x = xi2_mouse_x; - mouse_y = xi2_mouse_y; - } - xi2_mouse_x = 0; - xi2_mouse_y = 0; -} diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index e2e51e7cfe..9695522295 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -58,6 +58,7 @@ static std::unordered_map xkb_keycodes = { {"LNFD", 0x1c}, /* linefeed => Enter */ {"LCTL", 0x1d}, + {"CTRL", 0x1d}, {"AC01", 0x1e}, {"AC02", 0x1f}, {"AC03", 0x20}, @@ -71,8 +72,10 @@ static std::unordered_map xkb_keycodes = { {"AC11", 0x28}, {"TLDE", 0x29}, + {"AE00", 0x29}, /* alias of TLDE on keycodes/xfree86 (i.e. X11 forwarding) */ {"LFSH", 0x2a}, {"BKSL", 0x2b}, + {"AC12", 0x2b}, {"AB01", 0x2c}, {"AB02", 0x2d}, {"AB03", 0x2e}, @@ -87,6 +90,7 @@ static std::unordered_map xkb_keycodes = { {"KPMU", 0x37}, {"LALT", 0x38}, + {"ALT", 0x38}, {"SPCE", 0x39}, {"CAPS", 0x3a}, {"FK01", 0x3b}, @@ -168,7 +172,9 @@ static std::unordered_map xkb_keycodes = { {"DELE", 0x153}, {"LWIN", 0x15b}, + {"WIN", 0x15b}, {"LMTA", 0x15b}, + {"META", 0x15b}, {"RWIN", 0x15c}, {"RMTA", 0x15c}, {"MENU", 0x15d}, diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 1f1e6eafdf..94c9048ef5 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -42,7 +42,8 @@ #include <86box/scsi_pcscsi.h> #include <86box/scsi_spock.h> -int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 }; +int scsi_card_current[SCSI_BUS_MAX] = { 0, 0, 0, 0 }; +double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 }; static uint8_t next_scsi_bus = 0; @@ -84,8 +85,9 @@ static SCSI_CARD scsi_cards[] = { { &scsi_t130b_device, }, { &aha1640_device, }, { &buslogic_640a_device, }, - { &ncr53c90_mca_device, }, + { &ncr53c90a_mca_device, }, { &spock_device, }, + { &tribble_device, }, { &buslogic_958d_pci_device, }, { &ncr53c810_pci_device, }, { &ncr53c815_pci_device, }, @@ -143,7 +145,7 @@ scsi_card_has_config(int card) return (device_has_config(scsi_cards[card].device) ? 1 : 0); } -char * +const char * scsi_card_get_internal_name(int card) { return device_get_internal_name(scsi_cards[card].device); @@ -155,7 +157,7 @@ scsi_card_get_from_internal_name(char *s) int c = 0; while (scsi_cards[c].device != NULL) { - if (!strcmp((char *) scsi_cards[c].device->internal_name, s)) + if (!strcmp(scsi_cards[c].device->internal_name, s)) return c; c++; } @@ -177,10 +179,20 @@ scsi_card_init(void) bus left. */ if (max > 0) { for (int i = 0; i < max; i++) { - if (!scsi_cards[scsi_card_current[i]].device) - continue; - - device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); + if ((scsi_card_current[i] > 0) && scsi_cards[scsi_card_current[i]].device) + device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); } } } + +void +scsi_bus_set_speed(uint8_t bus, double speed) +{ + scsi_bus_speed[bus] = speed; +} + +double +scsi_bus_get_speed(uint8_t bus) +{ + return scsi_bus_speed[bus]; +} diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 3cfe72760c..05b8b27264 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -71,13 +71,13 @@ uint16_t aha_ports[] = { static uint8_t *aha1542cp_pnp_rom = NULL; #pragma pack(push, 1) -typedef struct { - uint8_t CustomerSignature[20]; - uint8_t uAutoRetry; - uint8_t uBoardSwitches; - uint8_t uChecksum; - uint8_t uUnknown; - addr24 BIOSMailboxAddress; +typedef struct aha_setup_t { + uint8_t CustomerSignature[20]; + uint8_t uAutoRetry; + uint8_t uBoardSwitches; + uint8_t uChecksum; + uint8_t uUnknown; + addr24_t BIOSMailboxAddress; } aha_setup_t; #pragma pack(pop) @@ -123,8 +123,8 @@ aha_mem_write(uint32_t addr, uint8_t val, void *priv) static uint8_t aha_mem_read(uint32_t addr, void *priv) { - x54x_t *dev = (x54x_t *) priv; - rom_t *rom = &dev->bios; + const x54x_t *dev = (x54x_t *) priv; + const rom_t *rom = &dev->bios; addr &= 0x3fff; @@ -152,18 +152,18 @@ aha154x_shram(x54x_t *dev, uint8_t cmd) static void aha_eeprom_save(x54x_t *dev) { - FILE *f; + FILE *fp; - f = nvr_fopen(dev->nvr_path, "wb"); - if (f) { - fwrite(dev->nvr, 1, NVR_SIZE, f); - fclose(f); - f = NULL; + fp = nvr_fopen(dev->nvr_path, "wb"); + if (fp) { + fwrite(dev->nvr, 1, NVR_SIZE, fp); + fclose(fp); + fp = NULL; } } static uint8_t -aha154x_eeprom(x54x_t *dev, uint8_t cmd, uint8_t arg, uint8_t len, uint8_t off, uint8_t *bufp) +aha154x_eeprom(x54x_t *dev, uint8_t cmd, UNUSED(uint8_t arg), uint8_t len, uint8_t off, uint8_t *bufp) { uint8_t r = 0xff; int c; @@ -217,39 +217,42 @@ aha154x_mmap(x54x_t *dev, uint8_t cmd) /* Enable the mapper, so, set ROM2 active. */ dev->bios.rom = dev->rom2; break; + + default: + break; } return 0; } static uint8_t -aha_get_host_id(void *p) +aha_get_host_id(void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; return dev->nvr[0] & 0x07; } static uint8_t -aha_get_irq(void *p) +aha_get_irq(void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; return (dev->nvr[1] & 0x07) + 9; } static uint8_t -aha_get_dma(void *p) +aha_get_dma(void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; return (dev->nvr[1] >> 4) & 0x07; } static uint8_t -aha_cmd_is_fast(void *p) +aha_cmd_is_fast(void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; if (dev->Command == CMD_BIOS_SCSI) return 1; @@ -258,9 +261,9 @@ aha_cmd_is_fast(void *p) } static uint8_t -aha_fast_cmds(void *p, uint8_t cmd) +aha_fast_cmds(void *priv, uint8_t cmd) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; if (cmd == CMD_BIOS_SCSI) { dev->BIOSMailboxReq++; @@ -271,23 +274,20 @@ aha_fast_cmds(void *p, uint8_t cmd) } static uint8_t -aha_param_len(void *p) +aha_param_len(void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; switch (dev->Command) { case CMD_BIOS_MBINIT: /* Same as 0x01 for AHA. */ return sizeof(MailboxInit_t); - break; case CMD_SHADOW_RAM: return 1; - break; case CMD_WRITE_EEPROM: return 35; - break; case CMD_READ_EEPROM: return 3; @@ -307,10 +307,10 @@ aha_param_len(void *p) } static uint8_t -aha_cmds(void *p) +aha_cmds(void *priv) { - x54x_t *dev = (x54x_t *) p; - MailboxInit_t *mbi; + x54x_t *dev = (x54x_t *) priv; + const MailboxInit_t *mbi; if (!dev->CmdParamLeft) { aha_log("Running Operation Code 0x%02X\n", dev->Command); @@ -351,7 +351,9 @@ aha_cmds(void *p) * and expects a 0x04 back in the INTR * register. --FvK */ - /* dev->Interrupt = aha154x_shram(dev,val); */ +#if 0 + dev->Interrupt = aha154x_shram(dev,val); +#endif dev->Interrupt = aha154x_shram(dev, dev->CmdBuf[0]); break; @@ -451,9 +453,9 @@ aha_cmds(void *p) } static void -aha_setup_data(void *p) +aha_setup_data(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; ReplyInquireSetupInformation *ReplyISI; aha_setup_t *aha_setup; @@ -486,9 +488,9 @@ aha_do_bios_mail(x54x_t *dev) } static void -aha_callback(void *p) +aha_callback(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; if (dev->BIOSMailboxInit && dev->BIOSMailboxReq) aha_do_bios_mail(dev); @@ -497,7 +499,7 @@ aha_callback(void *p) static uint8_t aha_mca_read(int port, void *priv) { - x54x_t *dev = (x54x_t *) priv; + const x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[port & 7]); } @@ -551,6 +553,9 @@ aha_mca_write(int port, uint8_t val, void *priv) case 0x10: /* [1]=xx01 0xxx */ dev->rom_addr = 0xC8000; break; + + default: + break; } else { /* Disabled. */ @@ -606,7 +611,7 @@ aha_mca_write(int port, uint8_t val, void *priv) static uint8_t aha_mca_feedb(void *priv) { - x54x_t *dev = (x54x_t *) priv; + const x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[2] & 0x01); } @@ -696,6 +701,8 @@ aha_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) break; #endif + default: + break; } } @@ -706,7 +713,7 @@ aha_setbios(x54x_t *dev) uint32_t size; uint32_t mask; uint32_t temp; - FILE *f; + FILE *fp; int i; /* Only if this device has a BIOS ROM. */ @@ -715,7 +722,7 @@ aha_setbios(x54x_t *dev) /* Open the BIOS image file and make sure it exists. */ aha_log("%s: loading BIOS from '%s'\n", dev->name, dev->bios_path); - if ((f = rom_fopen(dev->bios_path, "rb")) == NULL) { + if ((fp = rom_fopen(dev->bios_path, "rb")) == NULL) { aha_log("%s: BIOS ROM not found!\n", dev->name); return; } @@ -727,17 +734,17 @@ aha_setbios(x54x_t *dev) * this special case, we can't: we may need WRITE access to the * memory later on. */ - (void) fseek(f, 0L, SEEK_END); - temp = ftell(f); - (void) fseek(f, 0L, SEEK_SET); + (void) fseek(fp, 0L, SEEK_END); + temp = ftell(fp); + (void) fseek(fp, 0L, SEEK_SET); /* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */ dev->rom1 = malloc(ROM_SIZE); - (void) !fread(dev->rom1, ROM_SIZE, 1, f); + (void) !fread(dev->rom1, ROM_SIZE, 1, fp); temp -= ROM_SIZE; if (temp > 0) { dev->rom2 = malloc(ROM_SIZE); - (void) !fread(dev->rom2, ROM_SIZE, 1, f); + (void) !fread(dev->rom2, ROM_SIZE, 1, fp); temp -= ROM_SIZE; } else { dev->rom2 = NULL; @@ -747,13 +754,13 @@ aha_setbios(x54x_t *dev) free(dev->rom1); if (dev->rom2 != NULL) free(dev->rom2); - (void) fclose(f); + (void) fclose(fp); return; } - temp = ftell(f); + temp = ftell(fp); if (temp > ROM_SIZE) temp = ROM_SIZE; - (void) fclose(f); + (void) fclose(fp); /* Adjust BIOS size in chunks of 2K, as per BIOS spec. */ size = 0x10000; @@ -814,7 +821,7 @@ static void aha_setmcode(x54x_t *dev) { uint32_t temp; - FILE *f; + FILE *fp; /* Only if this device has a BIOS ROM. */ if (dev->mcode_path == NULL) @@ -822,7 +829,7 @@ aha_setmcode(x54x_t *dev) /* Open the microcode image file and make sure it exists. */ aha_log("%s: loading microcode from '%ls'\n", dev->name, dev->bios_path); - if ((f = rom_fopen(dev->mcode_path, "rb")) == NULL) { + if ((fp = rom_fopen(dev->mcode_path, "rb")) == NULL) { aha_log("%s: microcode ROM not found!\n", dev->name); return; } @@ -834,13 +841,13 @@ aha_setmcode(x54x_t *dev) * this special case, we can't: we may need WRITE access to the * memory later on. */ - (void) fseek(f, 0L, SEEK_END); - temp = ftell(f); - (void) fseek(f, 0L, SEEK_SET); + (void) fseek(fp, 0L, SEEK_END); + temp = ftell(fp); + (void) fseek(fp, 0L, SEEK_SET); if (temp < (dev->cmd_33_offset + dev->cmd_33_len - 1)) { aha_log("%s: microcode ROM size invalid!\n", dev->name); - (void) fclose(f); + (void) fclose(fp); return; } @@ -850,11 +857,11 @@ aha_setmcode(x54x_t *dev) aha1542cp_pnp_rom = NULL; } aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7); - fseek(f, dev->pnp_offset, SEEK_SET); - (void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, f); + fseek(fp, dev->pnp_offset, SEEK_SET); + (void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, fp); memset(&(aha1542cp_pnp_rom[4]), 0x00, 5); - fseek(f, dev->pnp_offset + 4, SEEK_SET); - (void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, f); + fseek(fp, dev->pnp_offset + 4, SEEK_SET); + (void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, fp); /* Even the real AHA-1542CP microcode seem to be flipping bit 4 to not erroneously indicate there is a range length. */ aha1542cp_pnp_rom[0x87] |= 0x04; @@ -864,10 +871,10 @@ aha_setmcode(x54x_t *dev) aha1542cp_pnp_rom[dev->pnp_len + 6] = 0x00; /* Load the SCSISelect decompression code. */ - fseek(f, dev->cmd_33_offset, SEEK_SET); - (void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, f); + fseek(fp, dev->cmd_33_offset, SEEK_SET); + (void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, fp); - (void) fclose(f); + (void) fclose(fp); } static void @@ -892,7 +899,7 @@ aha_initnvr(x54x_t *dev) static void aha_setnvr(x54x_t *dev) { - FILE *f; + FILE *fp; /* Only if this device has an EEPROM. */ if (dev->nvr_path == NULL) @@ -902,12 +909,12 @@ aha_setnvr(x54x_t *dev) dev->nvr = (uint8_t *) malloc(NVR_SIZE); memset(dev->nvr, 0x00, NVR_SIZE); - f = nvr_fopen(dev->nvr_path, "rb"); - if (f) { - if (fread(dev->nvr, 1, NVR_SIZE, f) != NVR_SIZE) + fp = nvr_fopen(dev->nvr_path, "rb"); + if (fp) { + if (fread(dev->nvr, 1, NVR_SIZE, fp) != NVR_SIZE) fatal("aha_setnvr(): Error reading data\n"); - fclose(f); - f = NULL; + fclose(fp); + fp = NULL; } else aha_initnvr(dev); @@ -997,6 +1004,9 @@ aha_init(const device_t *info) case 0x0334: dev->bios_path = "roms/scsi/adaptec/aha1540b320_334.bin"; break; + + default: + break; } dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ @@ -1015,6 +1025,7 @@ aha_init(const device_t *info) dev->rom_shramsz = 128; /* size of shadow RAM */ dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ + dev->flags |= X54X_HAS_SIGNATURE; dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ @@ -1031,6 +1042,7 @@ aha_init(const device_t *info) dev->rom_ioaddr = 0x3F7E; /* [2:0] idx into addr table */ dev->rom_fwhigh = 0x0022; /* firmware version (hi/lo) */ dev->flags |= X54X_CDROM_BOOT; + dev->flags |= X54X_HAS_SIGNATURE; dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ @@ -1051,6 +1063,7 @@ aha_init(const device_t *info) dev->rom_fwhigh = 0x0055; /* firmware version (hi/lo) */ dev->flags |= X54X_CDROM_BOOT; dev->flags |= X54X_ISAPNP; + dev->flags |= X54X_HAS_SIGNATURE; dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ @@ -1075,6 +1088,7 @@ aha_init(const device_t *info) dev->fw_rev = "BB01"; dev->flags |= X54X_LBA_BIOS; + dev->flags |= X54X_HAS_SIGNATURE; /*To be confirmed*/ /* Enable MCA. */ dev->pos_regs[0] = 0x1F; /* MCA board ID */ @@ -1082,8 +1096,13 @@ aha_init(const device_t *info) mca_add(aha_mca_read, aha_mca_write, aha_mca_feedb, NULL, dev); dev->ha_bps = 5000000.0; /* normal SCSI */ break; + + default: + break; } + scsi_bus_set_speed(dev->bus, dev->ha_bps); + /* Initialize ROM BIOS if needed. */ aha_setbios(dev); @@ -1106,7 +1125,7 @@ aha_init(const device_t *info) } } - return (dev); + return dev; } // clang-format off diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index efc2a62ae6..ac3b464a8a 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -53,20 +53,20 @@ * configuration parameters. */ #pragma pack(push, 1) -typedef struct { - uint8_t aInternalSignature[2]; - uint8_t cbInformation; - uint8_t aHostAdaptertype[6]; - uint8_t uReserved1; - uint8_t fFloppyEnabled : 1, - fFloppySecondary : 1, - fLevelSensitiveInterrupt : 1, - uReserved2 : 2, - uSystemRAMAreForBIOS : 3; - uint8_t uDMAChannel : 7, - fDMAAutoConfiguration : 1, - uIrqChannel : 7, - fIrqAutoConfiguration : 1; +typedef struct AutoSCSIRam_t { + uint8_t aInternalSignature[2]; + uint8_t cbInformation; + uint8_t aHostAdaptertype[6]; + uint8_t uReserved1; + uint8_t fFloppyEnabled : 1; + uint8_t fFloppySecondary : 1; + uint8_t fLevelSensitiveInterrupt : 1; + uint8_t uReserved2 : 2; + uint8_t uSystemRAMAreForBIOS : 3; + uint8_t uDMAChannel : 7; + uint8_t fDMAAutoConfiguration : 1; + uint8_t uIrqChannel : 7; + uint8_t fIrqAutoConfiguration : 1; uint8_t uDMATransferRate; uint8_t uSCSIId; uint8_t uSCSIConfiguration; @@ -142,46 +142,45 @@ typedef struct { /* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ #pragma pack(push, 1) -typedef struct { +typedef struct ReplyInquireExtendedSetupInformation_t { uint8_t uBusType; uint8_t uBiosAddress; uint16_t u16ScatterGatherLimit; uint8_t cMailbox; uint32_t uMailboxAddressBase; - uint8_t uReserved1 : 2, - fFastEISA : 1, - uReserved2 : 3, - fLevelSensitiveInterrupt : 1, - uReserved3 : 1; + uint8_t uReserved1 : 2; + uint8_t fFastEISA : 1; + uint8_t uReserved2 : 3; + uint8_t fLevelSensitiveInterrupt : 1; + uint8_t uReserved3 : 1; uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI : 1, - fHostDifferentialSCSI : 1, - fHostSupportsSCAM : 1, - fHostUltraSCSI : 1, - fHostSmartTermination : 1, - uReserved4 : 3; + uint8_t fHostWideSCSI : 1; + uint8_t fHostDifferentialSCSI : 1; + uint8_t fHostSupportsSCAM : 1; + uint8_t fHostUltraSCSI : 1; + uint8_t fHostSmartTermination : 1; + uint8_t uReserved4 : 3; } ReplyInquireExtendedSetupInformation; #pragma pack(pop) /* Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ #pragma pack(push, 1) -typedef struct { +typedef struct BuslogicPCIInformation_t { uint8_t IsaIOPort; uint8_t IRQ; - uint8_t LowByteTerminated : 1, - HighByteTerminated : 1, - uReserved : 2, /* Reserved. */ - JP1 : 1, /* Whatever that means. */ - JP2 : 1, /* Whatever that means. */ - JP3 : 1, /* Whatever that means. */ - InformationIsValid : 1; - uint8_t uReserved2; /* Reserved. */ + uint8_t LowByteTerminated : 1; + uint8_t HighByteTerminated : 1; + uint8_t uReserved : 2; /* Reserved. */ + uint8_t JP1 : 1; /* Whatever that means. */ + uint8_t JP2 : 1; /* Whatever that means. */ + uint8_t JP3 : 1; /* Whatever that means. */ + uint8_t InformationIsValid : 1; + uint8_t uReserved2; /* Reserved. */ } BuslogicPCIInformation_t; #pragma pack(pop) #pragma pack(push, 1) -typedef struct -{ +typedef struct ESCMD_t { /** Data length. */ uint32_t DataLength; /** Data pointer. */ @@ -204,14 +203,14 @@ typedef struct #pragma pack(pop) #pragma pack(push, 1) -typedef struct { +typedef struct MailboxInitExtended_t { uint8_t Count; uint32_t Address; } MailboxInitExtended_t; #pragma pack(pop) #pragma pack(push, 1) -typedef struct { +typedef struct buslogic_data_t { rom_t bios; int ExtendedLUNCCBFormat; int fAggressiveRoundRobinMode; @@ -220,11 +219,11 @@ typedef struct { int MMIOBase; int chip; int has_bios; - uint32_t bios_addr, - bios_size, - bios_mask; - uint8_t AutoSCSIROM[32768]; - uint8_t SCAMData[65536]; + uint32_t bios_addr; + uint32_t bios_size; + uint32_t bios_mask; + uint8_t AutoSCSIROM[32768]; + uint8_t SCAMData[65536]; } buslogic_data_t; #pragma pack(pop) @@ -325,6 +324,9 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) case CHIP_BUSLOGIC_PCI_958D_1995_12_30: memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4); break; + + default: + break; } HALR->structured.autoSCSIData.fLevelSensitiveInterrupt = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; @@ -407,17 +409,17 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) static void BuslogicInitializeAutoSCSIRam(x54x_t *dev) { - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + const HALocalRAM *HALR = &bl->LocalRAM; - FILE *f; + FILE *fp; - f = nvr_fopen(BuslogicGetNVRFileName(bl), "rb"); - if (f) { - if (fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f) != 64) + fp = nvr_fopen(BuslogicGetNVRFileName(bl), "rb"); + if (fp) { + if (fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, fp) != 64) fatal("BuslogicInitializeAutoSCSIRam(): Error reading data\n"); - fclose(f); - f = NULL; + fclose(fp); + fp = NULL; if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { x54x_io_remove(dev, dev->Base, 4); switch (HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { @@ -439,9 +441,9 @@ BuslogicInitializeAutoSCSIRam(x54x_t *dev) } static void -buslogic_cmd_phase1(void *p) +buslogic_cmd_phase1(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; if ((dev->CmdParam == 2) && (dev->Command == 0x90)) { dev->CmdParamLeft = dev->CmdBuf[1]; @@ -463,12 +465,12 @@ buslogic_cmd_phase1(void *p) } static uint8_t -buslogic_get_host_id(void *p) +buslogic_get_host_id(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + const HALocalRAM *HALR = &bl->LocalRAM; if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) return dev->HostID; @@ -477,14 +479,14 @@ buslogic_get_host_id(void *p) } static uint8_t -buslogic_get_irq(void *p) +buslogic_get_irq(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t bl_irq[7] = { 0, 9, 10, 11, 12, 14, 15 }; - HALocalRAM *HALR = &bl->LocalRAM; + const HALocalRAM *HALR = &bl->LocalRAM; if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) return dev->Irq; @@ -493,14 +495,14 @@ buslogic_get_irq(void *p) } static uint8_t -buslogic_get_dma(void *p) +buslogic_get_dma(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t bl_dma[4] = { 0, 5, 6, 7 }; - HALocalRAM *HALR = &bl->LocalRAM; + const HALocalRAM *HALR = &bl->LocalRAM; if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) return (dev->Base ? 7 : 0); @@ -511,10 +513,10 @@ buslogic_get_dma(void *p) } static uint8_t -buslogic_param_len(void *p) +buslogic_param_len(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; switch (dev->Command) { case 0x21: @@ -577,10 +579,10 @@ BuslogicSCSIBIOSDMATransfer(x54x_t *dev, ESCMD *ESCSICmd, uint8_t TargetID, int if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) { buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address); - dma_bm_read(Address, (uint8_t *) sd->sc->temp_buffer, TransferLength, transfer_size); + dma_bm_read(Address, sd->sc->temp_buffer, TransferLength, transfer_size); } else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) { buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address); - dma_bm_write(Address, (uint8_t *) sd->sc->temp_buffer, TransferLength, transfer_size); + dma_bm_write(Address, sd->sc->temp_buffer, TransferLength, transfer_size); } } } @@ -666,18 +668,18 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u } static uint8_t -buslogic_cmds(void *p) +buslogic_cmds(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + const HALocalRAM *HALR = &bl->LocalRAM; - FILE *f; + FILE *fp; uint16_t TargetsPresentMask = 0; uint32_t Offset; int i = 0; - MailboxInitExtended_t *MailboxInitE; + const MailboxInitExtended_t *MailboxInitE; ReplyInquireExtendedSetupInformation *ReplyIESI; BuslogicPCIInformation_t *ReplyPI; int cCharsToTransfer; @@ -827,6 +829,9 @@ buslogic_cmds(void *p) case CHIP_BUSLOGIC_PCI_958D_1995_12_30: ReplyIESI->uBusType = 'E'; /* PCI style */ break; + + default: + break; } ReplyIESI->uBiosAddress = 0xd8; ReplyIESI->u16ScatterGatherLimit = 8192; @@ -867,6 +872,7 @@ buslogic_cmds(void *p) dev->Status |= STAT_INVCMD; break; } + fallthrough; case 0x92: if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { dev->DataReplyLeft = 0; @@ -885,11 +891,11 @@ buslogic_cmds(void *p) BuslogicAutoSCSIRamSetDefaults(dev, 3); break; case 1: - f = nvr_fopen(BuslogicGetNVRFileName(bl), "wb"); - if (f) { - fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f); - fclose(f); - f = NULL; + fp = nvr_fopen(BuslogicGetNVRFileName(bl), "wb"); + if (fp) { + fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, fp); + fclose(fp); + fp = NULL; } break; default: @@ -1012,13 +1018,13 @@ buslogic_cmds(void *p) } static void -buslogic_setup_data(void *p) +buslogic_setup_data(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; ReplyInquireSetupInformation *ReplyISI; buslogic_setup_t *bl_setup; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - HALocalRAM *HALR = &bl->LocalRAM; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + const HALocalRAM *HALR = &bl->LocalRAM; ReplyISI = (ReplyInquireSetupInformation *) dev->DataBuf; bl_setup = (buslogic_setup_t *) ReplyISI->VendorSpecificData; @@ -1048,14 +1054,17 @@ buslogic_setup_data(void *p) case CHIP_BUSLOGIC_PCI_958D_1995_12_30: bl_setup->uHostBusType = 'F'; break; + + default: + break; } } static uint8_t -buslogic_is_aggressive_mode(void *p) +buslogic_is_aggressive_mode(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; buslogic_log("Buslogic: Aggressive mode = %d\n", bl->fAggressiveRoundRobinMode); @@ -1063,10 +1072,10 @@ buslogic_is_aggressive_mode(void *p) } static uint8_t -buslogic_interrupt_type(void *p) +buslogic_interrupt_type(void *priv) { - x54x_t *dev = (x54x_t *) p; - buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + x54x_t *dev = (x54x_t *) priv; + const buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) return 0; @@ -1075,9 +1084,9 @@ buslogic_interrupt_type(void *p) } static void -buslogic_reset(void *p) +buslogic_reset(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; bl->ExtendedLUNCCBFormat = 0; @@ -1108,9 +1117,9 @@ BuslogicBIOSUpdate(buslogic_data_t *bl) } static uint8_t -BuslogicPCIRead(int func, int addr, void *p) +BuslogicPCIRead(UNUSED(int func), int addr, void *priv) { - x54x_t *dev = (x54x_t *) p; + const x54x_t *dev = (x54x_t *) priv; #ifdef ENABLE_BUSLOGIC_LOG buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; #endif @@ -1175,28 +1184,28 @@ BuslogicPCIRead(int func, int addr, void *p) case 0x31: /* PCI_ROMBAR 15:11 */ buslogic_log("BT-958D: BIOS BAR 01 = %02X\n", (buslogic_pci_bar[2].addr_regs[1] & bl->bios_mask)); return buslogic_pci_bar[2].addr_regs[1]; - break; case 0x32: /* PCI_ROMBAR 23:16 */ buslogic_log("BT-958D: BIOS BAR 02 = %02X\n", buslogic_pci_bar[2].addr_regs[2]); return buslogic_pci_bar[2].addr_regs[2]; - break; case 0x33: /* PCI_ROMBAR 31:24 */ buslogic_log("BT-958D: BIOS BAR 03 = %02X\n", buslogic_pci_bar[2].addr_regs[3]); return buslogic_pci_bar[2].addr_regs[3]; - break; case 0x3C: return dev->Irq; case 0x3D: return PCI_INTA; + + default: + break; } return 0; } static void -BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) +BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; uint8_t valxor; @@ -1224,7 +1233,7 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) case 0x10: val &= 0xe0; val |= 1; - /*FALLTHROUGH*/ + fallthrough; case 0x11: case 0x12: @@ -1248,7 +1257,7 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) case 0x14: val &= 0xe0; - /*FALLTHROUGH*/ + fallthrough; case 0x15: case 0x16: @@ -1259,7 +1268,9 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ buslogic_pci_bar[1].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - // bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; +#if 0 + bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; +#endif /* Give it a 4 kB alignment as that's this emulator's granularity. */ buslogic_pci_bar[1].addr &= 0xffffc000; bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffc000; @@ -1292,6 +1303,9 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } else dev->Irq = 0; return; + + default: + break; } } @@ -1317,7 +1331,7 @@ BuslogicInitializeLocalRAM(buslogic_data_t *bl) static uint8_t buslogic_mca_read(int port, void *priv) { - x54x_t *dev = (x54x_t *) priv; + const x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[port & 7]); } @@ -1386,6 +1400,9 @@ buslogic_mca_write(int port, uint8_t val, void *priv) case 0x20: /* [0]=001x xxxx */ bl->bios_addr = 0xC4000; break; + + default: + break; } else { /* Disabled. */ @@ -1491,15 +1508,15 @@ buslogic_mca_write(int port, uint8_t val, void *priv) static uint8_t buslogic_mca_feedb(void *priv) { - x54x_t *dev = (x54x_t *) priv; + const x54x_t *dev = (x54x_t *) priv; return (dev->pos_regs[2] & 0x01); } void -BuslogicDeviceReset(void *p) +BuslogicDeviceReset(void *priv) { - x54x_t *dev = (x54x_t *) p; + x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; x54x_device_reset(dev); @@ -1512,16 +1529,16 @@ static void * buslogic_init(const device_t *info) { x54x_t *dev; - char *bios_rom_name; - uint16_t bios_rom_size; - uint16_t bios_rom_mask; + const char *bios_rom_name; + uint16_t bios_rom_size = 0; + uint16_t bios_rom_mask = 0; uint8_t has_autoscsi_rom; - char *autoscsi_rom_name; - uint16_t autoscsi_rom_size; + const char *autoscsi_rom_name = NULL; + uint16_t autoscsi_rom_size = 0; uint8_t has_scam_rom; - char *scam_rom_name; - uint16_t scam_rom_size; - FILE *f; + const char *scam_rom_name = NULL; + uint16_t scam_rom_size = 0; + FILE *fp; buslogic_data_t *bl; uint32_t bios_rom_addr; @@ -1684,11 +1701,15 @@ buslogic_init(const device_t *info) dev->ha_bps = 20000000.0; /* ultra SCSI */ dev->max_id = 15; /* wide SCSI */ break; + + default: + break; } - if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) { + scsi_bus_set_speed(dev->bus, dev->ha_bps); + + if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) x54x_io_set(dev, dev->Base, 4); - } memset(bl->AutoSCSIROM, 0xff, 32768); @@ -1702,20 +1723,20 @@ buslogic_init(const device_t *info) rom_init(&bl->bios, bios_rom_name, bios_rom_addr, bios_rom_size, bios_rom_mask, 0, MEM_MAPPING_EXTERNAL); if (has_autoscsi_rom) { - f = rom_fopen(autoscsi_rom_name, "rb"); - if (f) { - (void) !fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f); - fclose(f); - f = NULL; + fp = rom_fopen(autoscsi_rom_name, "rb"); + if (fp) { + (void) !fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, fp); + fclose(fp); + fp = NULL; } } if (has_scam_rom) { - f = rom_fopen(scam_rom_name, "rb"); - if (f) { - (void) !fread(bl->SCAMData, 1, scam_rom_size, f); - fclose(f); - f = NULL; + fp = rom_fopen(scam_rom_name, "rb"); + if (fp) { + (void) !fread(bl->SCAMData, 1, scam_rom_size, fp); + fclose(fp); + fp = NULL; } } } else { @@ -1725,7 +1746,7 @@ buslogic_init(const device_t *info) } if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); + pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev, &dev->pci_slot); buslogic_pci_bar[0].addr_regs[0] = 1; buslogic_pci_bar[1].addr_regs[0] = 0; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index b20a4b4ab3..a6420fb014 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -41,9 +41,10 @@ #include <86box/scsi_cdrom.h> #include <86box/version.h> +#define IDE_ATAPI_IS_EARLY id->sc->pad0 + #pragma pack(push, 1) -typedef struct -{ +typedef struct gesn_cdb_t { uint8_t opcode; uint8_t polled; uint8_t reserved2[2]; @@ -53,8 +54,7 @@ typedef struct uint8_t control; } gesn_cdb_t; -typedef struct -{ +typedef struct gesn_event_header_t { uint16_t len; uint8_t notification_class; uint8_t supported_events; @@ -186,7 +186,7 @@ uint8_t scsi_cdrom_command_flags[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; -static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); +static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_UNIT_ATN_PAGE | GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); static uint64_t scsi_cdrom_mode_sense_page_flags_sony = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE_SONY | GPMODEP_CDROM_AUDIO_PAGE_SONY | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1ULL << 0x02ULL) | (1ULL << 0x0fULL) | GPMODEP_ALL_PAGES); @@ -283,10 +283,10 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { }; static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { - {{ 0, 0 }, + {{ GPMODE_UNIT_ATN_PAGE, 6, 0, 0, 0, 0, 0, 0 }, /*Guess-work*/ { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, + { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -337,7 +337,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_sony_scsi = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CDROM_PAGE_SONY, 2, 1, 0 }, + { GPMODE_CDROM_PAGE_SONY, 2, 0, 5 }, { GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0xE, 5, 0, 0, 0, 0, 0, 1, 255, 2, 255, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -375,10 +375,10 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_sony_scsi = }; static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { - {{ 0, 0 }, + {{ GPMODE_UNIT_ATN_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /*Guess-work*/ { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, - { 0, 0 }, + { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -518,20 +518,22 @@ scsi_cdrom_init(scsi_cdrom_t *dev) dev->drv->bus_mode |= 2; if (dev->drv->bus_type < CDROM_BUS_SCSI) dev->drv->bus_mode |= 1; - scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); + scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", + dev->id, dev->drv->bus_type, dev->drv->bus_mode); dev->sense[0] = 0xf0; dev->sense[7] = 10; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00")) /*NEC only*/ - dev->status = READY_STAT | DSC_STAT; + /* NEC only */ + if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) + dev->tf->status = READY_STAT | DSC_STAT; else - dev->status = 0; - dev->pos = 0; + dev->tf->status = 0; + dev->tf->pos = 0; dev->packet_status = PHASE_NONE; scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; dev->drv->cur_speed = dev->drv->speed; scsi_cdrom_mode_sense_load(dev); - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) scsi_cdrom_drive_status_load(dev); } @@ -543,133 +545,147 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev) return 2; else if (dev->drv->bus_type == CDROM_BUS_ATAPI) { scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id, - (dev->features & 1) ? "DMA" : "PIO", + (dev->tf->features & 1) ? "DMA" : "PIO", dev->id); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev) -{ - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + return (dev->tf->features & 1) ? 2 : 1; } return 0; } static uint32_t -scsi_cdrom_get_channel(void *p, int channel) +scsi_cdrom_get_channel(void *priv, int channel) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) p; + const scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; + uint32_t ret; + if (!dev) return channel + 1; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) - return dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; - else - return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; + break; + default: + ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; + break; + } + + return ret; } static uint32_t -scsi_cdrom_get_volume(void *p, int channel) +scsi_cdrom_get_volume(void *priv, int channel) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) p; + const scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; + uint32_t ret; + if (!dev) return 255; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) - return dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; - else - return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : + GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; + break; + default: + ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; + break; + } + + return ret; } static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) { - FILE *f; + FILE *fp; char file_name[512]; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t)); - memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, sizeof(mode_sense_pages_t)); - - memset(file_name, 0, 512); - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "rb"); - if (f) { - if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, f) != 0x10) - fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); - fclose(f); - } - } else { - memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); - else - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, sizeof(mode_sense_pages_t)); - - memset(file_name, 0, 512); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "rb"); - if (f) { - if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f) != 0x10) - fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); - fclose(f); - } + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, + sizeof(mode_sense_pages_t)); + + memset(file_name, 0, 512); + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); + fp = plat_fopen(nvr_path(file_name), "rb"); + if (fp) { + if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, + 0x10, fp) != 0x10) + fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); + fclose(fp); + } + break; + default: + memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); + if (dev->drv->bus_type == CDROM_BUS_SCSI) + memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, + sizeof(mode_sense_pages_t)); + else + memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, + sizeof(mode_sense_pages_t)); + + memset(file_name, 0, 512); + if (dev->drv->bus_type == CDROM_BUS_SCSI) + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + else + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(file_name), "rb"); + if (fp) { + if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp) != 0x10) + fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); + fclose(fp); + } + break; } } static void scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) { - FILE *f; + FILE *fp; char file_name[512]; memset(file_name, 0, 512); - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "wb"); - if (f) { - fwrite(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, f); - fclose(f); - } - } else { - if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); - f = plat_fopen(nvr_path(file_name), "wb"); - if (f) { - fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); - fclose(f); - } + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); + fp = plat_fopen(nvr_path(file_name), "wb"); + if (fp) { + fwrite(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, fp); + fclose(fp); + } + break; + default: + if (dev->drv->bus_type == CDROM_BUS_SCSI) + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + else + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + fp = plat_fopen(nvr_path(file_name), "wb"); + if (fp) { + fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp); + fclose(fp); + } + break; } } @@ -682,7 +698,7 @@ scsi_cdrom_drive_status_load(scsi_cdrom_t *dev) } static uint8_t -scsi_cdrom_drive_status_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +scsi_cdrom_drive_status_read(scsi_cdrom_t *dev, UNUSED(uint8_t page_control), uint8_t page, uint8_t pos) { return dev->ms_drive_status_pages_saved.pages[page][pos]; } @@ -729,36 +745,42 @@ scsi_cdrom_drive_status(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t p static uint8_t scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved_sony.pages[page][pos]; - break; - case 1: - return scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][pos]; - break; - case 2: - return scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][pos]; - break; - } - } else { - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - break; - case 1: - return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; - else - return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; - break; - } + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + switch (page_control) { + case 0: + case 3: + return dev->ms_pages_saved_sony.pages[page][pos]; + case 1: + return scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][pos]; + case 2: + return scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][pos]; + + default: + break; + } + break; + default: + switch (page_control) { + case 0: + case 3: + return dev->ms_pages_saved.pages[page][pos]; + case 1: + return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; + case 2: + if (dev->drv->bus_type == CDROM_BUS_SCSI) + return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; + else + return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; + + default: + break; + } + break; } return 0; @@ -798,21 +820,21 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag else { if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) { buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f; - /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and early vendor SCSI CD-ROM models) are - caddy drives, the later ones are tray drives. */ - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - buf[pos++] |= ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) ? 0x20 : 0x00); - } else { - buf[pos++] |= ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00")) ? 0x00 : 0x20); - } + /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and + early vendor SCSI CD-ROM models) are caddy drives, the later + ones are tray drives. */ + if (dev->drv->bus_type == CDROM_BUS_SCSI) + buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00); + else + buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) || + ((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20); } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { if (j & 1) buf[pos++] = ((dev->drv->speed * 176) & 0xff); else buf[pos++] = ((dev->drv->speed * 176) >> 8); } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 8) && (j <= 9) && - (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403"))) { + (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403)) { if (j & 1) buf[pos++] = ((dev->drv->speed * 176) & 0xff); else @@ -840,7 +862,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) int32_t min_len = 0; double dlen; - dev->max_transfer_len = dev->request_length; + dev->max_transfer_len = dev->tf->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (dev->current_cdb[0]) { @@ -881,7 +903,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) break; } } - /* FALLTHROUGH */ + fallthrough; default: dev->packet_len = len; @@ -895,9 +917,9 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) dev->max_transfer_len = 65534; if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; + dev->tf->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; + dev->tf->request_length = dev->max_transfer_len; return; } @@ -928,10 +950,11 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) double bytes_per_second = 0.0; double period; - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - dev->callback = 0; + /* MAP: BUSY_STAT, no DRQ, phase 1. */ + dev->tf->status = BUSY_STAT; + dev->tf->phase = 1; + dev->tf->pos = 0; + dev->callback = 0; scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed); @@ -957,55 +980,85 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; - /*FALLTHROUGH*/ + fallthrough; case 0x25: - case 0x42: - case 0x43: - case 0x44: - case 0x51: - case 0x52: + case 0x42 ... 0x44: + case 0x51 ... 0x52: case 0xad: - case 0xb8: - case 0xb9: + case 0xb8 ... 0xb9: case 0xbe: if (dev->current_cdb[0] == 0x42) dev->callback += 40.0; /* Account for seek time. */ - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; - case 0xc6: - case 0xc7: - if ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433"))) { - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; + case 0xc6 ... 0xc7: + switch (dev->drv->type) { + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: + bytes_per_second = 176.0 * 1024.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; + } + case 0xc0: + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; } - break; case 0xc1: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_PIONEER_DRM604X_2403: + case CDROM_TYPE_TEXEL_DMXX24_100: + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; } - break; - case 0xc2: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - dev->callback += 40.0; - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; + case 0xc2 ... 0xc3: + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_PIONEER_DRM604X_2403: + case CDROM_TYPE_TEXEL_DMXX24_100: + if (dev->current_cdb[0] == 0xc2) + dev->callback += 40.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; } - break; - case 0xc3: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; + case 0xdd ... 0xde: + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; } - break; - + fallthrough; default: bytes_per_second = scsi_cdrom_bus_speed(dev); if (bytes_per_second == 0.0) { @@ -1030,7 +1083,7 @@ scsi_cdrom_command_complete(scsi_cdrom_t *dev) ui_sb_update_icon(SB_CDROM | dev->id, 0); dev->packet_status = PHASE_COMPLETE; scsi_cdrom_command_common(dev); - dev->phase = 3; + dev->tf->phase = 3; } static void @@ -1038,7 +1091,7 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_IN; scsi_cdrom_command_common(dev); - dev->phase = !(dev->packet_status & 0x01) << 1; + dev->tf->phase = !(dev->packet_status & 0x01) << 1; } static void @@ -1053,7 +1106,7 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_OUT; scsi_cdrom_command_common(dev); - dev->phase = !(dev->packet_status & 0x01) << 1; + dev->tf->phase = !(dev->packet_status & 0x01) << 1; } static void @@ -1072,8 +1125,9 @@ static void scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) { scsi_cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos = 0; + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, + dev->tf->request_length); + dev->tf->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; @@ -1102,11 +1156,12 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al } scsi_cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); + dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, + dev->tf->phase); } static void -scsi_cdrom_sense_clear(scsi_cdrom_t *dev, int command) +scsi_cdrom_sense_clear(scsi_cdrom_t *dev, UNUSED(int command)) { scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; } @@ -1127,14 +1182,14 @@ static void scsi_cdrom_cmd_error(scsi_cdrom_t *dev) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR; + dev->tf->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * CDROM_TIME; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; + dev->packet_status = PHASE_ERROR; + dev->callback = 50.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); ui_sb_update_icon(SB_CDROM | dev->id, 0); scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); @@ -1144,12 +1199,12 @@ static void scsi_cdrom_unit_attention(scsi_cdrom_t *dev) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; + dev->tf->error |= MCR_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; + dev->tf->pos = 0; dev->packet_status = PHASE_ERROR; dev->callback = 50.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); @@ -1228,7 +1283,7 @@ scsi_cdrom_invalid_field(scsi_cdrom_t *dev) scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -1238,7 +1293,7 @@ scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -1485,9 +1540,9 @@ scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *pack } static void -scsi_cdrom_insert(void *p) +scsi_cdrom_insert(void *priv) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) p; + scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; if (!dev) return; @@ -1505,7 +1560,7 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); + dev->id, ((dev->tf->request_length >> 5) & 7)); scsi_cdrom_invalid_lun(dev); return 0; } @@ -1604,14 +1659,14 @@ scsi_cdrom_reset(scsi_common_t *sc) return; scsi_cdrom_rezero(dev); - dev->status = 0; - dev->callback = 0.0; + dev->tf->status = 0; + dev->callback = 0.0; scsi_cdrom_set_callback(dev); - dev->phase = 1; - dev->request_length = 0xEB14; - dev->packet_status = PHASE_NONE; - dev->unit_attention = 0xff; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->tf->phase = 1; + dev->tf->request_length = 0xeb14; + dev->packet_status = PHASE_NONE; + dev->unit_attention = 0xff; + dev->cur_lun = SCSI_LUN_USE_CDB; } static void @@ -1701,7 +1756,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) int used_len; int alloc_length; int msf; - int pos = 0; + int pos = dev->drv->seek_pos; int size_idx; int idx = 0; uint32_t feature; @@ -1723,10 +1778,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - dev->status &= ~ERR_STAT; + dev->tf->status &= ~ERR_STAT; } else { BufLen = &blen; - dev->error = 0; + dev->tf->error = 0; } dev->packet_len = 0; @@ -1744,11 +1799,12 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (cdb[0] != 0) { scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, dev->unit_attention); - scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length); + dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, + dev->unit_attention); + scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->tf->request_length); - scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]); } @@ -1797,14 +1853,22 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; case 0xDA: /*GPCMD_SPEED_ALT*/ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) { /*GPCMD_STILL_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); - break; + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_STILL_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) + scsi_cdrom_buf_free(dev); + return; } + fallthrough; case GPCMD_SET_SPEED: dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; if (dev->drv->cur_speed < 1) @@ -1879,52 +1943,95 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_buf_free(dev); return; } - scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); return; case 0xC7: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_MSF_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAY_MSF_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; - } /*GPCMD_READ_DISC_INFORMATION_TOSHIBA*/ - case 0xDE: /*GPCMD_READ_DISC_INFORMATION_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 4); + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MSF_MATSUSHITA*/ + cdb[0] = GPCMD_PLAY_AUDIO_MSF; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_MSF_SONY*/ + cdb[0] = GPCMD_PLAY_AUDIO_MSF; + dev->current_cdb[0] = cdb[0]; + dev->sony_vendor = 1; + goto begin; + break; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_DISC_INFORMATION_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + if (!ret) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 4; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + default: + scsi_cdrom_illegal_opcode(dev); + break; } + break; - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; + case 0xDE: + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_DISC_INFORMATION_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 22); /* NEC manual claims 4 bytes, but the Linux kernel (namely sr_vendor.c) actually states otherwise. */ + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } + + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 22; + if (!ret) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; case GPCMD_READ_CD_OLD: /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ dev->current_cdb[0] = GPCMD_READ_CD; - /*FALLTHROUGH*/ + fallthrough; case GPCMD_READ_6: case GPCMD_READ_10: @@ -2002,6 +2109,9 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) return; } break; + + default: + break; } if (!dev->sector_len) { @@ -2024,14 +2134,24 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) { - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0); - else - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0); + break; + default: + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); + break; + } } else ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); @@ -2102,21 +2222,26 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_buf_alloc(dev, 65536); } - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - } else { - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + break; + default: + if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + break; } - memset(dev->buffer, 0, len); alloc_length = len; @@ -2128,7 +2253,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) another variable. */ if (dev->drv->cd_status == CD_STATUS_EMPTY) max_len = 70; /* No media inserted. */ - else if (dev->drv->cdrom_capacity > 405000) + else if (dev->drv->cdrom_capacity > CD_MAX_SECTORS) max_len = 65; /* DVD. */ else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) max_len = 1; /* Data CD. */ @@ -2409,108 +2534,200 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); break; - case 0xC0: /*GPCMD_UNKNOWN_SONY*/ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - dev->sony_vendor = 1; - break; - } /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA and GPCMD_EJECT_CHINON*/ - case 0xD8: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); + case 0xC0: + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_SET_ADDRESS_FORMAT_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; + dev->drv->sony_msf = cdb[8] & 1; + scsi_cdrom_command_complete(dev); break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_MAGAZINE_EJECT_PIONEER*/ + case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_EJECT_CHINON*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); + break; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } break; - case 0xC1: /*GPCMD_READ_TOC_SONY*/ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + case 0xD8: + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - if (strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - dev->sony_vendor = 0; - } else { + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; + + case 0xC1: + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_TOC_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; dev->sony_vendor = 1; - } - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } + scsi_cdrom_buf_alloc(dev, 65536); - len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf || dev->drv->sony_msf, max_len); + if (len == -1) { + /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - } /*GPCMD_PLAY_AUDIO_TOSHIBA*/ - case 0xD9: /*GPCMD_PLAY_AUDIO_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + scsi_cdrom_set_buf_len(dev, BufLen, &len); - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_TOC_PIONEER*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_12: - case GPCMD_PLAY_AUDIO_MSF: - case GPCMD_PLAY_AUDIO_TRACK_INDEX: - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: - case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: - len = 0; + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + if (!ret) { + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } - switch (cdb[0]) { - case GPCMD_PLAY_AUDIO_10: - msf = 0; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_PLAY_AUDIO_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; + + case 0xD9: + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_PLAY_AUDIO_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; + + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_12: + case GPCMD_PLAY_AUDIO_MSF: + case GPCMD_PLAY_AUDIO_TRACK_INDEX: + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: + len = 0; + + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + switch (cdb[0]) { + case GPCMD_PLAY_AUDIO_10: + msf = 0; pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; len = (cdb[7] << 8) | cdb[8]; break; case GPCMD_PLAY_AUDIO_12: - /* This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it. */ msf = 0; pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; @@ -2539,6 +2756,9 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; break; + + default: + break; } if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { @@ -2556,7 +2776,6 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_READ_SUBCHANNEL: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 0; max_len = cdb[7]; max_len <<= 8; @@ -2614,13 +2833,13 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[1] = 0x11; break; case CD_STATUS_PAUSED: - dev->buffer[1] = (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) ? 0x15 : 0x12; + dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x15 : 0x12; break; case CD_STATUS_DATA_ONLY: - dev->buffer[1] = (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) ? 0x00 : 0x15; + dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x15; break; default: - dev->buffer[1] = (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) ? 0x00 : 0x13; + dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x13; break; } @@ -2634,66 +2853,120 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; case 0xC6: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_TRACK_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; - msf = 3; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; + msf = 3; + if ((cdb[5] != 1) || (cdb[8] != 1)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = cdb[4]; - if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } - /* In this case, len is unused so just pass a fixed value of 1 intead. */ - ret = cdrom_audio_play(dev->drv, pos, 1 /*len*/, msf); + /* In this case, len is unused so just pass a fixed value of 1 intead. */ + ret = cdrom_audio_play(dev->drv, pos, 1 /*len*/, msf); - if (ret) + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_STOP_CHINON*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - } /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA and GPCMD_STOP_CHINON*/ - case 0xDD: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + break; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - alloc_length = cdb[1] & 0x1f; - len = 10; + if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); break; - } + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); + case 0xDD: + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } break; @@ -2733,10 +3006,14 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) } break; - case 0x26: /*GPCMD_UNKNOWN_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); + case 0x26: + if (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) { /*GPCMD_UNKNOWN_CHINON*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + } else { + scsi_cdrom_illegal_opcode(dev); + } break; case GPCMD_START_STOP_UNIT: @@ -2757,52 +3034,86 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) case 3: /* Load the disc (close tray). */ cdrom_reload(dev->id); break; + + default: + break; } scsi_cdrom_command_complete(dev); break; case 0xC4: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_READ_HEADER_MATSUSHITA*/ - cdb[0] = GPCMD_READ_HEADER; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAYBACK_STATUS_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_HEADER_MATSUSHITA*/ + cdb[0] = GPCMD_READ_HEADER; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_STATUS_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - scsi_cdrom_buf_alloc(dev, 18); + scsi_cdrom_buf_alloc(dev, 18); - len = max_len; + len = 18; - memset(dev->buffer, 0, 10); - dev->buffer[0] = 0x00; /*Reserved*/ - dev->buffer[1] = 0x00; /*Reserved*/ - dev->buffer[2] = cdb[7]; /*Audio Status data length*/ - dev->buffer[3] = cdb[8]; /*Audio Status data length*/ - dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf); /*Audio status*/ - dev->buffer[5] = 0x00; + memset(dev->buffer, 0, 18); + dev->buffer[0] = 0x00; /*Reserved*/ + dev->buffer[1] = 0x00; /*Reserved*/ + dev->buffer[2] = 0x00; /*Audio Status data length*/ + dev->buffer[3] = 0x00; /*Audio Status data length*/ + dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf || dev->drv->sony_msf); /*Audio status*/ + dev->buffer[5] = 0x00; - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_CADDY_EJECT_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - } /*GPCMD_CADDY_EJECT_TOSHIBA and GPCMD_CADDY_EJECT_NEC*/ case 0xDC: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_CADDY_EJECT_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } break; case GPCMD_INQUIRY: @@ -2850,14 +3161,14 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 68; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) + if (dev->drv->type == CDROM_TYPE_86BOX_100) ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ else ide_padstr8(dev->buffer + idx, 8, cdrom_drive_types[dev->drv->type].vendor); /* Vendor */ idx += 8; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) + if (dev->drv->type == CDROM_TYPE_86BOX_100) ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ else ide_padstr8(dev->buffer + idx, 40, cdrom_drive_types[dev->drv->type].model); /* Product */ @@ -2883,35 +3194,33 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (dev->drv->bus_type == CDROM_BUS_SCSI) { dev->buffer[3] = 0x02; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) { - dev->buffer[2] = 0x05; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433")) { - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272")) { - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) { - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) { - dev->buffer[3] = 0x01; - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i")) { - dev->buffer[3] = 0x01; - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - dev->buffer[3] = 0x01; - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { - dev->buffer[3] = 0x01; - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00")) { - dev->buffer[3] = 0x01; - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) { - dev->buffer[2] = 0x02; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - dev->buffer[2] = 0x02; + switch (dev->drv->type) { + case CDROM_TYPE_86BOX_100: + dev->buffer[2] = 0x05; /*SCSI-2 compliant*/ + break; + case CDROM_TYPE_CHINON_CDS431_H42: + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_MATSHITA_501_10b: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEAC_CD50_100: + case CDROM_TYPE_TEAC_R55S_10R: + case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + dev->buffer[2] = 0x00; + dev->buffer[3] = 0x01; /*SCSI-1 compliant*/ + break; + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + dev->buffer[3] = 0x00; /*SCSI unknown version per NEC manuals*/ + break; + default: + dev->buffer[2] = 0x02; /*SCSI-2 compliant*/ + break; } } else { dev->buffer[2] = 0x00; @@ -2920,32 +3229,32 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[4] = 31; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) { - dev->buffer[6] = 0x01; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PLEXTOR_CD-ROM_PX-32TS_1.03")) { - dev->buffer[6] = 0x01; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEAC_CD-R55S_1.0R")) { - dev->buffer[6] = 0x01; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { - dev->buffer[7] = 0x98; /* Linked Command and Relative Addressing supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433")) { - dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-2 CD-ROM drives from 1990*/ - dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272")) { - dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-2 CD-ROM drives from 1990*/ - dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) { - dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-2 CD-ROM drives from 1990*/ - dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { - dev->buffer[4] = 42; + switch (dev->drv->type) { + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-1 (or SCSI-2) CD-ROM drives from 1989-1990*/ + dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: + dev->buffer[4] = 42; + break; + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + break; + default: + dev->buffer[6] = 0x01; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ + break; } } - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) { + if (dev->drv->type == CDROM_TYPE_86BOX_100) { ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ @@ -2953,23 +3262,29 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) ide_padstr8(dev->buffer + 8, 8, cdrom_drive_types[dev->drv->type].vendor); /* Vendor */ ide_padstr8(dev->buffer + 16, 16, cdrom_drive_types[dev->drv->type].model); /* Product */ ide_padstr8(dev->buffer + 32, 4, cdrom_drive_types[dev->drv->type].revision); /* Revision */ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { dev->buffer[36] = 0x20; - ide_padstr8(dev->buffer + 37, 10, "1993/01/01"); /* Date */ + ide_padstr8(dev->buffer + 37, 10, "1991/01/01"); /* Date */ } } idx = 36; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) /*Toshiba only*/ - idx = 96; - else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) /*Pioneer only*/ + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) idx = 47; else { - if (max_len == 96) { - dev->buffer[4] = 91; - idx = 96; + switch (dev->drv->type) { + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + idx = 96; + break; + default: + if (max_len == 96) { + dev->buffer[4] = 91; + idx = 96; + } + break; } } } @@ -3004,84 +3319,151 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; case 0xC3: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_READ_TOC_MATSUSHITA*/ - cdb[0] = GPCMD_READ_TOC_PMA_ATIP; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_READ_HEADER_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_TOC_MATSUSHITA*/ + cdb[0] = GPCMD_READ_TOC_PMA_ATIP; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_HEADER_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; - alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 4); + alloc_length = ((cdb[7] << 8) | cdb[8]); + scsi_cdrom_buf_alloc(dev, 4); - dev->sector_len = 1; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - dev->buffer[0] = ((real_pos >> 16) & 0xff); - dev->buffer[1] = ((real_pos >> 8) & 0xff); - dev->buffer[2] = real_pos & 0xff; - dev->buffer[3] = 1; /*2048 bytes user data*/ + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); + dev->buffer[0] = ((real_pos >> 16) & 0xff); + dev->buffer[1] = ((real_pos >> 8) & 0xff); + dev->buffer[2] = real_pos & 0xff; + dev->buffer[3] = 1; /*2048 bytes user data*/ - len = 4; - len = MIN(len, alloc_length); + len = 4; + len = MIN(len, alloc_length); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + return; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_SET_STOP_TIME_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } + break; - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - } /*GPCMD_SET_STOP_TIME_TOSHIBA and GPCMD_SET_STOP_TIME_NEC*/ case 0xDB: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: /*GPCMD_SET_STOP_TIME_NEC*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; + } break; case 0xC2: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_READ_SUBCHANNEL_MATSUSHITA*/ - cdb[0] = GPCMD_READ_SUBCHANNEL; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_READ_SUBCHANNEL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - dev->sony_vendor = !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ? 0 : 1; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_SUBCHANNEL_MATSUSHITA*/ + cdb[0] = GPCMD_READ_SUBCHANNEL; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_SUBCHANNEL_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - if (strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - scsi_cdrom_buf_alloc(dev, 32); + scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s), code-q = %02x\n", dev->id, msf ? "MSF" : "LBA", cdb[2] & 0x40); - scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s)\n", dev->id, msf ? "MSF" : "LBA"); + if (cdb[2] & 0x40) { + scsi_cdrom_buf_alloc(dev, 9); + memset(dev->buffer, 0, 9); + len = 9; + cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf || dev->drv->sony_msf); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_SUBCODEQ_PIONEER*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - if (!(cdb[2] & 0x40)) - alloc_length = 4; - else - alloc_length = 24; + alloc_length = cdb[1] & 0x1f; + len = 9; - len = alloc_length; + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - memset(dev->buffer, 0, 24); - cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf); + if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; + memset(dev->buffer, 0, len); + cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + break; + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_STILL_TOSHIBA*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } - /*GPCMD_STILL_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); break; case GPCMD_SEEK_6: @@ -3095,17 +3477,30 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_SEEK_10: pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; + + default: + break; } dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); if (cdb[0] == GPCMD_SEEK_10) { - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) - cdrom_seek(dev->drv, pos, cdb[9] & 0xc0); - else - cdrom_seek(dev->drv, pos, 0); + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a: + case CDROM_TYPE_NEC_38_103: + case CDROM_TYPE_NEC_75_103: + case CDROM_TYPE_NEC_77_106: + case CDROM_TYPE_NEC_211_100: + case CDROM_TYPE_NEC_464_105: + case CDROM_TYPE_TOSHIBA_XM_3433: + case CDROM_TYPE_TOSHIBA_XM3201B_3232: + case CDROM_TYPE_TOSHIBA_XM3301TA_0272: + case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_SDM1401_1008: + cdrom_seek(dev->drv, pos, cdb[9] & 0xc0); + break; + default: + cdrom_seek(dev->drv, pos, 0); + break; + } } else cdrom_seek(dev->drv, pos, 0); @@ -3144,84 +3539,157 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; case 0xC5: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PAUSE_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); - scsi_cdrom_command_complete(dev); - break; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MATSUSHITA*/ + cdb[0] = GPCMD_PLAY_AUDIO_10; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PAUSE_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; + cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } + break; + case 0xC8: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAY_AUDIO_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA*/ + cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_AUDIO_SONY*/ + cdb[0] = GPCMD_PLAY_AUDIO_10; + dev->current_cdb[0] = cdb[0]; + dev->sony_vendor = 1; + goto begin; + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_AUDIO_TRACK_SEARCH_PIONEER*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } + break; + case 0xC9: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAYBACK_CONTROL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); - dev->sony_vendor = 1; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA*/ + cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_CONTROL_SONY*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + dev->sony_vendor = 1; - len = (cdb[7] << 8) | cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + len = (cdb[7] << 8) | cdb[8]; + if (!len) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + break; + } + scsi_cdrom_buf_alloc(dev, 65536); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 1); - break; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 1); + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_PLAY_AUDIO_PIONEER*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_pioneer(dev->drv, pos); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } + break; + case 0xCA: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_PAUSE_PIONEER*/ + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PAUSE_PIONEER*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); scsi_cdrom_command_complete(dev); - break; + } else { + scsi_cdrom_illegal_opcode(dev); } + break; + case 0xCB: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PAUSE_RESUME_MATSUSHITA*/ - cdb[0] = GPCMD_PAUSE_RESUME; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; + switch (dev->drv->type) { + case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PAUSE_RESUME_MATSUSHITA*/ + cdb[0] = GPCMD_PAUSE_RESUME; + dev->current_cdb[0] = cdb[0]; + goto begin; + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_STOP_PIONEER*/ + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + break; + default: + scsi_cdrom_illegal_opcode(dev); + break; } + break; + case 0xCC: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PLAYBACK_STATUS_PIONEER*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 18); + scsi_cdrom_buf_alloc(dev, 6); - len = max_len; + len = 6; - memset(dev->buffer, 0, 10); - dev->buffer[0] = 0x00; /*Reserved*/ - dev->buffer[1] = 0x00; /*Reserved*/ - dev->buffer[2] = cdb[7]; /*Audio Status data length*/ - dev->buffer[3] = cdb[8]; /*Audio Status data length*/ - dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf); /*Audio status*/ - dev->buffer[5] = 0x00; + memset(dev->buffer, 0, 6); + dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/ scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); @@ -3229,10 +3697,13 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; + } else { + scsi_cdrom_illegal_opcode(dev); } + break; + case 0xE0: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_DRIVE_STATUS_PIONEER*/ + if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_DRIVE_STATUS_PIONEER*/ scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); len = (cdb[9] | (cdb[8] << 8)); @@ -3265,29 +3736,37 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); return; + } else { + scsi_cdrom_illegal_opcode(dev); } + break; + case 0xE5: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_12_MATSUSHITA*/ + if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_12_MATSUSHITA*/ cdb[0] = GPCMD_PLAY_AUDIO_12; dev->current_cdb[0] = cdb[0]; goto begin; - break; + } else { + scsi_cdrom_illegal_opcode(dev); } + break; + case 0xE9: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA*/ + if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA*/ cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12; dev->current_cdb[0] = cdb[0]; goto begin; - break; } + fallthrough; default: scsi_cdrom_illegal_opcode(dev); break; } - /* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ + /* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->tf->phase, + dev->tf->request_length); */ - if (scsi_cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) scsi_cdrom_buf_free(dev); } @@ -3357,57 +3836,70 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) pos += 2; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << ((uint64_t) page)))) { - scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved_sony.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved_sony.pages[page][i + 2] = val; - else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); - error |= 1; + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << ((uint64_t) page)))) { + scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); + error |= 1; + } else { + for (i = 0; i < page_len; i++) { + ch = scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved_sony.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved_sony.pages[page][i + 2] = val; + else { + scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); + error |= 1; + } } } } - } - } else { - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { - scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); - error |= 1; + break; + default: + if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { + scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); + error |= 1; + } else { + for (i = 0; i < page_len; i++) { + ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else { + scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); + error |= 1; + } } } } - } + break; } pos += page_len; - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) - val = scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][0] & 0x80; - else if (dev->drv->bus_type == CDROM_BUS_SCSI) - val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + val = scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][0] & 0x80; + break; + default: + if (dev->drv->bus_type == CDROM_BUS_SCSI) + val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; + else + val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; + break; + } if (dev->do_page_save && val) scsi_cdrom_mode_sense_save(dev); @@ -3422,13 +3914,23 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } break; case 0xC9: - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { - for (i = 0; i < 18; i++) { - dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = dev->buffer[i]; - } + switch (dev->drv->type) { + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_SONY_CDU541_10i: + case CDROM_TYPE_SONY_CDU561_18k: + case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DMXX24_100: + for (i = 0; i < 18; i++) { + dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = dev->buffer[i]; + } + break; + default: + break; } break; + + default: + break; } scsi_cdrom_command_stop((scsi_common_t *) dev); @@ -3436,9 +3938,12 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } static void -scsi_cdrom_close(void *p) +scsi_cdrom_close(void *priv) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) p; + scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; + + if (dev->tf) + free(dev->tf); if (dev) free(dev); @@ -3499,7 +4004,7 @@ scsi_cdrom_get_timings(int ide_has_dma, int type) static void scsi_cdrom_identify(ide_t *ide, int ide_has_dma) { - scsi_cdrom_t *dev; + const scsi_cdrom_t *dev; char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; dev = (scsi_cdrom_t *) ide->sc; @@ -3507,76 +4012,97 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) device_identify[7] = dev->id + 0x30; scsi_cdrom_log("ATAPI Identify: %s\n", device_identify); - if ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01")) || (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC only*/ - ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (1 << 5); /* ATAPI device, CD-ROM drive, removable media, interrupt DRQ */ + if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) /*NEC only*/ + ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (1 << 5); /* ATAPI device, CD-ROM drive, removable media, interrupt DRQ */ else ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) { + if (dev->drv->type == CDROM_TYPE_86BOX_100) { ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ } else { - if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01")) { - ide_padstr((char *) (ide->buffer + 23), ".110 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00")) { - ide_padstr((char *) (ide->buffer + 23), ".100 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "AZT_CDA46802I_1.15")) { - ide_padstr((char *) (ide->buffer + 23), "1.15 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "AZT CDA46802I ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "HITACHI_CDR-8130_0020")) { - ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU76_1.0i")) { - ide_padstr((char *) (ide->buffer + 23), "1.0i ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU76 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU311_3.0h")) { - ide_padstr((char *) (ide->buffer + 23), "3.0h ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU311 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE280_1.05")) { - ide_padstr((char *) (ide->buffer + 23), "1.05 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE280_3.08")) { - ide_padstr((char *) (ide->buffer + 23), "3.08 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE273_4.20")) { - ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5302TA_0305")) { - ide_padstr((char *) (ide->buffer + 23), "0305 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5302TA ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5702B_TA70")) { - ide_padstr((char *) (ide->buffer + 23), "TA70 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5702B ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "GOLDSTAR_CRD-8160B_3.14")) { - ide_padstr((char *) (ide->buffer + 23), "3.14 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "GOLDSTAR CRD-8160B ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CR-571_1.0e")) { - ide_padstr((char *) (ide->buffer + 23), "1.0e ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-571 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CR-572_1.0j")) { - ide_padstr((char *) (ide->buffer + 23), "1.0j ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-572 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-587_7S13")) { - ide_padstr((char *) (ide->buffer + 23), "7S13 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-587 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-588_LS15")) { - ide_padstr((char *) (ide->buffer + 23), "LS15 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-588 ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MITSUMI_CRMC-FX4820T_D02A")) { - ide_padstr((char *) (ide->buffer + 23), "D02A ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MITSUMI CRMC-FX4820T ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PHILIPS_CD-ROM_PCA403CD_U31P")) { - ide_padstr((char *) (ide->buffer + 23), "U31P ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "PHILIPS CD-ROM PCA403CD ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "BTC_CD-ROM_BCD36XH_U1.0")) { - ide_padstr((char *) (ide->buffer + 23), "U1.0 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "BTC CD-ROM BCD36XH ", 40); /* Model */ - } else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "KENWOOD_CD-ROM_UCR-421_208E")) { - ide_padstr((char *) (ide->buffer + 23), "208E ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "KENWOOD CD-ROM UCR-421 ", 40); /* Model */ + switch (dev->drv->type) { + case CDROM_TYPE_AZT_CDA46802I_115: + ide_padstr((char *) (ide->buffer + 23), "1.15 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "AZT CDA46802I ", 40); /* Model */ + break; + case CDROM_TYPE_BTC_BCD36XH_U10: + ide_padstr((char *) (ide->buffer + 23), "U1.0 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "BTC CD-ROM BCD36XH ", 40); /* Model */ + break; + case CDROM_TYPE_GOLDSTAR_CRD_8160B_314: + ide_padstr((char *) (ide->buffer + 23), "3.14 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "GOLDSTAR CRD-8160B ", 40); /* Model */ + break; + case CDROM_TYPE_HITACHI_CDR_8130_0020: + ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */ + break; + case CDROM_TYPE_KENWOOD_UCR_421_208E: + ide_padstr((char *) (ide->buffer + 23), "208E ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "KENWOOD CD-ROM UCR-421 ", 40); /* Model */ + break; + case CDROM_TYPE_MATSHITA_587_7S13: + ide_padstr((char *) (ide->buffer + 23), "7S13 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-587 ", 40); /* Model */ + break; + case CDROM_TYPE_MATSHITA_588_LS15: + ide_padstr((char *) (ide->buffer + 23), "LS15 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-588 ", 40); /* Model */ + break; + case CDROM_TYPE_MATSHITA_571_10e: + ide_padstr((char *) (ide->buffer + 23), "1.0e ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-571 ", 40); /* Model */ + break; + case CDROM_TYPE_MATSHITA_572_10j: + ide_padstr((char *) (ide->buffer + 23), "1.0j ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-572 ", 40); /* Model */ + break; + case CDROM_TYPE_MITSUMI_FX4820T_D02A: + ide_padstr((char *) (ide->buffer + 23), "D02A ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "MITSUMI CRMC-FX4820T ", 40); /* Model */ + break; + case CDROM_TYPE_NEC_260_100: + ide_padstr((char *) (ide->buffer + 23), ".100 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ + break; + case CDROM_TYPE_NEC_260_101: + ide_padstr((char *) (ide->buffer + 23), ".110 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ + break; + case CDROM_TYPE_NEC_273_420: + ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ + break; + case CDROM_TYPE_NEC_280_105: + ide_padstr((char *) (ide->buffer + 23), "1.05 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ + break; + case CDROM_TYPE_NEC_280_308: + ide_padstr((char *) (ide->buffer + 23), "3.08 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ + break; + case CDROM_TYPE_PHILIPS_PCA403CD_U31P: + ide_padstr((char *) (ide->buffer + 23), "U31P ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "PHILIPS CD-ROM PCA403CD ", 40); /* Model */ + break; + case CDROM_TYPE_SONY_CDU76_10i: + ide_padstr((char *) (ide->buffer + 23), "1.0i ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU76 ", 40); /* Model */ + break; + case CDROM_TYPE_SONY_CDU311_30h: + ide_padstr((char *) (ide->buffer + 23), "3.0h ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU311 ", 40); /* Model */ + break; + case CDROM_TYPE_TOSHIBA_5302TA_0305: + ide_padstr((char *) (ide->buffer + 23), "0305 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5302TA ", 40); /* Model */ + break; + case CDROM_TYPE_TOSHIBA_5702B_TA70: + ide_padstr((char *) (ide->buffer + 23), "TA70 ", 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5702B ", 40); /* Model */ + break; } } @@ -3600,6 +4126,7 @@ scsi_cdrom_drive_reset(int c) ide_t *id; uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; uint8_t scsi_id = drv->scsi_device_id & 0x0f; + uint8_t valid = 0; if (drv->bus_type == CDROM_BUS_SCSI) { /* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */ @@ -3632,9 +4159,12 @@ scsi_cdrom_drive_reset(int c) drv->get_channel = scsi_cdrom_get_channel; drv->close = scsi_cdrom_close; - scsi_cdrom_init(dev); - if (drv->bus_type == CDROM_BUS_SCSI) { + valid = 1; + + if (!dev->tf) + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); + /* SCSI CD-ROM, attach to the SCSI bus. */ sd = &scsi_devices[scsi_bus][scsi_id]; @@ -3654,7 +4184,12 @@ scsi_cdrom_drive_reset(int c) otherwise, we do nothing - it's going to be a drive that's not attached to anything. */ if (id) { + valid = 1; + id->sc = (scsi_common_t *) dev; + dev->tf = id->tf; + if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) + IDE_ATAPI_IS_EARLY = 1; id->get_max = scsi_cdrom_get_max; id->get_timings = scsi_cdrom_get_timings; id->identify = scsi_cdrom_identify; @@ -3664,12 +4199,15 @@ scsi_cdrom_drive_reset(int c) id->phase_data_out = scsi_cdrom_phase_data_out; id->command_stop = scsi_cdrom_command_stop; id->bus_master_error = scsi_cdrom_bus_master_error; - id->interrupt_drq = (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || - (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))); + id->interrupt_drq = ((dev->drv->type == CDROM_TYPE_NEC_260_100) || + (dev->drv->type == CDROM_TYPE_NEC_260_101)); ide_atapi_attach(id); } scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel); } + + if (valid) + scsi_cdrom_init(dev); } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 42725c91b0..4442b2680c 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -23,8 +23,10 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/hdd.h> +#include <86box/hdc_ide.h> #include <86box/scsi.h> #include <86box/scsi_device.h> +#include <86box/plat_unused.h> scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX]; @@ -36,7 +38,7 @@ scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb) if (dev->command) { dev->command(dev->sc, cdb); - if (dev->sc->status & ERR_STAT) + if (dev->sc->tf->status & ERR_STAT) return SCSI_STATUS_CHECK_CONDITION; else return SCSI_STATUS_OK; @@ -97,7 +99,7 @@ scsi_device_valid(scsi_device_t *dev) } int -scsi_device_cdb_length(scsi_device_t *dev) +scsi_device_cdb_length(UNUSED(scsi_device_t *dev)) { /* Right now, it's 12 for all devices. */ return 12; @@ -139,7 +141,7 @@ scsi_device_command_phase1(scsi_device_t *dev) } else scsi_device_command_stop(dev); - if (dev->sc->status & ERR_STAT) + if (dev->sc->tf->status & ERR_STAT) dev->status = SCSI_STATUS_CHECK_CONDITION; else dev->status = SCSI_STATUS_OK; diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index f504985ef3..39a69ea323 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -12,27 +12,34 @@ * * Copyright 2017-2018 Miran Grca. */ +#include +#include +#include #include #include #include #include -#include #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/config.h> #include <86box/timer.h> #include <86box/device.h> -#include <86box/nvr.h> -#include <86box/hdd.h> -#include <86box/hdc.h> #include <86box/scsi.h> #include <86box/scsi_device.h> +#include <86box/machine.h> +#include <86box/nvr.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/sound.h> #include <86box/plat.h> #include <86box/ui.h> +#include <86box/hdd.h> #include <86box/scsi_disk.h> #include <86box/version.h> +#define IDE_ATAPI_IS_EARLY id->sc->pad0 + #define scsi_disk_sense_error dev->sense[0] #define scsi_disk_sense_key dev->sense[2] #define scsi_disk_asc dev->sense[12] @@ -116,6 +123,12 @@ static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = { [GPMODE_UNK_VENDOR_PAGE] = { 0xB0, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }} }; +static void scsi_disk_command_complete(scsi_disk_t *dev); + +static void scsi_disk_mode_sense_load(scsi_disk_t *dev); + +static void scsi_disk_init(scsi_disk_t *dev); + #ifdef ENABLE_SCSI_DISK_LOG int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; @@ -134,10 +147,63 @@ scsi_disk_log(const char *fmt, ...) # define scsi_disk_log(fmt, ...) #endif +static void +scsi_disk_set_callback(scsi_disk_t *dev) +{ + if (dev->drv->bus != HDD_BUS_SCSI) + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); +} + +static void +scsi_disk_init(scsi_disk_t *dev) +{ + if (!dev) + return; + + /* Do a reset (which will also rezero it). */ + scsi_disk_reset((scsi_common_t *) dev); + + /* Configure the drive. */ + dev->requested_blocks = 1; + + dev->drv->bus_mode = 0; + if (dev->drv->bus >= HDD_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus < HDD_BUS_SCSI) + dev->drv->bus_mode |= 1; + scsi_disk_log("SCSI HDD %i: Bus type %i, bus mode %i\n", + dev->id, dev->drv->bus, dev->drv->bus_mode); + + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + /* NEC only */ + dev->tf->status = 0; + dev->tf->pos = 0; + dev->packet_status = PHASE_NONE; + scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = dev->unit_attention = 0; + scsi_disk_mode_sense_load(dev); +} + +/* Returns: 0 for none, 1 for PIO, 2 for DMA. */ +static int +scsi_disk_current_mode(scsi_disk_t *dev) +{ + if (dev->drv->bus == HDD_BUS_SCSI) + return 2; + else if (dev->drv->bus == HDD_BUS_ATAPI) { + scsi_disk_log("SCSI DISK %i: ATAPI drive, setting to %s\n", dev->id, + (dev->tf->features & 1) ? "DMA" : "PIO", + dev->id); + return (dev->tf->features & 1) ? 2 : 1; + } + + return 0; +} + void scsi_disk_mode_sense_load(scsi_disk_t *dev) { - FILE *f; + FILE *fp; char file_name[512]; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); @@ -145,26 +211,26 @@ scsi_disk_mode_sense_load(scsi_disk_t *dev) memset(file_name, 0, 512); sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); - f = plat_fopen(nvr_path(file_name), "rb"); - if (f) { - if (fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, f) != 0x18) + fp = plat_fopen(nvr_path(file_name), "rb"); + if (fp) { + if (fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, fp) != 0x18) fatal("scsi_disk_mode_sense_load(): Error reading data\n"); - fclose(f); + fclose(fp); } } void scsi_disk_mode_sense_save(scsi_disk_t *dev) { - FILE *f; + FILE *fp; char file_name[512]; memset(file_name, 0, 512); sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); - f = plat_fopen(nvr_path(file_name), "wb"); - if (f) { - fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); - fclose(f); + fp = plat_fopen(nvr_path(file_name), "wb"); + if (fp) { + fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, fp); + fclose(fp); } } @@ -182,9 +248,9 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, case 2: case 3: switch (pos) { + default: case 0: case 1: - default: return scsi_disk_mode_sense_pages_default.pages[page][pos]; case 2: case 6: @@ -201,6 +267,8 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, case 5: return dev->drv->hpc & 0xff; } + + default: break; } else if (page == GPMODE_FORMAT_DEVICE_PAGE) @@ -210,9 +278,9 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, case 2: case 3: switch (pos) { + default: case 0: case 1: - default: return scsi_disk_mode_sense_pages_default.pages[page][pos]; /* Actual sectors + the 1 "alternate sector" we report. */ case 10: @@ -220,6 +288,8 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, case 11: return (dev->drv->spt + 1) & 0xff; } + + default: break; } else @@ -229,6 +299,9 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, return dev->ms_pages_saved.pages[page][pos]; case 2: return scsi_disk_mode_sense_pages_default.pages[page][pos]; + + default: + break; } return 0; @@ -273,14 +346,166 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, } static void -scsi_disk_command_common(scsi_disk_t *dev) +scsi_disk_update_request_length(scsi_disk_t *dev, int len, int block_len) { - dev->status = BUSY_STAT; - dev->phase = 1; - if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0.0; - else + int bt; + int min_len = 0; + + dev->max_transfer_len = dev->tf->request_length; + + /* For media access commands, make sure the requested DRQ length matches the block length. */ + switch (dev->current_cdb[0]) { + case 0x08: + case 0x0a: + case 0x28: + case 0x2a: + case 0xa8: + case 0xaa: + /* Round it to the nearest 2048 bytes. */ + dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; + + /* Make sure total length is not bigger than sum of the lengths of + all the requested blocks. */ + bt = (dev->requested_blocks * block_len); + if (len > bt) + len = bt; + + min_len = block_len; + + if (len <= block_len) { + /* Total length is less or equal to block length. */ + if (dev->max_transfer_len < block_len) { + /* Transfer a minimum of (block size) bytes. */ + dev->max_transfer_len = block_len; + dev->packet_len = block_len; + break; + } + } + fallthrough; + + default: + dev->packet_len = len; + break; + } + /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ + if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) + dev->max_transfer_len &= 0xfffe; + /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + if (!dev->max_transfer_len) + dev->max_transfer_len = 65534; + + if ((len <= dev->max_transfer_len) && (len >= min_len)) + dev->tf->request_length = dev->max_transfer_len = len; + else if (len > dev->max_transfer_len) + dev->tf->request_length = dev->max_transfer_len; + + return; +} + +static double +scsi_disk_bus_speed(scsi_disk_t *dev) +{ + double ret = -1.0; + + if (dev && dev->drv && (dev->drv->bus == HDD_BUS_SCSI)) { dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; + } else { + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + if (dev) + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; + } +} + +void +scsi_disk_command_common(scsi_disk_t *dev) +{ + double bytes_per_second = 0.0; + double period; + + /* MAP: BUSY_STAT, no DRQ, phase 1. */ + dev->tf->status = BUSY_STAT; + dev->tf->phase = 1; + dev->tf->pos = 0; + dev->callback = 0; + + if (dev->packet_status == PHASE_COMPLETE) { + switch (dev->current_cdb[0]) { + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_AND_VERIFY_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_12: + case GPCMD_WRITE_SAME_10: + /* Seek time is in us. */ + period = hdd_timing_write(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); + scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", + dev->id, (uint64_t) period); + dev->callback += period; + /* Account for seek time. */ + bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4); + + period = 1000000.0 / bytes_per_second; + scsi_disk_log("SCSI HD %i: Byte transfer period: %" PRIu64 " us\n", dev->id, + (uint64_t) period); + period = period * (double) (dev->packet_len); + scsi_disk_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, + (uint64_t) period); + dev->callback += period; + break; + default: + dev->callback = 0; + break; + } + } else { + switch (dev->current_cdb[0]) { + case GPCMD_REZERO_UNIT: + case 0x0b: + case 0x2b: + /* Seek time is in us. */ + period = hdd_seek_get_time(dev->drv, (dev->current_cdb[0] == GPCMD_REZERO_UNIT) ? + 0 : dev->sector_pos, HDD_OP_SEEK, 0, 0.0); + scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", + dev->id, (uint64_t) period); + dev->callback += period; + scsi_disk_set_callback(dev); + return; + case 0x08: + case 0x28: + case 0xa8: + /* Seek time is in us. */ + period = hdd_timing_read(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); + scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", + dev->id, (uint64_t) period); + dev->callback += period; + /* Account for seek time. */ + bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4); + break; + case 0x25: + default: + bytes_per_second = scsi_disk_bus_speed(dev); + if (bytes_per_second == 0.0) { + dev->callback = -1; /* Speed depends on SCSI controller */ + return; + } + break; + } + + period = 1000000.0 / bytes_per_second; + scsi_disk_log("SCSI HD %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + period = period * (double) (dev->packet_len); + scsi_disk_log("SCSI HD %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + dev->callback += period; + } + scsi_disk_set_callback(dev); } static void @@ -291,6 +516,13 @@ scsi_disk_command_complete(scsi_disk_t *dev) scsi_disk_command_common(dev); } +static void +scsi_disk_command_read(scsi_disk_t *dev) +{ + dev->packet_status = PHASE_DATA_IN; + scsi_disk_command_common(dev); +} + static void scsi_disk_command_read_dma(scsi_disk_t *dev) { @@ -298,6 +530,13 @@ scsi_disk_command_read_dma(scsi_disk_t *dev) scsi_disk_command_common(dev); } +static void +scsi_disk_command_write(scsi_disk_t *dev) +{ + dev->packet_status = PHASE_DATA_OUT; + scsi_disk_command_common(dev); +} + static void scsi_disk_command_write_dma(scsi_disk_t *dev) { @@ -305,27 +544,52 @@ scsi_disk_command_write_dma(scsi_disk_t *dev) scsi_disk_command_common(dev); } +/* id = Current ZIP device ID; + len = Total transfer length; + block_len = Length of a single block (why does it matter?!); + alloc_len = Allocated transfer length; + direction = Transfer direction (0 = read from host, 1 = write to host). */ static void scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int alloc_len, int direction) { - scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, - dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, + dev->tf->request_length); + dev->tf->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; } - if (len == 0) + if ((len == 0) || (scsi_disk_current_mode(dev) == 0)) { + if (dev->drv->bus != HDD_BUS_SCSI) + dev->packet_len = 0; + scsi_disk_command_complete(dev); - else { - if (direction == 0) - scsi_disk_command_read_dma(dev); - else - scsi_disk_command_write_dma(dev); + } else { + if (scsi_disk_current_mode(dev) == 2) { + if (dev->drv->bus != HDD_BUS_SCSI) + dev->packet_len = alloc_len; + + if (direction == 0) + scsi_disk_command_read_dma(dev); + else + scsi_disk_command_write_dma(dev); + } else { + scsi_disk_update_request_length(dev, len, block_len); + if (direction == 0) + scsi_disk_command_read(dev); + else + scsi_disk_command_write(dev); + } } + + scsi_disk_log("SCSI HD %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", + dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, + dev->tf->phase); } static void -scsi_disk_sense_clear(scsi_disk_t *dev, int command) +scsi_disk_sense_clear(scsi_disk_t *dev, UNUSED(int command)) { scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; } @@ -346,15 +610,44 @@ static void scsi_disk_cmd_error(scsi_disk_t *dev) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - dev->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; + dev->tf->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; + dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->phase = 3; dev->packet_status = PHASE_ERROR; dev->callback = 50.0 * SCSI_TIME; + scsi_disk_set_callback(dev); ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); scsi_disk_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); } +static void +scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) +{ + scsi_disk_log("SCSI HD %i: Allocated buffer length: %i\n", dev->id, len); + if (!dev->temp_buffer) + dev->temp_buffer = (uint8_t *) malloc(len); +} + +static void +scsi_disk_buf_free(scsi_disk_t *dev) +{ + if (dev->temp_buffer) { + scsi_disk_log("SCSI HD %i: Freeing buffer...\n", dev->id); + free(dev->temp_buffer); + dev->temp_buffer = NULL; + } +} + +static void +scsi_disk_bus_master_error(scsi_common_t *sc) +{ + scsi_disk_t *dev = (scsi_disk_t *) sc; + + scsi_disk_buf_free(dev); + scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); +} + static void scsi_disk_invalid_lun(scsi_disk_t *dev) { @@ -390,7 +683,7 @@ scsi_disk_invalid_field(scsi_disk_t *dev) scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -400,7 +693,7 @@ scsi_disk_invalid_field_pl(scsi_disk_t *dev) scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_disk_ascq = 0; scsi_disk_cmd_error(dev); - dev->status = 0x53; + dev->tf->status = 0x53; } static void @@ -412,18 +705,56 @@ scsi_disk_data_phase_error(scsi_disk_t *dev) scsi_disk_cmd_error(dev); } +static int +scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), int out) +{ + *len = 0; + uint32_t medium_size = hdd_image_get_last_sector(dev->id) + 1; + + if (!dev->sector_len) { + scsi_disk_command_complete(dev); + return -1; + } + + scsi_disk_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", + dev->requested_blocks, dev->sector_pos); + + if (dev->sector_pos >= medium_size) { + scsi_disk_log("SCSI HD %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); + scsi_disk_lba_out_of_range(dev); + return 0; + } + + *len = dev->requested_blocks << 9; + + for (int i = 0; i < dev->requested_blocks; i++) { + if (out) + hdd_image_write(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)); + else + hdd_image_read(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)); + } + + scsi_disk_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); + + dev->sector_pos += dev->requested_blocks; + dev->sector_len -= dev->requested_blocks; + + return 1; +} + static int scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) { if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->request_length >> 5) & 7)); + dev->id, ((dev->tf->request_length >> 5) & 7)); scsi_disk_invalid_lun(dev); return 0; } if (!(scsi_disk_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X\n", dev->id, cdb[0]); + scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], + (dev->drv->bus == HDD_BUS_SCSI) ? "SCSI" : "ATAPI"); scsi_disk_illegal_opcode(dev); return 0; } @@ -455,16 +786,20 @@ scsi_disk_rezero(scsi_disk_t *dev) scsi_disk_seek(dev, 0); } -static void +void scsi_disk_reset(scsi_common_t *sc) { scsi_disk_t *dev = (scsi_disk_t *) sc; scsi_disk_rezero(dev); - dev->status = 0; - dev->callback = 0.0; - dev->packet_status = PHASE_NONE; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->tf->status = 0; + dev->callback = 0.0; + scsi_disk_set_callback(dev); + dev->tf->phase = 1; + dev->tf->request_length = 0xEB14; + dev->packet_status = PHASE_NONE; + dev->unit_attention = 0; + dev->cur_lun = SCSI_LUN_USE_CDB; } void @@ -502,30 +837,14 @@ scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t all static void scsi_disk_set_buf_len(scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - scsi_disk_log("SCSI HD %i: Actual transfer length: %i\n", dev->id, *BufLen); -} - -static void -scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) -{ - scsi_disk_log("SCSI HD %i: Allocated buffer length: %i\n", dev->id, len); - if (!dev->temp_buffer) - dev->temp_buffer = (uint8_t *) malloc(len); -} - -static void -scsi_disk_buf_free(scsi_disk_t *dev) -{ - if (dev->temp_buffer) { - scsi_disk_log("SCSI HD %i: Freeing buffer...\n", dev->id); - free(dev->temp_buffer); - dev->temp_buffer = NULL; + if (dev->drv->bus == HDD_BUS_SCSI) { + if (*BufLen == -1) + *BufLen = *src_len; + else { + *BufLen = MIN(*src_len, *BufLen); + *src_len = *BufLen; + } + scsi_disk_log("SCSI HD %i: Actual transfer length: %i\n", dev->id, *BufLen); } } @@ -533,6 +852,8 @@ static void scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) { scsi_disk_t *dev = (scsi_disk_t *) sc; + int ret; + int32_t blen = 0; int32_t *BufLen; int32_t len; int32_t max_len; @@ -548,12 +869,18 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; uint8_t scsi_id = dev->drv->scsi_id & 0x0f; - BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + if (dev->drv->bus == HDD_BUS_SCSI) { + BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + dev->tf->status &= ~ERR_STAT; + } else { + BufLen = &blen; + dev->tf->error = 0; + } last_sector = hdd_image_get_last_sector(dev->id); - dev->status &= ~ERR_STAT; dev->packet_len = 0; + dev->request_pos = 0; device_identify[6] = (dev->id / 10) + 0x30; device_identify[7] = (dev->id % 10) + 0x30; @@ -569,7 +896,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) if (cdb[0] != 0) { scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); - scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->request_length); + scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->tf->request_length); scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], @@ -590,7 +917,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_invalid_field(dev); return; } - /*FALLTHROUGH*/ + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -601,19 +928,25 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_REZERO_UNIT: dev->sector_pos = dev->sector_len = 0; + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + scsi_disk_seek(dev, 0); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ + /* If there's a unit attention condition and there's a buffered not + ready, a standalone REQUEST SENSE should forget about the not + ready, and report unit attention straight away. */ len = cdb[4]; if (!len) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); break; } @@ -646,60 +979,83 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = 512; + switch (cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; + /* + For READ (6) and WRITE (6), a length of 0 indicates a + transfer of 256 sectors. + */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); break; case GPCMD_READ_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + + default: break; } - if ((dev->sector_pos > last_sector) /* || ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/) { + if (dev->sector_pos > last_sector) { scsi_disk_lba_out_of_range(dev); return; } - if ((!dev->sector_len) || (*BufLen == 0)) { + if (!dev->sector_len) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev); + scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); break; } max_len = dev->sector_len; + /* + If we're reading all blocks in one go for DMA, why not also for + PIO, it should NOT matter anyway, this step should be identical + and only the way the read dat is transferred to the host should + be different. + */ dev->requested_blocks = max_len; - alloc_length = dev->packet_len = max_len << 9; + dev->packet_len = max_len * alloc_length; scsi_disk_buf_alloc(dev, dev->packet_len); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > (uint32_t) *BufLen) - hdd_image_read(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); - else - hdd_image_read(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + + ret = scsi_disk_blocks(dev, &alloc_length, 1, 0); + if (ret <= 0) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); + scsi_disk_buf_free(dev); + return; } - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + scsi_disk_data_command_finish(dev, alloc_length, 512, alloc_length, 0); + + ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_VERIFY_6: @@ -710,72 +1066,91 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_command_complete(dev); break; } + fallthrough; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + alloc_length = 512; + switch (cdb[0]) { case GPCMD_VERIFY_6: case GPCMD_WRITE_6: dev->sector_len = cdb[4]; + /* + For READ (6) and WRITE (6), a length of 0 indicates a + transfer of 256 sectors. + */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, + dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_10: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, + dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + + default: break; } - if ((dev->sector_pos > last_sector) /* || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/ - ) { + if (dev->sector_pos > last_sector) { scsi_disk_lba_out_of_range(dev); return; } - if ((!dev->sector_len) || (*BufLen == 0)) { + if (!dev->sector_len) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); break; } + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + max_len = dev->sector_len; + /* + If we're writing all blocks in one go for DMA, why not also for + PIO, it should NOT matter anyway, this step should be identical + and only the way the read dat is transferred to the host should + be different. + */ dev->requested_blocks = max_len; - alloc_length = dev->packet_len = max_len << 9; + dev->packet_len = max_len * alloc_length; scsi_disk_buf_alloc(dev, dev->packet_len); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + dev->requested_blocks = max_len; + dev->packet_len = max_len << 9; - if (dev->requested_blocks > 1) - scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); - else - scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + scsi_disk_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); + + ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_WRITE_SAME_10: - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); alloc_length = 512; if ((cdb[1] & 6) == 6) { @@ -786,42 +1161,43 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - if ((dev->sector_pos > last_sector) /* || - ((dev->sector_pos + dev->sector_len - 1) > last_sector)*/ - ) { + if (dev->sector_pos > last_sector) { scsi_disk_lba_out_of_range(dev); return; } - if ((!dev->sector_len) || (*BufLen == 0)) { + if (!dev->sector_len) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); break; } scsi_disk_buf_alloc(dev, alloc_length); - scsi_disk_set_buf_len(dev, BufLen, &alloc_length); + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); max_len = 1; dev->requested_blocks = 1; + dev->packet_len = alloc_length; + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); scsi_disk_data_command_finish(dev, 512, 512, alloc_length, 1); - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_HDD | dev->drv->bus, 1); - else - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); + ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); return; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + if (dev->drv->bus == HDD_BUS_SCSI) + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + else + block_desc = 0; if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; @@ -954,8 +1330,8 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) memset(dev->temp_buffer, 0, 8); dev->temp_buffer[0] = 0; /*SCSI HD*/ dev->temp_buffer[1] = 0; /*Fixed*/ - dev->temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - dev->temp_buffer[3] = 0x02; + dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; dev->temp_buffer[4] = 31; dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ dev->temp_buffer[7] = 0x20; /* Wide bus supported */ @@ -1001,7 +1377,14 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_SEEK_10: pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; + + default: + break; } + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = 0; + scsi_disk_seek(dev, pos); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); @@ -1031,7 +1414,11 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; } - /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ + /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, + dev->tf->request_length); */ + + if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) + scsi_disk_buf_free(dev); } static void @@ -1046,26 +1433,27 @@ scsi_disk_command_stop(scsi_common_t *sc) static uint8_t scsi_disk_phase_data_out(scsi_common_t *sc) { - scsi_disk_t *dev = (scsi_disk_t *) sc; - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; - int i; - int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - uint32_t last_sector = hdd_image_get_last_sector(dev->id); - uint32_t c; - uint32_t h; - uint32_t s; - uint32_t last_to_write = 0; - uint16_t block_desc_len; - uint16_t pos; - uint16_t param_list_len; - uint8_t hdr_len; - uint8_t val; - uint8_t old_val; - uint8_t ch; - uint8_t error = 0; - uint8_t page; - uint8_t page_len; + scsi_disk_t *dev = (scsi_disk_t *) sc; + uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + int i; + const int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + uint32_t last_sector = hdd_image_get_last_sector(dev->id); + uint32_t c; + uint32_t h; + uint32_t s; + int len = 0; + uint32_t last_to_write = 0; + uint16_t block_desc_len; + uint16_t pos; + uint16_t param_list_len; + uint8_t hdr_len; + uint8_t val; + uint8_t old_val; + uint8_t ch; + uint8_t error = 0; + uint8_t page; + uint8_t page_len; if (!*BufLen) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); @@ -1083,12 +1471,8 @@ scsi_disk_phase_data_out(scsi_common_t *sc) case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - if ((dev->requested_blocks > 0) && (*BufLen > 0)) { - if (dev->packet_len > (uint32_t) *BufLen) - hdd_image_write(dev->id, dev->sector_pos, *BufLen >> 9, dev->temp_buffer); - else - hdd_image_write(dev->id, dev->sector_pos, dev->requested_blocks, dev->temp_buffer); - } + if (dev->requested_blocks > 0) + scsi_disk_blocks(dev, &len, 1, 1); break; case GPCMD_WRITE_SAME_10: if (!dev->current_cdb[7] && !dev->current_cdb[8]) @@ -1130,15 +1514,18 @@ scsi_disk_phase_data_out(scsi_common_t *sc) param_list_len = dev->current_cdb[4]; } - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = dev->temp_buffer[2]; - block_desc_len <<= 8; - block_desc_len |= dev->temp_buffer[3]; - } else { - block_desc_len = dev->temp_buffer[6]; - block_desc_len <<= 8; - block_desc_len |= dev->temp_buffer[7]; - } + if (dev->drv->bus == HDD_BUS_SCSI) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = dev->temp_buffer[2]; + block_desc_len <<= 8; + block_desc_len |= dev->temp_buffer[3]; + } else { + block_desc_len = dev->temp_buffer[6]; + block_desc_len <<= 8; + block_desc_len |= dev->temp_buffer[7]; + } + } else + block_desc_len = 0; pos = hdr_len + block_desc_len; @@ -1193,15 +1580,99 @@ scsi_disk_phase_data_out(scsi_common_t *sc) return 1; } +static int +scsi_disk_get_max(int ide_has_dma, int type) +{ + int ret; + + switch (type) { + case TYPE_PIO: + ret = ide_has_dma ? 4 : 0; + break; + case TYPE_SDMA: + ret = ide_has_dma ? 2 : -1; + break; + case TYPE_MDMA: + ret = ide_has_dma ? 2 : -1; + break; + case TYPE_UDMA: + ret = ide_has_dma ? 5 : -1; + break; + default: + ret = -1; + break; + } + + return ret; +} + +static int +scsi_disk_get_timings(int ide_has_dma, int type) +{ + int ret; + + switch (type) { + case TIMINGS_DMA: + ret = ide_has_dma ? 120 : 0; + break; + case TIMINGS_PIO: + ret = ide_has_dma ? 120 : 0; + break; + case TIMINGS_PIO_FC: + ret = 0; + break; + default: + ret = 0; + break; + } + + return ret; +} + +/** + * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command + */ +static void +scsi_disk_identify(ide_t *ide, int ide_has_dma) +{ + const scsi_disk_t *dev; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + + dev = (scsi_disk_t *) ide->sc; + + device_identify[7] = dev->id + 0x30; + scsi_disk_log("ATAPI Identify: %s\n", device_identify); + + /* ATAPI device, direct-access device, non-removable media, accelerated DRQ */ + ide->buffer[0] = 0x8000 | (0 << 8) | 0x00 | (2 << 5); + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ + + ide->buffer[49] = 0x200; /* LBA supported */ + ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + + if (ide_has_dma) { + ide->buffer[71] = 30; + ide->buffer[72] = 30; + ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ + ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ + } +} + void scsi_disk_hard_reset(void) { scsi_disk_t *dev; scsi_device_t *sd; + ide_t *id; uint8_t scsi_bus; uint8_t scsi_id; + uint8_t valid = 0; for (uint8_t c = 0; c < HDD_NUM; c++) { + valid = 0; if (hdd[c].bus == HDD_BUS_SCSI) { scsi_disk_log("SCSI disk hard_reset drive=%d\n", c); @@ -1224,13 +1695,18 @@ scsi_disk_hard_reset(void) if (!hdd_image_load(c)) continue; - if (!hdd[c].priv) { - hdd[c].priv = (scsi_disk_t *) malloc(sizeof(scsi_disk_t)); - memset(hdd[c].priv, 0, sizeof(scsi_disk_t)); - } + valid = 1; + + hdd_preset_apply(c); + + if (!hdd[c].priv) + hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t)); dev = (scsi_disk_t *) hdd[c].priv; + if (!dev->tf) + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); + /* SCSI disk, attach to the SCSI bus. */ sd = &scsi_devices[scsi_bus][scsi_id]; @@ -1242,14 +1718,60 @@ scsi_disk_hard_reset(void) sd->command_stop = scsi_disk_command_stop; sd->type = SCSI_FIXED_DISK; - dev->id = c; - dev->drv = &hdd[c]; + scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); + } else if (hdd[c].bus == HDD_BUS_ATAPI) { + /* Make sure to ignore any SCSI disk whose image file name is empty. */ + if (strlen(hdd[c].fn) == 0) + continue; + + /* Make sure to ignore any SCSI disk whose image fails to load. */ + /* ATAPI hard disk, attach to the IDE bus. */ + id = ide_get_drive(hdd[c].ide_channel); + /* If the IDE channel is initialized, we attach to it, + otherwise, we do nothing - it's going to be a drive + that's not attached to anything. */ + if (id) { + if (!hdd_image_load(c)) + continue; + + valid = 1; + + hdd_preset_apply(c); + + if (!hdd[c].priv) + hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t)); + + dev = (scsi_disk_t *) hdd[c].priv; + + id->sc = (scsi_common_t *) dev; + dev->tf = id->tf; + IDE_ATAPI_IS_EARLY = 0; + id->get_max = scsi_disk_get_max; + id->get_timings = scsi_disk_get_timings; + id->identify = scsi_disk_identify; + id->stop = NULL; + id->packet_command = scsi_disk_command; + id->device_reset = scsi_disk_reset; + id->phase_data_out = scsi_disk_phase_data_out; + id->command_stop = scsi_disk_command_stop; + id->bus_master_error = scsi_disk_bus_master_error; + id->interrupt_drq = 0; + + ide_atapi_attach(id); + } + + scsi_disk_log("ATAPI hard disk drive %i attached to IDE channel %i\n", c, hdd[c].ide_channel); + } + + if (valid) { + dev->id = c; + dev->drv = &hdd[c]; dev->cur_lun = SCSI_LUN_USE_CDB; - scsi_disk_mode_sense_load(dev); + scsi_disk_init(dev); - scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); + scsi_disk_mode_sense_load(dev); } } } @@ -1262,17 +1784,22 @@ scsi_disk_close(void) uint8_t scsi_id; for (uint8_t c = 0; c < HDD_NUM; c++) { - if (hdd[c].bus == HDD_BUS_SCSI) { - scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; - scsi_id = hdd[c].scsi_id & 0x0f; + if ((hdd[c].bus == HDD_BUS_SCSI) || (hdd[c].bus == HDD_BUS_ATAPI)) { + if (hdd[c].bus == HDD_BUS_SCSI) { + scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; + scsi_id = hdd[c].scsi_id & 0x0f; - memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); + memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); + } hdd_image_close(c); dev = hdd[c].priv; if (dev) { + if (dev->tf) + free(dev->tf); + free(dev); hdd[c].priv = NULL; } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 2d21592c90..e9ebe85044 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -93,9 +93,15 @@ #define STATUS_BUFFER_NOT_READY 0x04 #define STATUS_53C80_ACCESSIBLE 0x80 -typedef struct { - uint8_t icr, mode, tcr, data_wait; - uint8_t isr, output_data, target_id, tx_data; +typedef struct ncr_t { + uint8_t icr; + uint8_t mode; + uint8_t tcr; + uint8_t data_wait; + uint8_t isr; + uint8_t output_data; + uint8_t target_id; + uint8_t tx_data; uint8_t msglun; uint8_t command[20]; @@ -103,12 +109,19 @@ typedef struct { int msgout_pos; int is_msgout; - int dma_mode, cur_bus, bus_in, new_phase; - int state, clear_req, wait_data, wait_complete; - int command_pos, data_pos; + int dma_mode; + int cur_bus; + int bus_in; + int new_phase; + int state; + int clear_req; + int wait_data; + int wait_complete; + int command_pos; + int data_pos; } ncr_t; -typedef struct { +typedef struct t128_t { uint8_t ctrl; uint8_t status; uint8_t buffer[512]; @@ -121,14 +134,15 @@ typedef struct { int bios_enabled; } t128_t; -typedef struct { +typedef struct ncr5380_t { ncr_t ncr; t128_t t128; const char *name; uint8_t buffer[128]; - uint8_t int_ram[0x40], ext_ram[0x600]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; uint32_t rom_addr; uint16_t base; @@ -171,7 +185,7 @@ typedef struct { #define DMA_SEND 1 #define DMA_INITIATOR_RECEIVE 2 -static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 6, 6 }; +static int cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; @@ -193,12 +207,6 @@ ncr_log(const char *fmt, ...) #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) -static void -ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev); - -static void -ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev); - static void ncr_callback(void *priv); @@ -242,7 +250,7 @@ static void ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) { memset(ncr, 0x00, sizeof(ncr_t)); - ncr_log("NCR reset\n"); + ncr_log("NCR Reset\n"); timer_stop(&ncr_dev->timer); @@ -252,27 +260,6 @@ ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) ncr_irq(ncr_dev, ncr, 0); } -static void -ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) -{ - double p = ncr_dev->period; - - if (ncr->data_wait & 2) - ncr->data_wait &= ~2; - - if (callback) { - if (ncr_dev->type == 3) - p *= 512.0; - else - p *= 128.0; - } - - p += 1.0; - - ncr_log("P = %lf, command = %02x, callback = %i, period = %lf, t128 pos = %i\n", p, ncr->command[0], callback, ncr_dev->period, ncr_dev->t128.host_pos); - timer_on_auto(&ncr_dev->timer, p); -} - static uint32_t get_bus_host(ncr_t *ncr) { @@ -314,9 +301,9 @@ get_bus_host(ncr_t *ncr) static void ncr_bus_read(ncr5380_t *ncr_dev) { - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev; - int phase; + ncr_t *ncr = &ncr_dev->ncr; + const scsi_device_t *dev; + int phase; /*Wait processes to handle bus requests*/ if (ncr->clear_req) { @@ -440,7 +427,9 @@ ncr_bus_update(void *priv, int bus) if (ncr->command_pos == cmd_len[(ncr->command[0] >> 5) & 7]) { if (ncr->is_msgout) { ncr->is_msgout = 0; - // ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); +#if 0 + ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); +#endif } /*Reset data position to default*/ @@ -461,13 +450,8 @@ ncr_bus_update(void *priv, int bus) /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { p = scsi_device_get_callback(dev); - if (p <= 0.0) { - ncr_dev->period = 0.2; - } else { - ncr_dev->period = p / ((double) dev->buffer_length); - } - ncr->data_wait |= 2; - ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i\n", ncr->target_id, ncr->command[0], p, ncr_dev->period, dev->buffer_length); + ncr_dev->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); + ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr_dev->period, dev->buffer_length, ncr->dma_mode); } } ncr->new_phase = dev->phase; @@ -486,14 +470,15 @@ ncr_bus_update(void *priv, int bus) } else { ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; - if (ncr->data_wait & 2) - ncr->data_wait &= ~2; if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr_log("DMA mode idle in\n"); timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else + } else { + ncr_log("DMA mode IN.\n"); ncr->clear_req = 3; + } + ncr->cur_bus &= ~BUS_REQ; ncr->new_phase = SCSI_PHASE_DATA_IN; } @@ -516,9 +501,9 @@ ncr_bus_update(void *priv, int bus) ncr->data_wait |= 1; ncr_log("DMA mode idle out\n"); timer_on_auto(&ncr_dev->timer, ncr_dev->period); - } else { + } else ncr->clear_req = 3; - } + ncr->cur_bus &= ~BUS_REQ; ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); } @@ -565,6 +550,9 @@ ncr_bus_update(void *priv, int bus) SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); } break; + + default: + break; } ncr->bus_in = bus; @@ -573,10 +561,10 @@ ncr_bus_update(void *priv, int bus) static void ncr_write(uint16_t port, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - int bus_host = 0; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + int bus_host = 0; ncr_log("NCR5380 write(%04x,%02x)\n", port & 7, val); @@ -608,7 +596,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*Don't stop the timer until it finishes the transfer*/ if (ncr_dev->t128.block_loaded && (ncr->mode & MODE_DMA)) { ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); + timer_on_auto(&ncr_dev->timer, ncr_dev->period + 1.0); } /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -619,12 +607,6 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr->dma_mode = DMA_IDLE; } } else { - /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - ncr_log("Continuing DMA mode\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } - /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { ncr_log("No DMA mode\n"); @@ -649,22 +631,16 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; if (ncr_dev->type == 3) { - if (dev->buffer_length > 0) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - - ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); - ncr_dev->t128.block_count = dev->buffer_length >> 9; - ncr_dev->t128.block_loaded = 1; - - ncr_dev->t128.host_pos = 0; ncr_dev->t128.status |= 0x04; - } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.block_count = dev->buffer_length >> 9; - ncr_log("DMA send timer on\n"); - ncr_timer_on(ncr_dev, ncr, 0); + if (dev->buffer_length < 512) + ncr_dev->t128.block_count = 1; + + ncr_dev->t128.block_loaded = 1; } } break; @@ -674,28 +650,18 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; if (ncr_dev->type == 3) { - ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0], dev->buffer_length); - if (dev->buffer_length > 0) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - + ncr_dev->t128.status |= 0x04; + ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); ncr_dev->t128.block_count = dev->buffer_length >> 9; if (dev->buffer_length < 512) ncr_dev->t128.block_count = 1; ncr_dev->t128.block_loaded = 1; - - ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); - ncr_dev->t128.status |= 0x04; timer_on_auto(&ncr_dev->timer, 0.02); } - } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { - memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); - - ncr_log("DMA receive timer start\n"); - ncr_timer_on(ncr_dev, ncr, 0); - } } break; @@ -704,10 +670,8 @@ ncr_write(uint16_t port, uint8_t val, void *priv) break; } - if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0 || ncr_dev->type >= 3) { - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); - } + bus_host = get_bus_host(ncr); + ncr_bus_update(priv, bus_host); } static uint8_t @@ -823,17 +787,17 @@ ncr_read(uint16_t port, void *priv) ncr_log("NCR5380 read(%04x)=%02x\n", port & 7, ret); - return (ret); + return ret; } /* Memory-mapped I/O READ handler. */ static uint8_t memio_read(uint32_t addr, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - uint8_t ret = 0xff; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + uint8_t ret = 0xff; addr &= 0x3fff; @@ -860,10 +824,12 @@ memio_read(uint32_t addr, void *priv) break; case 0x3900: - if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { + if (ncr_dev->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr_dev->status_ctrl & CTRL_DATA_DIR))) { ret = 0xff; + ncr_log("No Read.\n"); } else { ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; + ncr_log("Read host pos = %i, ret = %02x\n", ncr_dev->buffer_host_pos, ret); if (ncr_dev->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -893,14 +859,18 @@ memio_read(uint32_t addr, void *priv) break; case 0x3982: /* switch register read */ - ret = 0xff; + ret = 0xf8; + ret |= (ncr_dev->irq & 0x07); + ncr_log("Switches read=%02x.\n", ret); break; - case 0x3983: - ret = 0xff; + default: break; } break; + + default: + break; } #if ENABLE_NCR5380_LOG @@ -915,9 +885,9 @@ memio_read(uint32_t addr, void *priv) static void memio_write(uint32_t addr, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + ncr_t *ncr = &ncr_dev->ncr; + scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; addr &= 0x3fff; @@ -961,13 +931,10 @@ memio_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period); + ncr_log("Write block counter register: val=%d, dma mode=%x, period=%lf\n", val, ncr->dma_mode, ncr_dev->period); ncr_dev->block_count = val; ncr_dev->block_count_loaded = 1; - if (ncr->mode & MODE_DMA) - ncr_timer_on(ncr_dev, ncr, 0); - if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length); ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -975,9 +942,20 @@ memio_write(uint32_t addr, uint8_t val, void *priv) ncr_dev->buffer_host_pos = 0; ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; } + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer) && (dev->buffer_length > 0)) { + memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); + ncr_log("DMA timer on\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); + } + break; + + default: break; } break; + + default: + break; } } @@ -985,8 +963,8 @@ memio_write(uint32_t addr, uint8_t val, void *priv) static uint8_t t130b_read(uint32_t addr, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - uint8_t ret = 0xff; + const ncr5380_t *ncr_dev = (ncr5380_t *) priv; + uint8_t ret = 0xff; addr &= 0x3fff; if (addr < 0x1800) @@ -995,7 +973,7 @@ t130b_read(uint32_t addr, void *priv) ret = ncr_dev->ext_ram[addr & 0x7f]; ncr_log("MEM: Reading %02X from %08X\n", ret, addr); - return (ret); + return ret; } /* Memory-mapped I/O WRITE handler for the Trantor T130B. */ @@ -1039,10 +1017,13 @@ t130b_in(uint16_t port, void *priv) case 0x0f: ret = ncr_read(port, ncr_dev); break; + + default: + break; } ncr_log("I/O: Reading %02X from %04X\n", ret, port); - return (ret); + return ret; } static void @@ -1075,161 +1056,10 @@ t130b_out(uint16_t port, uint8_t val, void *priv) case 0x0f: ncr_write(port, val, ncr_dev); break; - } -} - -static void -ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) -{ - int bus; - uint8_t data; - - if (scsi_device_get_callback(dev) > 0.0) - ncr_timer_on(ncr_dev, ncr, 1); - else - ncr_timer_on(ncr_dev, ncr, 0); - - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - /* Data ready. */ - if (ncr_dev->type == 3) - data = ncr_dev->t128.buffer[ncr_dev->t128.pos]; - else - data = ncr_dev->buffer[ncr_dev->buffer_pos]; - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(data); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - if (ncr_dev->type == 3) { - ncr_dev->t128.pos++; - ncr_log("Buffer pos for writing = %d, data = %02x\n", ncr_dev->t128.pos, data); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer_pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of write transfer\n"); - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } - ncr_dma_send(ncr_dev, ncr, dev); -} -static void -ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev) -{ - int bus; - uint8_t temp; - - if (scsi_device_get_callback(dev) > 0.0) { - ncr_timer_on(ncr_dev, ncr, 1); - } else { - ncr_timer_on(ncr_dev, ncr, 0); - } - - for (uint8_t c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) + default: break; } - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(ncr_dev, bus | BUS_ACK); - ncr_bus_update(ncr_dev, bus & ~BUS_ACK); - - if (ncr_dev->type == 3) { - ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; - ncr_log("Buffer pos for reading = %d, temp = %02x\n", ncr_dev->t128.pos, temp); - - if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { - ncr_dev->t128.pos = 0; - ncr_dev->t128.host_pos = 0; - ncr_dev->t128.status &= ~0x02; - ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); - if (!ncr_dev->t128.block_count) { - ncr_dev->t128.block_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } else { - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - ncr_log("IO End of read transfer\n"); - ncr->isr |= STATUS_END_OF_DMA; - timer_stop(&ncr_dev->timer); - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr_irq(ncr_dev, ncr, 1); - } - } - return; - } - } - ncr_dma_initiator_receive(ncr_dev, ncr, dev); } static void @@ -1238,31 +1068,37 @@ ncr_callback(void *priv) ncr5380_t *ncr_dev = (ncr5380_t *) priv; ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; - - if (ncr_dev->type == 3) { - ncr_log("DMA Callback, load = %i\n", ncr_dev->t128.block_loaded); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { - ncr_log("Timer on! Host POS = %i, status = %02x, DMA mode = %i, Period = %lf\n", ncr_dev->t128.host_pos, ncr_dev->t128.status, ncr->dma_mode, scsi_device_get_callback(dev)); - if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length) && ncr_dev->t128.block_count) { - ncr_dev->t128.status |= 0x04; - } - ncr_timer_on(ncr_dev, ncr, 0); - } + int bus; + int bytes_tx = 0; + int limit = 100; + uint8_t temp; + + if (ncr_dev->type != 3) { + if (ncr->dma_mode != DMA_IDLE) + timer_on_auto(&ncr_dev->timer, 1.0); } else { - ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl); - if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded) { - ncr_timer_on(ncr_dev, ncr, 0); + if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && ncr_dev->t128.block_loaded) { + if ((ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) && ncr_dev->t128.block_count) + ncr_dev->t128.status |= 0x04; + + timer_on_auto(&ncr_dev->timer, ncr_dev->period / 55.0); } } if (ncr->data_wait & 1) { ncr->clear_req = 3; ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) { - return; + if (ncr_dev->type == 3) { + if (ncr->dma_mode == DMA_IDLE) + return; } } + if (ncr_dev->type != 3) { + if (ncr->dma_mode == DMA_IDLE) + return; + } + switch (ncr->dma_mode) { case DMA_SEND: if (ncr_dev->type != 3) { @@ -1278,9 +1114,52 @@ ncr_callback(void *priv) if (!ncr_dev->block_count_loaded) break; + + while (bytes_tx < limit) { + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = ncr_dev->buffer[ncr_dev->buffer_pos]; + + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer_pos++; + bytes_tx++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); + + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + bytes_tx = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->ncr_busy = 0; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } + } } else { if (!(ncr_dev->t128.status & 0x04)) { - ncr_log("Write status busy\n"); + ncr_log("Write status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); break; } @@ -1291,8 +1170,48 @@ ncr_callback(void *priv) if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) break; + +write_again: + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + temp = ncr_dev->t128.buffer[ncr_dev->t128.pos]; + + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(temp); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->t128.pos++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->t128.pos); + + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->ncr_busy = 0; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->t128.block_count); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } else + goto write_again; } - ncr_dma_send(ncr_dev, ncr, dev); break; case DMA_INITIATOR_RECEIVE: @@ -1309,6 +1228,47 @@ ncr_callback(void *priv) if (!ncr_dev->block_count_loaded) break; + + while (bytes_tx < limit) { + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr_bus_read(ncr_dev); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = get_bus_host(ncr); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; + ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); + bytes_tx++; + + if (ncr_dev->buffer_pos == MIN(128, dev->buffer_length)) { + bytes_tx = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } + } } else { if (!(ncr_dev->t128.status & 0x04)) { ncr_log("Read status busy, block count = %i, host pos = %i\n", ncr_dev->t128.block_count, ncr_dev->t128.host_pos); @@ -1322,8 +1282,49 @@ ncr_callback(void *priv) if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) break; + +read_again: + for (uint8_t c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + /* Data ready. */ + ncr_bus_read(ncr_dev); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = get_bus_host(ncr); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->t128.buffer[ncr_dev->t128.pos++] = temp; + ncr_log("Buffer pos for reading=%d, temp=%02x, len=%d.\n", ncr_dev->t128.pos, temp, dev->buffer_length); + + if (ncr_dev->t128.pos == MIN(512, dev->buffer_length)) { + ncr_dev->t128.pos = 0; + ncr_dev->t128.host_pos = 0; + ncr_dev->t128.status &= ~0x02; + ncr_dev->t128.block_count = (ncr_dev->t128.block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d, status=%02x, len=%i, cdb[0] = %02x\n", ncr_dev->t128.block_count, ncr_dev->t128.status, dev->buffer_length, ncr->command[0]); + if (!ncr_dev->t128.block_count) { + ncr_dev->t128.block_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + break; + } else + goto read_again; } - ncr_dma_initiator_receive(ncr_dev, ncr, dev); + break; + + default: break; } @@ -1333,7 +1334,8 @@ ncr_callback(void *priv) ncr_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - timer_on_auto(&ncr_dev->timer, 10.0); + if (ncr_dev->type == 3) + timer_on_auto(&ncr_dev->timer, 10.0); } } @@ -1341,36 +1343,41 @@ static uint8_t t128_read(uint32_t addr, void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; + const ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; uint8_t ret = 0xff; addr &= 0x3fff; - if (addr >= 0 && addr < 0x1800) + if (ncr_dev->t128.bios_enabled && (addr >= 0) && (addr < 0x1800)) ret = ncr_dev->bios_rom.rom[addr & 0x1fff]; - else if (addr >= 0x1800 && addr < 0x1880) + else if ((addr >= 0x1800) && (addr < 0x1880)) ret = ncr_dev->t128.ext_ram[addr & 0x7f]; - else if (addr >= 0x1c00 && addr < 0x1c20) { + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { ret = ncr_dev->t128.ctrl; - } else if (addr >= 0x1c20 && addr < 0x1c40) { + ncr_log("T128 ctrl read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1c20) && (addr < 0x1c40)) { ret = ncr_dev->t128.status; - ncr_log("T128 status read = %02x, cur bus = %02x, req = %02x, dma = %02x\n", ret, ncr->cur_bus, ncr->cur_bus & BUS_REQ, ncr->mode & MODE_DMA); - } else if (addr >= 0x1d00 && addr < 0x1e00) { + ncr_log("T128 status read=%02x, dma=%02x\n", ret, ncr->mode & MODE_DMA); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) ret = ncr_read((addr - 0x1d00) >> 5, ncr_dev); - } else if (addr >= 0x1e00 && addr < 0x2000) { - if (ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length) || ncr->dma_mode != DMA_INITIATOR_RECEIVE) { + else if (addr >= 0x1e00 && addr < 0x2000) { + if ((ncr_dev->t128.host_pos >= MIN(512, dev->buffer_length)) || + (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) ret = 0xff; - } else { + else { ret = ncr_dev->t128.buffer[ncr_dev->t128.host_pos++]; - ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, ncr_dev->t128.host_pos); + ncr_log("Read transfer, addr = %i, pos = %i\n", addr & 0x1ff, + ncr_dev->t128.host_pos); if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { ncr_dev->t128.status &= ~0x04; - ncr_log("Transfer busy read, status = %02x, period = %lf\n", ncr_dev->t128.status, ncr_dev->period); - if (ncr_dev->period == 0.2 || ncr_dev->period == 0.02) + ncr_log("Transfer busy read, status = %02x, period = %lf\n", + ncr_dev->t128.status, ncr_dev->period); + if ((ncr_dev->period == 0.2) || (ncr_dev->period == 0.02)) timer_on_auto(&ncr_dev->timer, 40.2); - } else if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && scsi_device_get_callback(dev) > 100.0) + } else if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && + (scsi_device_get_callback(dev) > 100.0)) cycles += 100; /*Needed to avoid timer de-syncing with transfers.*/ } } @@ -1381,43 +1388,44 @@ t128_read(uint32_t addr, void *priv) static void t128_write(uint32_t addr, uint8_t val, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; - ncr_t *ncr = &ncr_dev->ncr; - scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; + ncr5380_t *ncr_dev = (ncr5380_t *) priv; + const ncr_t *ncr = &ncr_dev->ncr; + const scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id]; addr &= 0x3fff; - if (addr >= 0x1800 && addr < 0x1880) + if ((addr >= 0x1800) && (addr < 0x1880)) ncr_dev->t128.ext_ram[addr & 0x7f] = val; - else if (addr >= 0x1c00 && addr < 0x1c20) { - if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) { + else if ((addr >= 0x1c00) && (addr < 0x1c20)) { + if ((val & 0x02) && !(ncr_dev->t128.ctrl & 0x02)) ncr_dev->t128.status |= 0x02; - ncr_log("Timer fired\n"); - } + ncr_dev->t128.ctrl = val; - ncr_log("T128 ctrl write = %02x\n", val); - } else if (addr >= 0x1d00 && addr < 0x1e00) + ncr_log("T128 ctrl write=%02x\n", val); + } else if ((addr >= 0x1d00) && (addr < 0x1e00)) ncr_write((addr - 0x1d00) >> 5, val, ncr_dev); - else if (addr >= 0x1e00 && addr < 0x2000) { - if (ncr_dev->t128.host_pos < MIN(512, dev->buffer_length) && ncr->dma_mode == DMA_SEND) { + else if ((addr >= 0x1e00) && (addr < 0x2000)) { + if ((ncr_dev->t128.host_pos < MIN(512, dev->buffer_length)) && + (ncr->dma_mode == DMA_SEND)) { ncr_dev->t128.buffer[ncr_dev->t128.host_pos] = val; ncr_dev->t128.host_pos++; - ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", addr & 0x1ff, ncr_dev->t128.host_pos, val); + ncr_log("Write transfer, addr = %i, pos = %i, val = %02x\n", + addr & 0x1ff, ncr_dev->t128.host_pos, val); if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { ncr_dev->t128.status &= ~0x04; + ncr_dev->ncr_busy = 1; ncr_log("Transfer busy write, status = %02x\n", ncr_dev->t128.status); timer_on_auto(&ncr_dev->timer, 0.02); } - } else - ncr_log("Write PDMA addr = %i, val = %02x\n", addr & 0x1ff, val); + } } } static uint8_t rt1000b_mc_read(int port, void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; + const ncr5380_t *ncr_dev = (ncr5380_t *) priv; return (ncr_dev->pos_regs[port & 7]); } @@ -1457,6 +1465,9 @@ rt1000b_mc_write(int port, uint8_t val, void *priv) case 0xe0: ncr_dev->rom_addr = 0xd8000; break; + + default: + break; } mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000); @@ -1467,7 +1478,7 @@ rt1000b_mc_write(int port, uint8_t val, void *priv) static uint8_t rt1000b_mc_feedb(void *priv) { - ncr5380_t *ncr_dev = (ncr5380_t *) priv; + const ncr5380_t *ncr_dev = (ncr5380_t *) priv; return ncr_dev->pos_regs[2] & 1; } @@ -1475,9 +1486,9 @@ rt1000b_mc_feedb(void *priv) static void * ncr_init(const device_t *info) { - char *fn = NULL; - char temp[128]; - ncr5380_t *ncr_dev; + const char *fn = NULL; + char temp[128]; + ncr5380_t *ncr_dev; ncr_dev = malloc(sizeof(ncr5380_t)); memset(ncr_dev, 0x00, sizeof(ncr5380_t)); @@ -1508,10 +1519,14 @@ ncr_init(const device_t *info) ncr_dev->bios_ver = 1; } - if (ncr_dev->bios_ver == 1) - fn = RT1000B_820R_ROM; - else - fn = RT1000B_810R_ROM; + switch (ncr_dev->bios_ver) { + case 0: + fn = RT1000B_810R_ROM; + break; + case 1: + fn = RT1000B_820R_ROM; + break; + } rom_init(&ncr_dev->bios_rom, fn, ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); @@ -1577,6 +1592,9 @@ ncr_init(const device_t *info) memio_write, NULL, NULL, ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev); break; + + default: + break; } sprintf(temp, "%s: BIOS=%05X", ncr_dev->name, ncr_dev->rom_addr); @@ -1586,19 +1604,19 @@ ncr_init(const device_t *info) sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); ncr_log("%s\n", temp); - ncr_reset(ncr_dev, &ncr_dev->ncr); - if (ncr_dev->type < 3 || ncr_dev->type == 4) { - ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; - ncr_dev->buffer_host_pos = 128; + if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) { + ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr_dev->buffer_host_pos = 128; } else { - ncr_dev->t128.status = 0x04; - ncr_dev->t128.host_pos = 512; - + ncr_dev->t128.status = 0x04; + ncr_dev->t128.host_pos = 512; if (!ncr_dev->t128.bios_enabled) ncr_dev->t128.status |= 0x80; } timer_add(&ncr_dev->timer, ncr_callback, ncr_dev, 0); + scsi_bus_set_speed(ncr_dev->bus, 5000000.0); + return ncr_dev; } diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 482e098e34..42925338d9 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -204,7 +204,7 @@ typedef enum { SCSI_STATE_WRITE_MESSAGE } scsi_state_t; -typedef struct { +typedef struct ncr53c8xx_t { char *nvr_path; uint8_t pci_slot; uint8_t chip, wide; @@ -234,6 +234,7 @@ typedef struct { int waiting; uint8_t current_lun; + uint8_t irq_state; uint8_t istat; uint8_t dcmd; @@ -291,9 +292,16 @@ typedef struct { uint32_t dbc; uint32_t dsp; uint32_t dsps; - uint32_t scratcha, scratchb, scratchc, scratchd; - uint32_t scratche, scratchf, scratchg, scratchh; - uint32_t scratchi, scratchj; + uint32_t scratcha; + uint32_t scratchb; + uint32_t scratchc; + uint32_t scratchd; + uint32_t scratche; + uint32_t scratchf; + uint32_t scratchg; + uint32_t scratchh; + uint32_t scratchi; + uint32_t scratchj; int last_level; void *hba_private; uint32_t buffer_pos; @@ -479,7 +487,7 @@ ncr53c8xx_write(ncr53c8xx_t *dev, uint32_t addr, uint8_t *buf, uint32_t len) } static __inline uint32_t -read_dword(ncr53c8xx_t *dev, uint32_t addr) +read_dword(UNUSED(ncr53c8xx_t *dev), uint32_t addr) { uint32_t buf; ncr53c8xx_log("Reading the next DWORD from memory (%08X)...\n", addr); @@ -491,10 +499,10 @@ static void do_irq(ncr53c8xx_t *dev, int level) { if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); ncr53c8xx_log("Raising IRQ...\n"); } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); ncr53c8xx_log("Lowering IRQ...\n"); } } @@ -527,12 +535,16 @@ ncr53c8xx_update_irq(ncr53c8xx_t *dev) level = 1; } +#ifdef STATE_KEEPING if (level != dev->last_level) { +#endif ncr53c8xx_log("Update IRQ level %d dstat %02x sist %02x%02x\n", level, dev->dstat, dev->sist1, dev->sist0); dev->last_level = level; do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */ +#ifdef STATE_KEEPING } +#endif } /* Stop SCRIPTS execution and raise a SCSI interrupt. */ @@ -578,7 +590,7 @@ ncr53c8xx_set_phase(ncr53c8xx_t *dev, int phase) } static void -ncr53c8xx_bad_phase(ncr53c8xx_t *dev, int out, int new_phase) +ncr53c8xx_bad_phase(ncr53c8xx_t *dev, UNUSED(int out), int new_phase) { /* Trigger a phase mismatch. */ ncr53c8xx_log("Phase mismatch interrupt\n"); @@ -603,7 +615,7 @@ ncr53c8xx_disconnect(ncr53c8xx_t *dev) } static void -ncr53c8xx_bad_selection(ncr53c8xx_t *dev, uint32_t id) +ncr53c8xx_bad_selection(ncr53c8xx_t *dev, UNUSED(uint32_t id)) { ncr53c8xx_log("Selected absent target %d\n", id); ncr53c8xx_script_scsi_interrupt(dev, 0, NCR_SIST1_STO); @@ -863,7 +875,7 @@ ncr53c8xx_skip_msgbytes(ncr53c8xx_t *dev, unsigned int n) } static void -ncr53c8xx_bad_message(ncr53c8xx_t *dev, uint8_t msg) +ncr53c8xx_bad_message(ncr53c8xx_t *dev, UNUSED(uint8_t msg)) { ncr53c8xx_log("Unimplemented message 0x%02x\n", msg); ncr53c8xx_set_phase(dev, PHASE_MI); @@ -1191,6 +1203,9 @@ ncr53c8xx_process_script(ncr53c8xx_t *dev) if (insn & (1 << 10)) dev->carry = 0; break; + + default: + break; } } else { reg = ((insn >> 16) & 0x7f) | (insn & 0x80); @@ -1216,6 +1231,9 @@ ncr53c8xx_process_script(ncr53c8xx_t *dev) else op1 = data8; break; + + default: + break; } switch (operator) { @@ -1252,6 +1270,9 @@ ncr53c8xx_process_script(ncr53c8xx_t *dev) else dev->carry = op0 < op1; break; + + default: + break; } switch (opcode) { @@ -1262,6 +1283,9 @@ ncr53c8xx_process_script(ncr53c8xx_t *dev) case 6: /* To SFBR */ dev->sfbr = op0; break; + + default: + break; } } break; @@ -1403,9 +1427,9 @@ ncr53c8xx_execute_script(ncr53c8xx_t *dev) } static void -ncr53c8xx_callback(void *p) +ncr53c8xx_callback(void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; if (!dev->sstop) { if (dev->waiting) @@ -1421,15 +1445,15 @@ ncr53c8xx_callback(void *p) static void ncr53c8xx_eeprom(ncr53c8xx_t *dev, uint8_t save) { - FILE *f; + FILE *fp; - f = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); - if (f) { + fp = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); + if (fp) { if (save) - fwrite(&dev->nvram, sizeof(dev->nvram), 1, f); + fwrite(&dev->nvram, sizeof(dev->nvram), 1, fp); else - (void) !fread(&dev->nvram, sizeof(dev->nvram), 1, f); - fclose(f); + (void) !fread(&dev->nvram, sizeof(dev->nvram), 1, fp); + fclose(fp); } } @@ -1559,7 +1583,9 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val) ncr53c8xx_log("Woken by SIGP\n"); dev->waiting = 0; dev->dsp = dev->dnad; - /* ncr53c8xx_execute_script(dev); */ +#if 0 + ncr53c8xx_execute_script(dev); +#endif } if ((val & NCR_ISTAT_SRST) && !(tmp & NCR_ISTAT_SRST)) { ncr53c8xx_soft_reset(dev); @@ -1978,6 +2004,9 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) CASE_GET_REG32_COND(scratchh, 0x74) CASE_GET_REG32_COND(scratchi, 0x78) CASE_GET_REG32_COND(scratchj, 0x7c) + + default: + break; } ncr53c8xx_log("readb 0x%x\n", offset); return 0; @@ -1987,16 +2016,17 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset) } static uint8_t -ncr53c8xx_io_readb(uint16_t addr, void *p) +ncr53c8xx_io_readb(uint16_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; + return ncr53c8xx_reg_readb(dev, addr & 0xff); } static uint16_t -ncr53c8xx_io_readw(uint16_t addr, void *p) +ncr53c8xx_io_readw(uint16_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint16_t val; addr &= 0xff; @@ -2006,9 +2036,9 @@ ncr53c8xx_io_readw(uint16_t addr, void *p) } static uint32_t -ncr53c8xx_io_readl(uint16_t addr, void *p) +ncr53c8xx_io_readl(uint16_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint32_t val; addr &= 0xff; @@ -2020,25 +2050,28 @@ ncr53c8xx_io_readl(uint16_t addr, void *p) } static void -ncr53c8xx_io_writeb(uint16_t addr, uint8_t val, void *p) +ncr53c8xx_io_writeb(uint16_t addr, uint8_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; + ncr53c8xx_reg_writeb(dev, addr & 0xff, val); } static void -ncr53c8xx_io_writew(uint16_t addr, uint16_t val, void *p) +ncr53c8xx_io_writew(uint16_t addr, uint16_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; + addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); } static void -ncr53c8xx_io_writel(uint16_t addr, uint32_t val, void *p) +ncr53c8xx_io_writel(uint16_t addr, uint32_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; + addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); ncr53c8xx_reg_writeb(dev, addr + 1, (val >> 8) & 0xff); @@ -2047,17 +2080,17 @@ ncr53c8xx_io_writel(uint16_t addr, uint32_t val, void *p) } static void -ncr53c8xx_mmio_writeb(uint32_t addr, uint8_t val, void *p) +ncr53c8xx_mmio_writeb(uint32_t addr, uint8_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; ncr53c8xx_reg_writeb(dev, addr & 0xff, val); } static void -ncr53c8xx_mmio_writew(uint32_t addr, uint16_t val, void *p) +ncr53c8xx_mmio_writew(uint32_t addr, uint16_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); @@ -2065,9 +2098,9 @@ ncr53c8xx_mmio_writew(uint32_t addr, uint16_t val, void *p) } static void -ncr53c8xx_mmio_writel(uint32_t addr, uint32_t val, void *p) +ncr53c8xx_mmio_writel(uint32_t addr, uint32_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; addr &= 0xff; ncr53c8xx_reg_writeb(dev, addr, val & 0xff); @@ -2077,17 +2110,17 @@ ncr53c8xx_mmio_writel(uint32_t addr, uint32_t val, void *p) } static uint8_t -ncr53c8xx_mmio_readb(uint32_t addr, void *p) +ncr53c8xx_mmio_readb(uint32_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; return ncr53c8xx_reg_readb(dev, addr & 0xff); } static uint16_t -ncr53c8xx_mmio_readw(uint32_t addr, void *p) +ncr53c8xx_mmio_readw(uint32_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint16_t val; addr &= 0xff; @@ -2097,9 +2130,9 @@ ncr53c8xx_mmio_readw(uint32_t addr, void *p) } static uint32_t -ncr53c8xx_mmio_readl(uint32_t addr, void *p) +ncr53c8xx_mmio_readl(uint32_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint32_t val; addr &= 0xff; @@ -2112,57 +2145,57 @@ ncr53c8xx_mmio_readl(uint32_t addr, void *p) } static void -ncr53c8xx_ram_writeb(uint32_t addr, uint8_t val, void *p) +ncr53c8xx_ram_writeb(uint32_t addr, uint8_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; dev->ram[addr & 0x0fff] = val; } static void -ncr53c8xx_ram_writew(uint32_t addr, uint16_t val, void *p) +ncr53c8xx_ram_writew(uint32_t addr, uint16_t val, void *priv) { - ncr53c8xx_ram_writeb(addr, val & 0xff, p); - ncr53c8xx_ram_writeb(addr + 1, (val >> 8) & 0xff, p); + ncr53c8xx_ram_writeb(addr, val & 0xff, priv); + ncr53c8xx_ram_writeb(addr + 1, (val >> 8) & 0xff, priv); } static void -ncr53c8xx_ram_writel(uint32_t addr, uint32_t val, void *p) +ncr53c8xx_ram_writel(uint32_t addr, uint32_t val, void *priv) { - ncr53c8xx_ram_writeb(addr, val & 0xff, p); - ncr53c8xx_ram_writeb(addr + 1, (val >> 8) & 0xff, p); - ncr53c8xx_ram_writeb(addr + 2, (val >> 16) & 0xff, p); - ncr53c8xx_ram_writeb(addr + 3, (val >> 24) & 0xff, p); + ncr53c8xx_ram_writeb(addr, val & 0xff, priv); + ncr53c8xx_ram_writeb(addr + 1, (val >> 8) & 0xff, priv); + ncr53c8xx_ram_writeb(addr + 2, (val >> 16) & 0xff, priv); + ncr53c8xx_ram_writeb(addr + 3, (val >> 24) & 0xff, priv); } static uint8_t -ncr53c8xx_ram_readb(uint32_t addr, void *p) +ncr53c8xx_ram_readb(uint32_t addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + const ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; return dev->ram[addr & 0x0fff]; } static uint16_t -ncr53c8xx_ram_readw(uint32_t addr, void *p) +ncr53c8xx_ram_readw(uint32_t addr, void *priv) { uint16_t val; - val = ncr53c8xx_ram_readb(addr, p); - val |= ncr53c8xx_ram_readb(addr + 1, p) << 8; + val = ncr53c8xx_ram_readb(addr, priv); + val |= ncr53c8xx_ram_readb(addr + 1, priv) << 8; return val; } static uint32_t -ncr53c8xx_ram_readl(uint32_t addr, void *p) +ncr53c8xx_ram_readl(uint32_t addr, void *priv) { uint32_t val; - val = ncr53c8xx_ram_readb(addr, p); - val |= ncr53c8xx_ram_readb(addr + 1, p) << 8; - val |= ncr53c8xx_ram_readb(addr + 2, p) << 16; - val |= ncr53c8xx_ram_readb(addr + 3, p) << 24; + val = ncr53c8xx_ram_readb(addr, priv); + val |= ncr53c8xx_ram_readb(addr + 1, priv) << 8; + val |= ncr53c8xx_ram_readb(addr + 2, priv) << 16; + val |= ncr53c8xx_ram_readb(addr + 3, priv) << 24; return val; } @@ -2246,9 +2279,9 @@ uint8_t ncr53c8xx_pci_regs[256]; bar_t ncr53c8xx_pci_bar[4]; static uint8_t -ncr53c8xx_pci_read(int func, int addr, void *p) +ncr53c8xx_pci_read(UNUSED(int func), int addr, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; ncr53c8xx_log("NCR53c8xx: Reading register %02X\n", addr & 0xff); @@ -2341,15 +2374,18 @@ ncr53c8xx_pci_read(int func, int addr, void *p) return 0x11; case 0x3F: return 0x40; + + default: + break; } return 0; } static void -ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) +ncr53c8xx_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - ncr53c8xx_t *dev = (ncr53c8xx_t *) p; + ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint8_t valxor; ncr53c8xx_log("NCR53c8xx: Write value %02X to register %02X\n", val, addr & 0xff); @@ -2479,6 +2515,9 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) ncr53c8xx_pci_regs[addr] = val; dev->irq = val; return; + + default: + break; } } @@ -2518,9 +2557,9 @@ ncr53c8xx_init(const device_t *info) dev->has_bios = 0; if (info->local & 0x8000) - dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); else - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); if (dev->chip == CHIP_875) { dev->chip_rev = 0x04; @@ -2584,6 +2623,8 @@ ncr53c8xx_init(const device_t *info) timer_add(&dev->timer, ncr53c8xx_callback, dev, 0); + scsi_bus_set_speed(dev->bus, 10000000.0); + return dev; } diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f3dc6ebaff..674bbdabfa 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -149,7 +149,7 @@ #define SBAC_STATUS (1 << 24) #define SBAC_PABTEN (1 << 25) -typedef struct { +typedef struct esp_t { mem_mapping_t mmio_mapping; mem_mapping_t ram_mapping; char *nvr_path; @@ -188,15 +188,16 @@ typedef struct { int mca; uint16_t Base; - uint8_t HostID, DmaChannel; + uint8_t HostID; + uint8_t DmaChannel; - struct - { + struct { uint8_t mode; uint8_t status; int pos; } dma_86c01; + uint8_t irq_state; uint8_t pos_regs[8]; } esp_t; @@ -237,20 +238,18 @@ esp_irq(esp_t *dev, int level) { if (dev->mca) { if (level) { - picint(1 << dev->irq); - dev->dma_86c01.status |= 0x01; + picintlevel(1 << dev->irq, &dev->irq_state); esp_log("Raising IRQ...\n"); } else { - picintc(1 << dev->irq); - dev->dma_86c01.status &= ~0x01; + picintclevel(1 << dev->irq, &dev->irq_state); esp_log("Lowering IRQ...\n"); } } else { if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); esp_log("Raising IRQ...\n"); } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); esp_log("Lowering IRQ...\n"); } } @@ -379,9 +378,9 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen) dma_set_drq(dev->DmaChannel, 0); } else { esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE); - dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); - fifo8_push_all(&dev->cmdfifo, buf, dmalen); } + dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); + fifo8_push_all(&dev->cmdfifo, buf, dmalen); } else { dmalen = MIN(fifo8_num_used(&dev->fifo), maxlen); esp_log("ESP Get command, dmalen = %i\n", dmalen); @@ -464,7 +463,7 @@ esp_do_command_phase(esp_t *dev) scsi_device_identify(sd, SCSI_LUN_USE_CDB); - dev->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; + dev->rregs[ESP_RINTR] |= (INTR_BS | INTR_FC); esp_raise_irq(dev); } @@ -517,7 +516,6 @@ esp_dma_enable(esp_t *dev, int level) if (level) { esp_log("ESP DMA Enabled\n"); dev->dma_enabled = 1; - dev->dma_86c01.status |= 0x02; timer_stop(&dev->timer); if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { timer_on_auto(&dev->timer, 40.0); @@ -528,7 +526,6 @@ esp_dma_enable(esp_t *dev, int level) } else { esp_log("ESP DMA Disabled\n"); dev->dma_enabled = 0; - dev->dma_86c01.status &= ~0x02; } } @@ -545,6 +542,8 @@ esp_hard_reset(esp_t *dev) dev->do_cmd = 0; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); + for (uint8_t i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); timer_stop(&dev->timer); } @@ -569,7 +568,6 @@ esp_do_nodma(esp_t *dev, scsi_device_t *sd) esp_do_cmd(dev); } else { dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); - ; esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset); dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; @@ -665,7 +663,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) count = tdbc = esp_get_tc(dev); - if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/ + if (dev->mca) { if (sd->buffer_length < 0) { if (dev->dma_enabled) goto done; @@ -713,7 +711,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) return; } - esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); + esp_log("ESP SCSI dmaleft = %d, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); /* Make sure count is never bigger than buffer_length. */ if (count > dev->xfer_counter) @@ -725,7 +723,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < count) { dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); - esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + esp_log("ESP SCSI DMA read for 53C9x: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); dev->dma_86c01.pos++; } dev->dma_86c01.pos = 0; @@ -739,7 +737,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < count) { int val = dma_channel_read(dev->DmaChannel); - esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); + esp_log("ESP SCSI DMA write for 53C9x: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff; dev->dma_86c01.pos++; } @@ -951,9 +949,9 @@ esp_write_response(esp_t *dev) } static void -esp_callback(void *p) +esp_callback(void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; if (dev->dma_enabled || dev->do_cmd || ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD)) { if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) { @@ -965,7 +963,7 @@ esp_callback(void *p) } } - esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); + esp_log("ESP DMA activated = %d, CMD activated = %d, CMD = %02x\n", dev->dma_enabled, dev->do_cmd, (dev->rregs[ESP_CMD] & CMD_CMD)); } static uint32_t @@ -1028,7 +1026,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) switch (saddr) { case ESP_TCHI: dev->tchi_written = 1; - /* fall through */ + fallthrough; case ESP_TCLO: case ESP_TCMID: esp_log("Transfer count regs %02x = %i\n", saddr, val); @@ -1058,14 +1056,13 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) dev->dma = 1; /* Reload DMA counter. */ esp_set_tc(dev, esp_get_stc(dev)); - if (dev->mca) - esp_dma_enable(dev, 1); } else { dev->dma = 0; esp_log("ESP Command not for DMA\n"); - if (dev->mca) - esp_dma_enable(dev, 0); } + if (dev->mca) + esp_dma_enable(dev, dev->dma); + esp_log("[%04X:%08X]: ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", CS, cpu_state.pc, val & (CMD_CMD | CMD_DMA), dev->dma, dev->dma_enabled); switch (val & CMD_CMD) { case CMD_NOP: @@ -1082,6 +1079,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: + for (uint8_t i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); @@ -1089,7 +1089,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) } break; case CMD_TI: - esp_log("val = %02X\n", val); + esp_log("Transfer Information val = %02X\n", val); break; case CMD_SEL: handle_s_without_atn(dev); @@ -1130,6 +1130,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_log("ESP Disable Selection\n"); esp_raise_irq(dev); break; + + default: + break; } break; case ESP_WBUSID: @@ -1255,6 +1258,9 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) dev->dma_regs[DMA_STAT] &= ~(val & mask); } break; + + default: + break; } } @@ -1357,44 +1363,49 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) } static void -esp_pci_io_writeb(uint16_t addr, uint8_t val, void *p) +esp_pci_io_writeb(uint16_t addr, uint8_t val, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; + esp_io_pci_write(dev, addr, val, 1); } static void -esp_pci_io_writew(uint16_t addr, uint16_t val, void *p) +esp_pci_io_writew(uint16_t addr, uint16_t val, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; + esp_io_pci_write(dev, addr, val, 2); } static void -esp_pci_io_writel(uint16_t addr, uint32_t val, void *p) +esp_pci_io_writel(uint16_t addr, uint32_t val, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; esp_io_pci_write(dev, addr, val, 4); } static uint8_t -esp_pci_io_readb(uint16_t addr, void *p) +esp_pci_io_readb(uint16_t addr, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; + return esp_io_pci_read(dev, addr, 1); } static uint16_t -esp_pci_io_readw(uint16_t addr, void *p) +esp_pci_io_readw(uint16_t addr, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; + return esp_io_pci_read(dev, addr, 2); } static uint32_t -esp_pci_io_readl(uint16_t addr, void *p) +esp_pci_io_readl(uint16_t addr, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; + return esp_io_pci_read(dev, addr, 4); } @@ -1447,11 +1458,11 @@ esp_bios_disable(esp_t *dev) static void dc390_save_eeprom(esp_t *dev) { - FILE *f = nvr_fopen(dev->nvr_path, "wb"); - if (!f) + FILE *fp = nvr_fopen(dev->nvr_path, "wb"); + if (!fp) return; - fwrite(dev->eeprom.data, 1, 128, f); - fclose(f); + fwrite(dev->eeprom.data, 1, 128, fp); + fclose(fp); } static void @@ -1545,6 +1556,9 @@ dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) esp_log("EEPROM Write enable command\n"); eeprom->wp = 0; break; + + default: + break; } } else { esp_log("EEPROM Read, write or erase word\n"); @@ -1580,16 +1594,16 @@ dc390_load_eeprom(esp_t *dev) uint8_t *nvr = (uint8_t *) eeprom->data; int i; uint16_t checksum = 0; - FILE *f; + FILE *fp; eeprom->out = 1; - f = nvr_fopen(dev->nvr_path, "rb"); - if (f) { + fp = nvr_fopen(dev->nvr_path, "rb"); + if (fp) { esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, f) != 128) + if (fread(nvr, 1, 128, fp) != 128) fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(f); + fclose(fp); } else { for (i = 0; i < 16; i++) { nvr[i * 2] = 0x57; @@ -1618,9 +1632,9 @@ uint8_t esp_pci_regs[256]; bar_t esp_pci_bar[2]; static uint8_t -esp_pci_read(int func, int addr, void *p) +esp_pci_read(UNUSED(int func), int addr, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; // esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); @@ -1637,7 +1651,6 @@ esp_pci_read(int func, int addr, void *p) return 2; } } - break; case 0x01: return 0x10; case 0x02: @@ -1691,15 +1704,18 @@ esp_pci_read(int func, int addr, void *p) case 0x40 ... 0x4f: return esp_pci_regs[addr]; + + default: + break; } return 0; } static void -esp_pci_write(int func, int addr, uint8_t val, void *p) +esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - esp_t *dev = (esp_t *) p; + esp_t *dev = (esp_t *) priv; uint8_t valxor; int eesk; int eedi; @@ -1795,11 +1811,14 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) case 0x40 ... 0x4f: esp_pci_regs[addr] = val; return; + + default: + break; } } static void * -dc390_init(const device_t *info) +dc390_init(UNUSED(const device_t *info)) { esp_t *dev; @@ -1816,7 +1835,7 @@ dc390_init(const device_t *info) dev->PCIBase = 0; dev->MMIOBase = 0; - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev, &dev->pci_slot); esp_pci_bar[0].addr_regs[0] = 1; esp_pci_regs[0x04] = 3; @@ -1846,14 +1865,16 @@ dc390_init(const device_t *info) timer_add(&dev->timer, esp_callback, dev, 0); + scsi_bus_set_speed(dev->bus, 10000000.0); + return dev; } static uint16_t -ncr53c90_in(uint16_t port, void *priv) +ncr53c9x_in(uint16_t port, void *priv) { esp_t *dev = (esp_t *) priv; - uint16_t ret = 0; + uint16_t ret = 0xffff; port &= 0x1f; @@ -1866,69 +1887,81 @@ ncr53c90_in(uint16_t port, void *priv) break; case 0x0c: + if (dev->rregs[ESP_RSTAT] & STAT_INT) + dev->dma_86c01.status |= 0x01; + else + dev->dma_86c01.status &= ~0x01; + + if ((dev->dma_86c01.mode & 0x40) || dev->dma_enabled) + dev->dma_86c01.status |= 0x02; + else + dev->dma_86c01.status &= ~0x02; + ret = dev->dma_86c01.status; break; + + default: + break; } } - esp_log("[%04X:%08X]: NCR53c90 DMA read port = %02x, ret = %02x\n", CS, cpu_state.pc, port, ret); + esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x.\n\n", CS, cpu_state.pc, port, ret); return ret; } static uint8_t -ncr53c90_inb(uint16_t port, void *priv) +ncr53c9x_inb(uint16_t port, void *priv) { - return ncr53c90_in(port, priv); + return ncr53c9x_in(port, priv); } static uint16_t -ncr53c90_inw(uint16_t port, void *priv) +ncr53c9x_inw(uint16_t port, void *priv) { - return (ncr53c90_in(port, priv) & 0xff) | (ncr53c90_in(port + 1, priv) << 8); + return (ncr53c9x_in(port, priv) & 0xff) | (ncr53c9x_in(port + 1, priv) << 8); } static void -ncr53c90_out(uint16_t port, uint16_t val, void *priv) +ncr53c9x_out(uint16_t port, uint16_t val, void *priv) { esp_t *dev = (esp_t *) priv; port &= 0x1f; - esp_log("[%04X:%08X]: NCR53c90 DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); + esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); if (port >= 0x10) esp_reg_write(dev, port - 0x10, val); else { - if (port == 0x02) { - dev->dma_86c01.mode = (val & 0x40); - } + if (port == 0x02) + dev->dma_86c01.mode = val; } } static void -ncr53c90_outb(uint16_t port, uint8_t val, void *priv) +ncr53c9x_outb(uint16_t port, uint8_t val, void *priv) { - ncr53c90_out(port, val, priv); + ncr53c9x_out(port, val, priv); } static void -ncr53c90_outw(uint16_t port, uint16_t val, void *priv) +ncr53c9x_outw(uint16_t port, uint16_t val, void *priv) { - ncr53c90_out(port, val & 0xff, priv); - ncr53c90_out(port + 1, val >> 8, priv); + ncr53c9x_out(port, val & 0xff, priv); + ncr53c9x_out(port + 1, val >> 8, priv); } static uint8_t -ncr53c90_mca_read(int port, void *priv) +ncr53c9x_mca_read(int port, void *priv) { - esp_t *dev = (esp_t *) priv; + const esp_t *dev = (esp_t *) priv; return (dev->pos_regs[port & 7]); } static void -ncr53c90_mca_write(int port, uint8_t val, void *priv) +ncr53c9x_mca_write(int port, uint8_t val, void *priv) { esp_t *dev = (esp_t *) priv; static const uint16_t ncrmca_iobase[] = { @@ -1945,8 +1978,8 @@ ncr53c90_mca_write(int port, uint8_t val, void *priv) /* This is always necessary so that the old handler doesn't remain. */ if (dev->Base != 0) { io_removehandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); + ncr53c9x_inb, ncr53c9x_inw, NULL, + ncr53c9x_outb, ncr53c9x_outw, NULL, dev); } /* Get the new assigned I/O base address. */ @@ -1970,28 +2003,28 @@ ncr53c90_mca_write(int port, uint8_t val, void *priv) if (dev->Base != 0) { /* Card enabled; register (new) I/O handler. */ io_sethandler(dev->Base, 0x20, - ncr53c90_inb, ncr53c90_inw, NULL, - ncr53c90_outb, ncr53c90_outw, NULL, dev); + ncr53c9x_inb, ncr53c9x_inw, NULL, + ncr53c9x_outb, ncr53c9x_outw, NULL, dev); esp_hard_reset(dev); } /* Say hello. */ - esp_log("NCR 53c90: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", + esp_log("NCR 53c9x: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", dev->Base, dev->irq, dev->DmaChannel, dev->HostID); } } static uint8_t -ncr53c90_mca_feedb(void *priv) +ncr53c9x_mca_feedb(void *priv) { - esp_t *dev = (esp_t *) priv; + const esp_t *dev = (esp_t *) priv; return (dev->pos_regs[2] & 0x01); } static void * -ncr53c90_mca_init(const device_t *info) +ncr53c9x_mca_init(UNUSED(const device_t *info)) { esp_t *dev; @@ -2005,14 +2038,16 @@ ncr53c90_mca_init(const device_t *info) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4d; /* MCA board ID */ + dev->pos_regs[0] = 0x4f; /* MCA board ID */ dev->pos_regs[1] = 0x7f; - mca_add(ncr53c90_mca_read, ncr53c90_mca_write, ncr53c90_mca_feedb, NULL, dev); + mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); esp_hard_reset(dev); timer_add(&dev->timer, esp_callback, dev, 0); + scsi_bus_set_speed(dev->bus, 5000000.0); + return dev; } @@ -2057,12 +2092,12 @@ const device_t dc390_pci_device = { .config = bios_enable_config }; -const device_t ncr53c90_mca_device = { - .name = "NCR 53c90 MCA", - .internal_name = "ncr53c90", +const device_t ncr53c90a_mca_device = { + .name = "NCR 53c90a MCA", + .internal_name = "ncr53c90a", .flags = DEVICE_MCA, .local = 0, - .init = ncr53c90_mca_init, + .init = ncr53c9x_mca_init, .close = esp_close, .reset = NULL, { .available = NULL }, diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index cddf15740c..ba2817fe3a 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -135,7 +135,7 @@ typedef struct { int cir_status; uint8_t pacing; - + uint8_t irq_state; uint8_t buf[0x600]; struct { @@ -159,6 +159,7 @@ typedef struct { int scb_state; int in_reset; int in_invalid; + int spock_16bit; uint64_t temp_period; double media_period; @@ -286,9 +287,9 @@ spock_add_to_period(spock_t *scsi, int TransferLength) } static void -spock_write(uint16_t port, uint8_t val, void *p) +spock_write(uint16_t port, uint8_t val, void *priv) { - spock_t *scsi = (spock_t *) p; + spock_t *scsi = (spock_t *) priv; spock_log("spock_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); @@ -320,13 +321,16 @@ spock_write(uint16_t port, uint8_t val, void *p) scsi->basic_ctrl = val; spock_rethink_irqs(scsi); break; + + default: + break; } } static void -spock_writew(uint16_t port, uint16_t val, void *p) +spock_writew(uint16_t port, uint16_t val, void *priv) { - spock_t *scsi = (spock_t *) p; + spock_t *scsi = (spock_t *) priv; switch (port & 7) { case 0: /*Command Interface Register*/ @@ -339,15 +343,18 @@ spock_writew(uint16_t port, uint16_t val, void *p) scsi->cir_pending[3] = val >> 8; scsi->cir_status |= 2; break; + + default: + break; } spock_log("spock_writew: port=%04x val=%04x\n", port, val); } static uint8_t -spock_read(uint16_t port, void *p) +spock_read(uint16_t port, void *priv) { - spock_t *scsi = (spock_t *) p; + const spock_t *scsi = (spock_t *) priv; uint8_t temp = 0xff; switch (port & 7) { @@ -378,6 +385,9 @@ spock_read(uint16_t port, void *p) temp |= STATUS_CMD_FULL; } break; + + default: + break; } spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x.\n", port, temp, CS, cs, cpu_state.pc); @@ -385,10 +395,10 @@ spock_read(uint16_t port, void *p) } static uint16_t -spock_readw(uint16_t port, void *p) +spock_readw(uint16_t port, void *priv) { - spock_t *scsi = (spock_t *) p; - uint16_t temp = 0xffff; + const spock_t *scsi = (spock_t *) priv; + uint16_t temp = 0xffff; switch (port & 7) { case 0: /*Command Interface Register*/ @@ -397,6 +407,9 @@ spock_readw(uint16_t port, void *p) case 2: /*Command Interface Register*/ temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); break; + + default: + break; } spock_log("spock_readw: port=%04x val=%04x\n", port, temp); @@ -662,9 +675,9 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) spock_log("Get POS Info\n"); get_pos_info_t *get_pos_info = &scsi->get_pos_info; - get_pos_info->pos = 0x8eff; + get_pos_info->pos = scsi->spock_16bit ? 0x8efe : 0x8eff; get_pos_info->pos1 = scsi->pos_regs[3] | (scsi->pos_regs[2] << 8); - get_pos_info->pos2 = 0x0e | (scsi->pos_regs[4] << 8); + get_pos_info->pos2 = scsi->irq | (scsi->pos_regs[4] << 8); get_pos_info->pos3 = 1 << 12; get_pos_info->pos4 = (7 << 8) | 8; get_pos_info->pos5 = (16 << 8) | scsi->pacing; @@ -704,7 +717,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) case CMD_SEND_OTHER_SCSI: scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2); - spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id); + spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, CDB[0]=%02x, CDB_ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->cdb[0], scsi->cdb_id); scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; scsi->scsi_state = SCSI_STATE_SELECT; @@ -797,6 +810,9 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) scsi->scsi_state = SCSI_STATE_SELECT; scsi->scb_state = 2; return; + + default: + break; } break; @@ -843,6 +859,9 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) spock_log("Complete SCB ID = %d.\n", scsi->attention & 0x0f); } break; + + default: + break; } } while (scsi->scb_state != old_scb_state); } @@ -898,7 +917,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb) scsi_device_command_phase0(sd, scsi->temp_cdb); spock_log("SCSI ID %i: Current CDB[0] = %02x, LUN = %i, data len = %i, max len = %i, phase val = %02x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase); - if (sd->phase != SCSI_PHASE_STATUS && sd->buffer_length > 0) { + if ((sd->phase != SCSI_PHASE_STATUS) && (sd->buffer_length > 0)) { p = scsi_device_get_callback(sd); if (p <= 0.0) spock_add_to_period(scsi, sd->buffer_length); @@ -951,9 +970,9 @@ spock_process_scsi(spock_t *scsi, scb_t *scb) scsi->scsi_state = SCSI_STATE_IDLE; spock_log("State to idle, cmd timer %d\n", scsi->cmd_timer); - if (!scsi->cmd_timer) { + if (!scsi->cmd_timer) scsi->cmd_timer = 1; - } + spock_add_to_period(scsi, 1); break; } @@ -1000,6 +1019,9 @@ spock_callback(void *priv) case CMD_RESET: spock_process_imm_cmd(scsi); break; + + default: + break; } break; @@ -1024,6 +1046,9 @@ spock_callback(void *priv) scsi->irq_status = 0; spock_clear_irq(scsi, scsi->attention & 0x0f); break; + + default: + break; } } } @@ -1031,8 +1056,8 @@ spock_callback(void *priv) spock_process_scsi(scsi, scb); period = 0.2 * ((double) scsi->temp_period); - timer_on(&scsi->callback_timer, (scsi->media_period + period + 10.0), 0); - spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period); + timer_on_auto(&scsi->callback_timer, (scsi->media_period + period + 10.0)); + spock_log("Temporary period: %lf us (%" PRIi64 " periods), media period = %lf\n", scsi->callback_timer.period, scsi->temp_period, scsi->media_period); } static void @@ -1057,20 +1082,23 @@ spock_mca_write(int port, uint8_t val, void *priv) mem_mapping_enable(&scsi->bios_rom.mapping); } } + spock_log("[%04X:%08X]: POS Write Port = %x, val = %02x, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000); } static uint8_t spock_mca_read(int port, void *priv) { - spock_t *scsi = (spock_t *) priv; + const spock_t *scsi = (spock_t *) priv; + spock_log("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, + port & 7, scsi->pos_regs[port & 7]); return scsi->pos_regs[port & 7]; } static uint8_t spock_mca_feedb(void *priv) { - spock_t *scsi = (spock_t *) priv; + const spock_t *scsi = (spock_t *) priv; return (scsi->pos_regs[2] & 0x01); } @@ -1094,6 +1122,10 @@ spock_mca_reset(void *priv) scsi_device_reset(&scsi_devices[scsi->bus][i]); scsi->present[i] = 0; } + + spock_log("Reset.\n"); + mem_mapping_disable(&scsi->bios_rom.mapping); + spock_mca_write(0x102, 0, scsi); } static void * @@ -1107,20 +1139,24 @@ spock_init(const device_t *info) scsi->irq = 14; scsi->bios_ver = device_get_config_int("bios_ver"); + scsi->spock_16bit = info->local & 0xff; switch (scsi->bios_ver) { + case 0: + rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM, + 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + break; case 1: rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM, 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); break; - case 0: - rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM, - 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + + default: break; } mem_mapping_disable(&scsi->bios_rom.mapping); - scsi->pos_regs[0] = 0xff; + scsi->pos_regs[0] = scsi->spock_16bit ? 0xfe : 0xff; scsi->pos_regs[1] = 0x8e; mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi); @@ -1128,23 +1164,26 @@ spock_init(const device_t *info) scsi->cmd_timer = SPOCK_TIME * 50; scsi->status = STATUS_BUSY; - for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++) { + for (uint8_t c = 0; c < (SCSI_ID_MAX - 1); c++) scsi->dev_id[c].phys_id = -1; - } scsi->dev_id[SCSI_ID_MAX - 1].phys_id = scsi->adapter_id; timer_add(&scsi->callback_timer, spock_callback, scsi, 1); scsi->callback_timer.period = 10.0; - timer_set_delay_u64(&scsi->callback_timer, (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC))); + + timer_set_delay_u64(&scsi->callback_timer, + (uint64_t) (scsi->callback_timer.period * ((double) TIMER_USEC))); + + scsi_bus_set_speed(scsi->bus, 5000000.0); return scsi; } static void -spock_close(void *p) +spock_close(void *priv) { - spock_t *scsi = (spock_t *) p; + spock_t *scsi = (spock_t *) priv; if (scsi) { free(scsi); @@ -1191,3 +1230,17 @@ const device_t spock_device = { .force_redraw = NULL, .config = spock_rom_config }; + +const device_t tribble_device = { + .name = "IBM PS/2 SCSI Adapter (Tribble)", + .internal_name = "tribble", + .flags = DEVICE_MCA, + .local = 1, + .init = spock_init, + .close = spock_close, + .reset = NULL, + { .available = spock_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = spock_rom_config +}; diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index dd71b1a05b..6876e43857 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -83,22 +83,26 @@ x54x_irq(x54x_t *dev, int set) if (dev->card_bus & DEVICE_PCI) { x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); if (set) - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } else { x54x_log("%sing IRQ %i\n", set ? "Rais" : "Lower", irq); - if (set) { - if (dev->interrupt_type) - int_type = dev->interrupt_type(dev); + if (dev->interrupt_type) + int_type = dev->interrupt_type(dev); + if (set) { if (int_type) - picintlevel(1 << irq); + picintlevel(1 << irq, &dev->irq_state); else picint(1 << irq); - } else - picintc(1 << irq); + } else { + if (int_type) + picintclevel(1 << irq, &dev->irq_state); + else + picintc(1 << irq); + } } } @@ -238,6 +242,9 @@ completion_code(uint8_t *sense) case ASC_MEDIUM_NOT_PRESENT: ret = 0xaa; break; + + default: + break; } return ret; @@ -483,6 +490,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) default: x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command); + fallthrough; case 0x05: /* Format Track, invalid since SCSI has no tracks */ case 0x0a: /* ???? */ case 0x0b: /* ???? */ @@ -583,8 +591,8 @@ x54x_mbi_setup(x54x_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, static void x54x_ccb(x54x_t *dev) { - Req_t *req = &dev->Req; - uint8_t bytes[4] = { 0, 0, 0, 0 }; + const Req_t *req = &dev->Req; + uint8_t bytes[4] = { 0, 0, 0, 0 }; /* Rewrite the CCB up to the CDB. */ x54x_log("CCB completion code and statuses rewritten (pointer %08X)\n", req->CCBPointer); @@ -605,14 +613,16 @@ static void x54x_mbi(x54x_t *dev) { Req_t *req = &dev->Req; - // uint32_t CCBPointer = req->CCBPointer; - addr24 CCBPointer; - CCBU *CmdBlock = &(req->CmdBlock); - uint8_t HostStatus = req->HostStatus; - uint8_t TargetStatus = req->TargetStatus; - uint32_t MailboxCompletionCode = req->MailboxCompletionCode; - uint32_t Incoming; - uint8_t bytes[4] = { 0, 0, 0, 0 }; +#if 0 + uint32_t CCBPointer = req->CCBPointer; +#endif + addr24_t CCBPointer; + CCBU *CmdBlock = &(req->CmdBlock); + uint8_t HostStatus = req->HostStatus; + uint8_t TargetStatus = req->TargetStatus; + uint32_t MailboxCompletionCode = req->MailboxCompletionCode; + uint32_t Incoming; + uint8_t bytes[4] = { 0, 0, 0, 0 }; Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * ((dev->flags & X54X_MBX_24BIT) ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); @@ -734,7 +744,7 @@ static void x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength) { uint32_t Residue = 0; - addr24 Residue24; + addr24_t Residue24; int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length; uint8_t bytes[4] = { 0, 0, 0, 0 }; @@ -1017,7 +1027,7 @@ x54x_mbo_free(x54x_t *dev) static void x54x_notify(x54x_t *dev) { - Req_t *req = &dev->Req; + const Req_t *req = &dev->Req; scsi_device_t *sd; sd = &scsi_devices[dev->bus][req->TargetID]; @@ -1035,7 +1045,7 @@ x54x_notify(x54x_t *dev) } static void -x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, UNUSED(Mailbox32_t *Mailbox32)) { Req_t *req = &dev->Req; uint8_t id; @@ -1161,9 +1171,11 @@ x54x_mbo_process(x54x_t *dev) } else if (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT)) { x54x_log("Abort Mailbox Command\n"); x54x_req_abort(dev, mb32.CCBPointer); - } /* else { +#if 0 + } else { x54x_log("Invalid action code: %02X\n", mb32.u.out.ActionCode); - } */ +#endif + } if ((mb32.u.out.ActionCode == MBO_START) || (!dev->MailboxIsBIOS && (mb32.u.out.ActionCode == MBO_ABORT))) { /* We got the mailbox, decrease the number of pending requests. */ @@ -1281,8 +1293,10 @@ x54x_cmd_callback(void *priv) } period = (1000000.0 / dev->ha_bps) * ((double) dev->temp_period); - timer_on(&dev->timer, dev->media_period + period + 10.0, 0); - // x54x_log("Temporary period: %lf us (%" PRIi64 " periods)\n", dev->timer.period, dev->temp_period); + timer_on_auto(&dev->timer, dev->media_period + period + 10.0); +#if 0 + x54x_log("Temporary period: %lf us (%" PRIi64 " periods)\n", dev->timer.period, dev->temp_period); +#endif } static uint8_t @@ -1292,8 +1306,8 @@ x54x_in(uint16_t port, void *priv) uint8_t ret; switch (port & 3) { - case 0: default: + case 0: ret = dev->Status; break; @@ -1328,24 +1342,27 @@ x54x_in(uint16_t port, void *priv) if (dev->flags & X54X_INT_GEOM_WRITABLE) ret = dev->Geometry; else { - switch (dev->Geometry) { - case 0: - default: - ret = 'A'; - break; - case 1: - ret = 'D'; - break; - case 2: - ret = 'A'; - break; - case 3: - ret = 'P'; - break; - } - ret ^= 1; - dev->Geometry++; - dev->Geometry &= 0x03; + if (dev->flags & X54X_HAS_SIGNATURE) { + switch (dev->Geometry) { + default: + case 0: + ret = 'A'; + break; + case 1: + ret = 'D'; + break; + case 2: + ret = 'A'; + break; + case 3: + ret = 'P'; + break; + } + ret ^= 1; + dev->Geometry++; + dev->Geometry &= 0x03; + } else + ret = 0xff; break; } break; @@ -1403,6 +1420,7 @@ static void x54x_reset(x54x_t *dev) { clear_irq(dev); + dev->irq_state = 0; if (dev->flags & X54X_INT_GEOM_WRITABLE) dev->Geometry = 0x90; else @@ -1452,14 +1470,14 @@ x54x_out(uint16_t port, uint8_t val, void *priv) { ReplyInquireSetupInformation *ReplyISI; x54x_t *dev = (x54x_t *) priv; - MailboxInit_t *mbi; + const MailboxInit_t *mbi; int i = 0; BIOSCMD *cmd; uint16_t cyl = 0; int suppress = 0; uint32_t FIFOBuf; uint8_t reset; - addr24 Address; + addr24_t Address; uint8_t host_id = dev->HostID; uint8_t irq = 0; @@ -1759,6 +1777,9 @@ x54x_out(uint16_t port, uint8_t val, void *priv) if (dev->flags & X54X_INT_GEOM_WRITABLE) dev->Geometry = val; break; + + default: + break; } } diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 15411d3e61..dff0fcd0f7 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -15,10 +15,11 @@ add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c sio_fdc37c6xx.c sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c - sio_it8661f.c + sio_it86x1f.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c - sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c + sio_w83787f.c sio_w83877f.c sio_w83977f.c + sio_um8663f.c sio_um8669f.c sio_vt82c686.c) if(SIO_DETECT) diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index 4011f7ecff..cbe89c6823 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -35,9 +35,10 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t cur_reg, has_ide, - regs[81]; +typedef struct i82091aa_t { + uint8_t cur_reg; + uint8_t has_ide; + uint8_t regs[81]; uint16_t base_address; fdc_t *fdc; serial_t *uart[2]; @@ -71,6 +72,9 @@ lpt1_handler(i82091aa_t *dev) case 3: lpt_port = 0x000; break; + + default: + break; } if ((dev->regs[0x20] & 0x01) && lpt_port) @@ -112,6 +116,9 @@ serial_handler(i82091aa_t *dev, int uart) case 0x07: uart_port = COM3_ADDR; break; + + default: + break; } if (dev->regs[reg] & 0x01) @@ -135,7 +142,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) { i82091aa_t *dev = (i82091aa_t *) priv; uint8_t index; - uint8_t valxor; + uint8_t valxor = 0; uint8_t uart = (dev->cur_reg >> 4) - 0x03; uint8_t *reg = &(dev->regs[dev->cur_reg]); @@ -193,15 +200,18 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) if (dev->has_ide && (valxor & 0x03)) ide_handler(dev); break; + + default: + break; } } uint8_t i82091aa_read(uint16_t port, void *priv) { - i82091aa_t *dev = (i82091aa_t *) priv; - uint8_t ret = 0xff; - uint8_t index; + const i82091aa_t *dev = (i82091aa_t *) priv; + uint8_t ret = 0xff; + uint8_t index; index = (port & 1) ? 0 : 1; diff --git a/src/sio/sio_acc3221.c b/src/sio/sio_acc3221.c index f5c671c3a2..275d9ae2e0 100644 --- a/src/sio/sio_acc3221.c +++ b/src/sio/sio_acc3221.c @@ -31,6 +31,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> typedef struct acc3221_t { int reg_idx; @@ -344,9 +345,9 @@ acc3221_serial2_handler(acc3221_t *dev) } static void -acc3221_write(uint16_t addr, uint8_t val, void *p) +acc3221_write(uint16_t addr, uint8_t val, void *priv) { - acc3221_t *dev = (acc3221_t *) p; + acc3221_t *dev = (acc3221_t *) priv; uint8_t old; if (!(addr & 1)) @@ -405,14 +406,17 @@ acc3221_write(uint16_t addr, uint8_t val, void *p) ide_pri_enable(); } break; + + default: + break; } } } static uint8_t -acc3221_read(uint16_t addr, void *p) +acc3221_read(uint16_t addr, void *priv) { - acc3221_t *dev = (acc3221_t *) p; + const acc3221_t *dev = (acc3221_t *) priv; if (!(addr & 1)) return dev->reg_idx; @@ -448,7 +452,7 @@ acc3221_close(void *priv) } static void * -acc3221_init(const device_t *info) +acc3221_init(UNUSED(const device_t *info)) { acc3221_t *dev = (acc3221_t *) malloc(sizeof(acc3221_t)); memset(dev, 0, sizeof(acc3221_t)); diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 68d674b110..78c585c113 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -37,13 +37,14 @@ #define AB_RST 0x80 -typedef struct { - uint8_t chip_id, is_apm, - tries, - regs[48], - ld_regs[13][256]; - int locked, - cur_reg; +typedef struct ali5123_t { + uint8_t chip_id; + uint8_t is_apm; + uint8_t tries; + uint8_t regs[48]; + uint8_t ld_regs[13][256]; + int locked; + int cur_reg; fdc_t *fdc; serial_t *uart[3]; } ali5123_t; @@ -125,6 +126,9 @@ ali5123_serial_handler(ali5123_t *dev, int uart) case 0x05: serial_set_clock_src(dev->uart[uart], 2000000.0); break; + + default: + break; } } @@ -256,6 +260,10 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) case 0x07: if (dev->cur_reg == 0xf0) val &= 0xbf; + break; + + default: + break; } dev->ld_regs[cur_ld][dev->cur_reg] = val; } @@ -288,6 +296,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) ali5123_serial_handler(dev, 2); } break; + + default: + break; } return; @@ -332,6 +343,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x08) fdc_update_drvrate(dev->fdc, 3, (val & 0x08) >> 3); break; + + default: + break; } break; case 3: @@ -346,6 +360,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) if (valxor) ali5123_lpt_handler(dev); break; + + default: + break; } break; case 4: @@ -361,6 +378,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) if (valxor) ali5123_serial_handler(dev, 0); break; + + default: + break; } break; case 5: @@ -376,6 +396,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) if (valxor) ali5123_serial_handler(dev, (dev->regs[0x2d] & 0x20) ? 2 : 1); break; + + default: + break; } break; case 0x0b: @@ -391,18 +414,24 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) if (valxor) ali5123_serial_handler(dev, (dev->regs[0x2d] & 0x20) ? 1 : 2); break; + + default: + break; } break; + + default: + break; } } static uint8_t ali5123_read(uint16_t port, void *priv) { - ali5123_t *dev = (ali5123_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t ret = 0xff; - uint8_t cur_ld; + const ali5123_t *dev = (ali5123_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + uint8_t cur_ld; if (dev->locked) { if (index) diff --git a/src/sio/sio_detect.c b/src/sio/sio_detect.c index 36c12cd544..38faf3c2cb 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -26,8 +26,9 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct sio_detect_t { uint8_t regs[2]; } sio_detect_t; @@ -46,7 +47,7 @@ sio_detect_write(uint16_t port, uint8_t val, void *priv) static uint8_t sio_detect_read(uint16_t port, void *priv) { - sio_detect_t *dev = (sio_detect_t *) priv; + const sio_detect_t *dev = (sio_detect_t *) priv; pclog("sio_detect_read : port=%04x = %02X\n", port, dev->regs[port & 1]); @@ -62,7 +63,7 @@ sio_detect_close(void *priv) } static void * -sio_detect_init(const device_t *info) +sio_detect_init(UNUSED(const device_t *info)) { sio_detect_t *dev = (sio_detect_t *) malloc(sizeof(sio_detect_t)); memset(dev, 0, sizeof(sio_detect_t)); diff --git a/src/sio/sio_f82c710.c b/src/sio/sio_f82c710.c index ad347fb030..d4afb11da0 100644 --- a/src/sio/sio_f82c710.c +++ b/src/sio/sio_f82c710.c @@ -18,11 +18,9 @@ * * * - * Authors: Sarah Walker, - * Eluan Costa Miranda + * Authors: Eluan Costa Miranda * Lubomir Rintel * - * Copyright 2020 Sarah Walker. * Copyright 2020 Eluan Costa Miranda. * Copyright 2021 Lubomir Rintel. */ @@ -151,6 +149,9 @@ f82c606_update_ports(upc_t *dev, int set) case 0xc0: uart2_int = COM2_IRQ; break; + + default: + break; } switch (dev->regs[8] & 0x30) { @@ -163,6 +164,9 @@ f82c606_update_ports(upc_t *dev, int set) case 0x30: uart2_int = COM1_IRQ; break; + + default: + break; } switch (dev->regs[8] & 0x0c) { @@ -175,6 +179,9 @@ f82c606_update_ports(upc_t *dev, int set) case 0x0c: lpt1_int = LPT2_IRQ; break; + + default: + break; } switch (dev->regs[8] & 0x03) { @@ -187,6 +194,9 @@ f82c606_update_ports(upc_t *dev, int set) case 0x03: lpt1_int = LPT1_IRQ; break; + + default: + break; } if (dev->regs[0] & 1) { @@ -218,8 +228,8 @@ f82c606_update_ports(upc_t *dev, int set) static uint8_t f82c710_config_read(uint16_t port, void *priv) { - upc_t *dev = (upc_t *) priv; - uint8_t temp = 0xff; + const upc_t *dev = (upc_t *) priv; + uint8_t temp = 0xff; if (dev->configuration_mode) { if (port == dev->cri_addr) { diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index 219213d69d..0cd686991a 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -12,13 +12,15 @@ * * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2024 Miran Grca. */ +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> @@ -32,43 +34,80 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t id, tries, - regs[42]; - int locked, rw_locked, - cur_reg; +typedef struct fdc37c669_t { + uint8_t id; + uint8_t tries; + uint8_t regs[42]; + int locked; + int rw_locked; + int cur_reg; fdc_t *fdc; serial_t *uart[2]; } fdc37c669_t; static int next_id = 0; -static uint16_t -make_port(fdc37c669_t *dev, uint8_t reg) +#ifdef ENABLE_FDC37C669_LOG +int fdc37c669_do_log = ENABLE_FDC37C669_LOG; + +static void +fdc37c669_log(const char *fmt, ...) { - uint16_t p = 0; - uint16_t mask = 0; + va_list ap; - switch (reg) { - case 0x20: - case 0x21: - case 0x22: - mask = 0xfc; - break; - case 0x23: - mask = 0xff; - break; - case 0x24: - case 0x25: - mask = 0xfe; - break; + if (fdc37c669_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } +} +#else +# define fdc37c669_log(fmt, ...) +#endif - p = ((uint16_t) (dev->regs[reg] & mask)) << 2; - if (reg == 0x22) - p |= 6; +static void +fdc37c669_fdc_handler(fdc37c669_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, ((uint16_t) dev->regs[0x20]) << 2); +} - return p; +static void +fdc37c669_uart_handler(fdc37c669_t *dev, uint8_t uart) +{ + uint8_t uart_reg = 0x24 + uart; + uint8_t pwrdn_mask = 0x08 << (uart << 2); + uint8_t uart_shift = ((uart ^ 1) << 2); + + serial_remove(dev->uart[uart]); + if ((dev->regs[0x02] & pwrdn_mask) && (dev->regs[uart_reg] & 0xc0)) + serial_setup(dev->uart[0], ((uint16_t) dev->regs[0x24]) << 2, + (dev->regs[0x28] >> uart_shift) & 0x0f); +} + +static double +fdc37c669_uart_get_clock_src(fdc37c669_t *dev, uint8_t uart) +{ + double clock_srcs[4] = { 24000000.0 / 13.0, 24000000.0 / 12.0, 24000000.0 / 3.0, 24000000.0 / 3.0 }; + double ret; + uint8_t clock_src_0 = !!(dev->regs[0x04] & (0x10 << uart)); + uint8_t clock_src_1 = !!(dev->regs[0x0c] & (0x40 << uart)); + uint8_t clock_src = clock_src_0 | (clock_src_1 << 1); + + ret = clock_srcs[clock_src]; + + return ret; +} + +static void +fdc37c669_lpt_handler(fdc37c669_t *dev) +{ + uint8_t mask = ~(dev->regs[0x04] & 0x01); + + lpt_port_remove(dev->id); + if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40)) + lpt_port_init(dev->id, ((uint16_t) (dev->regs[0x23] & mask)) << 2); } static void @@ -76,146 +115,153 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) { fdc37c669_t *dev = (fdc37c669_t *) priv; uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - uint8_t max = 42; + uint8_t valxor = val ^ dev->regs[dev->cur_reg]; + + fdc37c669_log("[%04X:%08X] [W] %04X = %02X (%i, %i)\n", CS, cpu_state.pc, port, val, + dev->tries, dev->locked); if (index) { if ((val == 0x55) && !dev->locked) { - if (dev->tries) { + dev->tries = (dev->tries + 1) & 1; + + if (!dev->tries) dev->locked = 1; - dev->tries = 0; - } else - dev->tries++; } else { if (dev->locked) { - if (val < max) - dev->cur_reg = val; if (val == 0xaa) dev->locked = 0; - } else { - if (dev->tries) - dev->tries = 0; - } + else + dev->cur_reg = val; + } else + dev->tries = 0; } - return; - } else { - if (dev->locked) { - if ((dev->cur_reg < 0x18) && (dev->rw_locked)) - return; - if ((dev->cur_reg >= 0x26) && (dev->cur_reg <= 0x27)) - return; - if (dev->cur_reg == 0x29) - return; - valxor = val ^ dev->regs[dev->cur_reg]; - dev->regs[dev->cur_reg] = val; - } else - return; - } - - switch (dev->cur_reg) { - case 0: - if (!dev->id && (valxor & 8)) { - fdc_remove(dev->fdc); - if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + } else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) switch (dev->cur_reg) { + case 0x00: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x74) | (val & 0x8b); + if (!dev->id && (valxor & 8)) + fdc_set_power_down(dev->fdc, !(val & 0x08)); break; - case 1: - if (valxor & 4) { - if (dev->id) { - lpt2_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt2_init(make_port(dev, 0x23)); - } else { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); - } - } - if (valxor & 7) - dev->rw_locked = (val & 8) ? 0 : 1; + case 0x01: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x73) | (val & 0x8c); + if (valxor & 0x04) + fdc37c669_lpt_handler(dev); + if (valxor & 0x80) + dev->rw_locked = !(val & 0x80); break; - case 2: - if (valxor & 8) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } - if (valxor & 0x80) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } + case 0x02: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x77) | (val & 0x88); + if (valxor & 0x08) + fdc37c669_uart_handler(dev, 0); + if (valxor & 0x80) + fdc37c669_uart_handler(dev, 1); break; - case 3: - if (!dev->id && (valxor & 2)) - fdc_update_enh_mode(dev->fdc, (val & 2) ? 1 : 0); + case 0x03: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x08) | (val & 0xf7); + if (!dev->id && (valxor & 0x02)) + fdc_update_enh_mode(dev->fdc, !!(val & 0x02)); + break; + case 0x04: + dev->regs[dev->cur_reg] = val; + if (valxor & 0x03) + fdc37c669_lpt_handler(dev); + if (valxor & 0x10) + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + if (valxor & 0x20) + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); break; - case 5: + case 0x05: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x83) | (val & 0x7c); if (!dev->id && (valxor & 0x18)) fdc_update_densel_force(dev->fdc, (val & 0x18) >> 3); if (!dev->id && (valxor & 0x20)) fdc_set_swap(dev->fdc, (val & 0x20) >> 5); break; - case 0xB: - if (!dev->id && (valxor & 3)) - fdc_update_rwc(dev->fdc, 0, val & 3); - if (!dev->id && (valxor & 0xC)) - fdc_update_rwc(dev->fdc, 1, (val & 0xC) >> 2); + case 0x06: + dev->regs[dev->cur_reg] = val; + break; + case 0x07: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x06) | (val & 0xf9); + break; + case 0x08: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x0f) | (val & 0xf0); + break; + case 0x09: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x38) | (val & 0xc7); + break; + case 0x0a: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xf0) | (val & 0x0f); + break; + case 0x0b: + dev->regs[dev->cur_reg] = val; + if (!dev->id && (valxor & 0x03)) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + if (!dev->id && (valxor & 0x0c)) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + break; + case 0x0c: + dev->regs[dev->cur_reg] = val; + if (valxor & 0x40) + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + if (valxor & 0x80) + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); + break; + case 0x0f: + case 0x12 ... 0x1f: + dev->regs[dev->cur_reg] = val; + break; + case 0x10: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x07) | (val & 0xf8); + break; + case 0x11: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xfc) | (val & 0x03); break; case 0x20: - if (!dev->id && (valxor & 0xfc)) { - fdc_remove(dev->fdc); - if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + dev->regs[dev->cur_reg] = val & 0xfc; + if (!dev->id && (valxor & 0xfc)) + fdc37c669_fdc_handler(dev); + break; + case 0x21: + dev->regs[dev->cur_reg] = val & 0xfc; + break; + case 0x22: + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x03) | (val & 0xfc); break; case 0x23: - if (valxor) { - if (dev->id) { - lpt2_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt2_init(make_port(dev, 0x23)); - } else { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); - } - } + dev->regs[dev->cur_reg] = val; + if (valxor) + fdc37c669_lpt_handler(dev); break; case 0x24: - if (valxor & 0xfe) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } + dev->regs[dev->cur_reg] = val & 0xfe; + if (valxor & 0xfe) + fdc37c669_uart_handler(dev, 0); break; case 0x25: - if (valxor & 0xfe) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } + dev->regs[dev->cur_reg] = val & 0xfe; + if (valxor & 0xfe) + fdc37c669_uart_handler(dev, 1); + break; + case 0x26: + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc_set_dma_ch(dev->fdc, val >> 4); break; case 0x27: - if (valxor & 0xf) { - if (dev->id) - lpt2_irq(val & 0xf); - else - lpt1_irq(val & 0xf); - } + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc_set_irq(dev->fdc, val >> 4); + if (valxor & 0x0f) + lpt_port_irq(dev->id, val & 0x0f); break; case 0x28: - if (valxor & 0xf) { - serial_remove(dev->uart[1]); - if ((dev->regs[2] & 0x80) && (dev->regs[0x25] >= 0x40)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); - } - if (valxor & 0xf0) { - serial_remove(dev->uart[0]); - if ((dev->regs[2] & 8) && (dev->regs[0x24] >= 0x40)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); - } + dev->regs[dev->cur_reg] = val; + if (valxor & 0xf0) + fdc37c669_uart_handler(dev, 0); + if (valxor & 0x0f) + fdc37c669_uart_handler(dev, 1); + break; + case 0x29: + dev->regs[dev->cur_reg] = val & 0x0f; break; } } @@ -223,30 +269,30 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) static uint8_t fdc37c669_read(uint16_t port, void *priv) { - fdc37c669_t *dev = (fdc37c669_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t ret = 0xff; + const fdc37c669_t *dev = (fdc37c669_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; if (dev->locked) { if (index) ret = dev->cur_reg; - else if ((dev->cur_reg >= 0x18) || !dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) ret = dev->regs[dev->cur_reg]; } + fdc37c669_log("[%04X:%08X] [R] %04X = %02X (%i, %i)\n", CS, cpu_state.pc, port, ret, + dev->tries, dev->locked); + return ret; } static void -fdc37c669_reset(fdc37c669_t *dev) +fdc37c669_reset(void *priv) { - serial_remove(dev->uart[0]); - serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + fdc37c669_t *dev = (fdc37c669_t *) priv; - serial_remove(dev->uart[1]); - serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + memset(dev->regs, 0x00, 42); - memset(dev->regs, 0, 42); dev->regs[0x00] = 0x28; dev->regs[0x01] = 0x9c; dev->regs[0x02] = 0x88; @@ -254,32 +300,23 @@ fdc37c669_reset(fdc37c669_t *dev) dev->regs[0x06] = 0xff; dev->regs[0x0d] = 0x03; dev->regs[0x0e] = 0x02; - dev->regs[0x1e] = 0x80; /* Gameport controller. */ - dev->regs[0x20] = (FDC_PRIMARY_ADDR >> 2) & 0xfc; - dev->regs[0x21] = (0x1f0 >> 2) & 0xfc; - dev->regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; - if (dev->id == 1) { - dev->regs[0x23] = (LPT2_ADDR >> 2); - - lpt2_remove(); - lpt2_init(LPT2_ADDR); - - dev->regs[0x24] = (COM3_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM4_ADDR >> 2) & 0xfe; - } else { + dev->regs[0x1e] = 0x3c; /* Gameport controller. */ + dev->regs[0x20] = 0x3c; + dev->regs[0x21] = 0x3c; + dev->regs[0x22] = 0x3d; + + if (dev->id != 1) { fdc_reset(dev->fdc); + fdc37c669_fdc_handler(dev); + } - lpt1_remove(); - lpt1_init(LPT1_ADDR); + fdc37c669_uart_handler(dev, 0); + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); - dev->regs[0x23] = (LPT1_ADDR >> 2); + fdc37c669_uart_handler(dev, 1); + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); - dev->regs[0x24] = (COM1_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM2_ADDR >> 2) & 0xfe; - } - dev->regs[0x26] = (2 << 4) | 3; - dev->regs[0x27] = (6 << 4) | (dev->id ? 5 : 7); - dev->regs[0x28] = (4 << 4) | 3; + fdc37c669_lpt_handler(dev); dev->locked = 0; dev->rw_locked = 0; @@ -309,8 +346,8 @@ fdc37c669_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); - io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), 0x0002, - fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); + io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), + 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); fdc37c669_reset(dev); @@ -326,7 +363,7 @@ const device_t fdc37c669_device = { .local = 0, .init = fdc37c669_init, .close = fdc37c669_close, - .reset = NULL, + .reset = fdc37c669_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, @@ -340,7 +377,7 @@ const device_t fdc37c669_370_device = { .local = 1, .init = fdc37c669_init, .close = fdc37c669_close, - .reset = NULL, + .reset = fdc37c669_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_fdc37c67x.c b/src/sio/sio_fdc37c67x.c index 35c7ccc5b5..871f3b1c8a 100644 --- a/src/sio/sio_fdc37c67x.c +++ b/src/sio/sio_fdc37c67x.c @@ -33,19 +33,23 @@ #include <86box/fdc.h> #include "cpu.h" #include <86box/sio.h> +#include <86box/plat_unused.h> #define AB_RST 0x80 -typedef struct { - uint8_t chip_id, is_apm, - tries, - gpio_regs[2], auxio_reg, - regs[48], - ld_regs[11][256]; - uint16_t gpio_base, /* Set to EA */ - auxio_base, sio_base; - int locked, - cur_reg; +typedef struct fdc37c67x_t { + uint8_t chip_id; + uint8_t is_apm; + uint8_t tries; + uint8_t gpio_regs[2]; + uint8_t auxio_reg; + uint8_t regs[48]; + uint8_t ld_regs[11][256]; + uint16_t gpio_base; /* Set to EA */ + uint16_t auxio_base; + uint16_t sio_base; + int locked; + int cur_reg; fdc_t *fdc; serial_t *uart[2]; } fdc37c67x_t; @@ -65,15 +69,15 @@ make_port(fdc37c67x_t *dev, uint8_t ld) } static uint8_t -fdc37c67x_auxio_read(uint16_t port, void *priv) +fdc37c67x_auxio_read(UNUSED(uint16_t port), void *priv) { - fdc37c67x_t *dev = (fdc37c67x_t *) priv; + const fdc37c67x_t *dev = (fdc37c67x_t *) priv; return dev->auxio_reg; } static void -fdc37c67x_auxio_write(uint16_t port, uint8_t val, void *priv) +fdc37c67x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv) { fdc37c67x_t *dev = (fdc37c67x_t *) priv; @@ -83,8 +87,8 @@ fdc37c67x_auxio_write(uint16_t port, uint8_t val, void *priv) static uint8_t fdc37c67x_gpio_read(uint16_t port, void *priv) { - fdc37c67x_t *dev = (fdc37c67x_t *) priv; - uint8_t ret = 0xff; + const fdc37c67x_t *dev = (fdc37c67x_t *) priv; + uint8_t ret = 0xff; ret = dev->gpio_regs[port & 1]; @@ -168,7 +172,7 @@ fdc37c67x_auxio_handler(fdc37c67x_t *dev) } static void -fdc37c67x_sio_handler(fdc37c67x_t *dev) +fdc37c67x_sio_handler(UNUSED(fdc37c67x_t *dev)) { #if 0 if (dev->sio_base) { @@ -207,6 +211,9 @@ fdc37c67x_gpio_handler(fdc37c67x_t *dev) case 3: ld_port = 0xea; /* Default */ break; + + default: + break; } dev->gpio_base = ld_port; if (ld_port > 0x0000) @@ -279,6 +286,9 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) case 0x02: case 0x07: return; + + default: + break; } dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; } @@ -306,6 +316,10 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) case 0x26: case 0x27: fdc37c67x_sio_handler(dev); + break; + + default: + break; } return; @@ -359,6 +373,9 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x18) fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); break; + + default: + break; } break; case 3: @@ -375,6 +392,9 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x70) fdc37c67x_smi_handler(dev); break; + + default: + break; } break; case 4: @@ -391,6 +411,9 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x70) fdc37c67x_smi_handler(dev); break; + + default: + break; } break; case 5: @@ -407,6 +430,9 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x70) fdc37c67x_smi_handler(dev); break; + + default: + break; } break; case 8: @@ -423,8 +449,14 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) case 0xb5: fdc37c67x_smi_handler(dev); break; + + default: + break; } break; + + default: + break; } } @@ -570,7 +602,9 @@ fdc37c67x_init(const device_t *info) dev->chip_id = info->local & 0xff; dev->gpio_regs[0] = 0xff; - // dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; +#if 0 + dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; +#endif dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; fdc37c67x_reset(dev); diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 8400ca1e08..c1fb2c1a5b 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -11,10 +11,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ #include @@ -35,12 +33,15 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t max_reg, chip_id, - tries, has_ide, - regs[16]; - int cur_reg, - com3_addr, com4_addr; +typedef struct fdc37c6xx_t { + uint8_t max_reg; + uint8_t chip_id; + uint8_t tries; + uint8_t has_ide; + uint8_t regs[16]; + int cur_reg; + int com3_addr; + int com4_addr; fdc_t *fdc; serial_t *uart[2]; } fdc37c6xx_t; @@ -65,6 +66,9 @@ set_com34_addr(fdc37c6xx_t *dev) dev->com3_addr = 0x220; dev->com4_addr = 0x228; break; + + default: + break; } } @@ -92,6 +96,9 @@ set_serial_addr(fdc37c6xx_t *dev, int port) case 3: serial_setup(dev->uart[port], dev->com4_addr, COM4_IRQ); break; + + default: + break; } } @@ -115,6 +122,9 @@ lpt1_handler(fdc37c6xx_t *dev) lpt1_init(LPT2_ADDR); lpt1_irq(7 /*5*/); break; + + default: + break; } } @@ -206,6 +216,9 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x20) fdc_set_swap(dev->fdc, (dev->regs[5] & 0x20) >> 5); break; + + default: + break; } } } else if ((port == FDC_PRIMARY_ADDR) && (val == 0x55)) @@ -215,8 +228,8 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) static uint8_t fdc37c6xx_read(uint16_t port, void *priv) { - fdc37c6xx_t *dev = (fdc37c6xx_t *) priv; - uint8_t ret = 0xff; + const fdc37c6xx_t *dev = (fdc37c6xx_t *) priv; + uint8_t ret = 0xff; if (dev->tries == 2) { if (port == 0x3f1) @@ -381,6 +394,20 @@ const device_t fdc37c661_ide_device = { .config = NULL }; +const device_t fdc37c661_ide_sec_device = { + .name = "SMC FDC37C661 Super I/O (With Secondary IDE)", + .internal_name = "fdc37c661_ide_sec", + .flags = 0, + .local = 0x261, + .init = fdc37c6xx_init, + .close = fdc37c6xx_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c663_device = { .name = "SMC FDC37C663 Super I/O", .internal_name = "fdc37c663", @@ -451,6 +478,20 @@ const device_t fdc37c665_ide_pri_device = { .config = NULL }; +const device_t fdc37c665_ide_sec_device = { + .name = "SMC FDC37C665 Super I/O (With Secondary IDE)", + .internal_name = "fdc37c665_ide_sec", + .flags = 0, + .local = 0x265, + .init = fdc37c6xx_init, + .close = fdc37c6xx_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c666_device = { .name = "SMC FDC37C666 Super I/O", .internal_name = "fdc37c666", diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 80f451e060..4acbfeff52 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -35,10 +35,11 @@ #include <86box/apm.h> #include <86box/acpi.h> #include <86box/sio.h> +#include <86box/plat_unused.h> #define AB_RST 0x80 -typedef struct { +typedef struct access_bus_t { uint8_t control; uint8_t status; uint8_t own_addr; @@ -47,16 +48,19 @@ typedef struct { uint16_t base; } access_bus_t; -typedef struct { - uint8_t chip_id, is_apm, - tries, - gpio_regs[2], auxio_reg, - regs[48], - ld_regs[11][256]; - uint16_t gpio_base, /* Set to EA */ - auxio_base, nvr_sec_base; - int locked, - cur_reg; +typedef struct fdc37c93x_t { + uint8_t chip_id; + uint8_t is_apm; + uint8_t tries; + uint8_t gpio_regs[2]; + uint8_t auxio_reg; + uint8_t regs[48]; + uint8_t ld_regs[11][256]; + uint16_t gpio_base; /* Set to EA */ + uint16_t auxio_base; + uint16_t nvr_sec_base; + int locked; + int cur_reg; fdc_t *fdc; serial_t *uart[2]; access_bus_t *access_bus; @@ -87,15 +91,15 @@ make_port_sec(fdc37c93x_t *dev, uint8_t ld) } static uint8_t -fdc37c93x_auxio_read(uint16_t port, void *priv) +fdc37c93x_auxio_read(UNUSED(uint16_t port), void *priv) { - fdc37c93x_t *dev = (fdc37c93x_t *) priv; + const fdc37c93x_t *dev = (fdc37c93x_t *) priv; return dev->auxio_reg; } static void -fdc37c93x_auxio_write(uint16_t port, uint8_t val, void *priv) +fdc37c93x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; @@ -105,8 +109,8 @@ fdc37c93x_auxio_write(uint16_t port, uint8_t val, void *priv) static uint8_t fdc37c93x_gpio_read(uint16_t port, void *priv) { - fdc37c93x_t *dev = (fdc37c93x_t *) priv; - uint8_t ret = 0xff; + const fdc37c93x_t *dev = (fdc37c93x_t *) priv; + uint8_t ret = 0xff; ret = dev->gpio_regs[port & 1]; @@ -239,6 +243,9 @@ fdc37c93x_gpio_handler(fdc37c93x_t *dev) case 3: ld_port = 0xea; /* Default */ break; + + default: + break; } dev->gpio_base = ld_port; if (ld_port > 0x0000) @@ -250,8 +257,8 @@ fdc37c93x_gpio_handler(fdc37c93x_t *dev) static uint8_t fdc37c93x_access_bus_read(uint16_t port, void *priv) { - access_bus_t *dev = (access_bus_t *) priv; - uint8_t ret = 0xff; + const access_bus_t *dev = (access_bus_t *) priv; + uint8_t ret = 0xff; switch (port & 3) { case 0: @@ -266,6 +273,9 @@ fdc37c93x_access_bus_read(uint16_t port, void *priv) case 3: ret = (dev->clock & 0x87); break; + + default: + break; } return ret; @@ -290,6 +300,9 @@ fdc37c93x_access_bus_write(uint16_t port, uint8_t val, void *priv) dev->clock &= 0x80; dev->clock |= (val & 0x07); break; + + default: + break; } } @@ -410,6 +423,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (!dev->is_apm) return; break; + + default: + break; } dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; } @@ -436,6 +452,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if ((valxor & 0x40) && (dev->chip_id != 0x02)) fdc37c93x_access_bus_handler(dev); break; + + default: + break; } return; @@ -489,6 +508,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x18) fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); break; + + default: + break; } break; case 3: @@ -503,6 +525,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_lpt_handler(dev); break; + + default: + break; } break; case 4: @@ -517,6 +542,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_serial_handler(dev, 0); break; + + default: + break; } break; case 5: @@ -531,6 +559,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_serial_handler(dev, 1); break; + + default: + break; } break; case 6: @@ -554,8 +585,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); if (dev->ld_regs[6][dev->cur_reg] & 0x80) switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) { - case 0x00: default: + case 0x00: nvr_bank_set(0, 0xff, dev->nvr); nvr_bank_set(1, 1, dev->nvr); break; @@ -588,6 +619,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) } } break; + + default: + break; } break; case 8: @@ -600,6 +634,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_auxio_handler(dev); break; + + default: + break; } break; case 9: @@ -614,6 +651,9 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_access_bus_handler(dev); break; + + default: + break; } break; case 10: @@ -628,8 +668,14 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (valxor) fdc37c93x_acpi_handler(dev); break; + + default: + break; } break; + + default: + break; } } @@ -783,7 +829,7 @@ access_bus_close(void *priv) } static void * -access_bus_init(const device_t *info) +access_bus_init(UNUSED(const device_t *info)) { access_bus_t *dev = (access_bus_t *) malloc(sizeof(access_bus_t)); memset(dev, 0, sizeof(access_bus_t)); @@ -830,7 +876,9 @@ fdc37c93x_init(const device_t *info) is_compaq = (info->local >> 8) & 0x02; dev->gpio_regs[0] = 0xff; - // dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; +#if 0 + dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; +#endif dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; if (dev->chip_id == 0x30) { diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index af238c51fb..38a1635383 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -68,9 +68,12 @@ fdc37m60x_log(const char *fmt, ...) # define fdc37m60x_log(fmt, ...) #endif -typedef struct -{ - uint8_t index, regs[256], device_regs[10][256], cfg_lock, ide_function; +typedef struct fdc37m60x_t { + uint8_t index; + uint8_t regs[256]; + uint8_t device_regs[10][256]; + uint8_t cfg_lock; + uint8_t ide_function; uint16_t sio_index_port; fdc_t *fdc; @@ -141,6 +144,9 @@ fdc37m60x_write(uint16_t addr, uint8_t val, void *priv) dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] = (INDEX == 0x30) ? (val & 1) : val; fdc37m60x_logical_device_handler(dev); break; + + default: + break; } } } else { @@ -157,8 +163,8 @@ fdc37m60x_write(uint16_t addr, uint8_t val, void *priv) static uint8_t fdc37m60x_read(uint16_t addr, void *priv) { - fdc37m60x_t *dev = (fdc37m60x_t *) priv; - uint8_t ret = 0xff; + const fdc37m60x_t *dev = (fdc37m60x_t *) priv; + uint8_t ret = 0xff; if (addr & 1) ret = (INDEX >= 0x30) ? dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] : dev->regs[INDEX]; @@ -242,6 +248,9 @@ fdc37m60x_logical_device_handler(fdc37m60x_t *dev) case 0x05: fdc37m60x_uart_handler(1, dev); break; + + default: + break; } } diff --git a/src/sio/sio_it8661f.c b/src/sio/sio_it8661f.c deleted file mode 100644 index 9b3baa1880..0000000000 --- a/src/sio/sio_it8661f.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * 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. - * - * Implementation of the ITE IT8661F chipset. - * - * Note: This Super I/O is partially incomplete and intended only for having the intended machine to function - * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 - * - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/fdd_common.h> -#include <86box/sio.h> - -#define LDN dev->regs[7] - -typedef struct -{ - fdc_t *fdc_controller; - serial_t *uart[2]; - - uint8_t index, regs[256], device_regs[6][256]; - int unlocked, enumerator; -} it8661f_t; - -static uint8_t mb_pnp_key[32] = { 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }; - -static void it8661f_reset(void *priv); - -#ifdef ENABLE_IT8661_LOG -int it8661_do_log = ENABLE_IT8661_LOG; - -void -it8661_log(const char *fmt, ...) -{ - va_list ap; - - if (it8661_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define it8661_log(fmt, ...) -#endif - -static void -it8661_fdc(uint16_t addr, uint8_t val, it8661f_t *dev) -{ - fdc_remove(dev->fdc_controller); - - if (((addr == 0x30) && (val & 1)) || (dev->device_regs[0][0x30] & 1)) { - switch (addr) { - case 0x30: - dev->device_regs[0][addr] = val & 1; - break; - - case 0x31: - dev->device_regs[0][addr] = val & 3; - if (val & 1) - dev->device_regs[0][addr] |= 0x55; - break; - - case 0x60: - case 0x61: - dev->device_regs[0][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); - break; - - case 0x70: - dev->device_regs[0][addr] = val & 0x0f; - break; - - case 0x74: - dev->device_regs[0][addr] = val & 7; - break; - - case 0xf0: - dev->device_regs[0][addr] = val & 0x0f; - break; - } - - fdc_set_base(dev->fdc_controller, (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61])); - fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0x0f); - fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 7); - - if (dev->device_regs[0][0xf0] & 1) - fdc_writeprotect(dev->fdc_controller); - - it8661_log("ITE 8661-FDC: BASE %04x IRQ %02x\n", (dev->device_regs[0][0x60] << 8) | (dev->device_regs[0][0x61]), - dev->device_regs[0][0x70] & 0x0f); - } -} - -static void -it8661_serial(int uart, uint16_t addr, uint8_t val, it8661f_t *dev) -{ - serial_remove(dev->uart[uart]); - - if (((addr == 0x30) && (val & 1)) || (dev->device_regs[1 + uart][0x30] & 1)) { - switch (addr) { - case 0x30: - dev->device_regs[1 + uart][addr] = val & 1; - break; - - case 0x60: - case 0x61: - dev->device_regs[1 + uart][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); - break; - - case 0x70: - dev->device_regs[1 + uart][addr] = val & 0x0f; - break; - - case 0x74: - dev->device_regs[1 + uart][addr] = val & 7; - break; - - case 0xf0: - dev->device_regs[1 + uart][addr] = val & 3; - break; - } - - serial_setup(dev->uart[uart], (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), dev->device_regs[1 + uart][0x70] & 0x0f); - - it8661_log("ITE 8661-UART%01x: BASE %04x IRQ %02x\n", 1 + (LDN % 1), - (dev->device_regs[1 + uart][0x60] << 8) | (dev->device_regs[1 + uart][0x61]), - dev->device_regs[1 + uart][0x70] & 0x0f); - } -} - -void -it8661_lpt(uint16_t addr, uint8_t val, it8661f_t *dev) -{ - lpt1_remove(); - - if (((addr == 0x30) && (val & 1)) || (dev->device_regs[3][0x30] & 1)) { - switch (addr) { - case 0x30: - dev->device_regs[3][addr] = val & 1; - break; - - case 0x60: - case 0x61: - dev->device_regs[3][addr] = val & ((addr == 0x61) ? 0xff : 0xf8); - break; - - case 0x70: - dev->device_regs[3][addr] = val & 0x0f; - break; - - case 0x74: - dev->device_regs[3][addr] = val & 7; - break; - - case 0xf0: - dev->device_regs[3][addr] = val & 3; - break; - } - - lpt1_init((dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61])); - lpt1_irq(dev->device_regs[3][0x70] & 0x0f); - - it8661_log("ITE 8661-LPT: BASE %04x IRQ %02x\n", (dev->device_regs[3][0x60] << 8) | (dev->device_regs[3][0x61]), - dev->device_regs[3][0x70] & 0x0f); - } -} - -void -it8661_ldn(uint16_t addr, uint8_t val, it8661f_t *dev) -{ - switch (LDN) { - case 0: - it8661_fdc(addr, val, dev); - break; - case 1: - case 2: - it8661_serial((LDN & 2) - 1, addr, val, dev); - break; - case 3: - it8661_lpt(addr, val, dev); - break; - } -} - -static void -it8661f_write(uint16_t addr, uint8_t val, void *priv) -{ - it8661f_t *dev = (it8661f_t *) priv; - - switch (addr) { - case FDC_SECONDARY_ADDR: - if (!dev->unlocked) { - (val == mb_pnp_key[dev->enumerator]) ? dev->enumerator++ : (dev->enumerator = 0); - if (dev->enumerator == 31) { - dev->unlocked = 1; - it8661_log("ITE8661F: Unlocked!\n"); - } - } else - dev->index = val; - break; - - case 0x371: - if (dev->unlocked) { - switch (dev->index) { - case 0x02: - dev->regs[dev->index] = val; - if (val & 1) - it8661f_reset(dev); - if (val & 2) - dev->unlocked = 0; - break; - case 0x07: - dev->regs[dev->index] = val; - break; - case 0x22: - dev->regs[dev->index] = val & 0x30; - break; - case 0x23: - dev->regs[dev->index] = val & 0x1f; - break; - default: - it8661_ldn(dev->index, val, dev); - break; - } - } - break; - } - - return; -} - -static uint8_t -it8661f_read(uint16_t addr, void *priv) -{ - it8661f_t *dev = (it8661f_t *) priv; - - it8661_log("IT8661F:\n", addr, dev->regs[dev->index]); - return (addr == 0xa79) ? dev->regs[dev->index] : 0xff; -} - -static void -it8661f_reset(void *priv) -{ - it8661f_t *dev = (it8661f_t *) priv; - dev->regs[0x20] = 0x86; - dev->regs[0x21] = 0x61; - - dev->device_regs[0][0x60] = 3; - dev->device_regs[0][0x61] = 0xf0; - dev->device_regs[0][0x70] = 6; - dev->device_regs[0][0x71] = 2; - dev->device_regs[0][0x74] = 2; - - dev->device_regs[1][0x60] = 3; - dev->device_regs[1][0x61] = 0xf8; - dev->device_regs[1][0x70] = 4; - dev->device_regs[1][0x71] = 2; - - dev->device_regs[2][0x60] = 2; - dev->device_regs[2][0x61] = 0xf8; - dev->device_regs[2][0x70] = 3; - dev->device_regs[2][0x71] = 2; - - dev->device_regs[3][0x60] = 3; - dev->device_regs[3][0x61] = 0x78; - dev->device_regs[3][0x70] = 7; - dev->device_regs[3][0x71] = 2; - dev->device_regs[3][0x74] = 3; - dev->device_regs[3][0xf0] = 3; -} - -static void -it8661f_close(void *priv) -{ - it8661f_t *dev = (it8661f_t *) priv; - - free(dev); -} - -static void * -it8661f_init(const device_t *info) -{ - it8661f_t *dev = (it8661f_t *) malloc(sizeof(it8661f_t)); - memset(dev, 0, sizeof(it8661f_t)); - - dev->fdc_controller = device_add(&fdc_at_smc_device); - fdc_reset(dev->fdc_controller); - - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - - io_sethandler(FDC_SECONDARY_ADDR, 0x0002, it8661f_read, NULL, NULL, it8661f_write, NULL, NULL, dev); - - dev->enumerator = 0; - dev->unlocked = 0; - - it8661f_reset(dev); - return dev; -} - -const device_t it8661f_device = { - .name = "ITE IT8661F", - .internal_name = "it8661f", - .flags = 0, - .local = 0, - .init = it8661f_init, - .close = it8661f_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c new file mode 100644 index 0000000000..ece59501f5 --- /dev/null +++ b/src/sio/sio_it86x1f.c @@ -0,0 +1,873 @@ +/* + * 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. + * + * Emulation of the ITE IT86x1F Super I/O chips. + * + * + * + * Authors: RichardG, + * + * Copyright 2023 RichardG. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/gameport.h> +#include <86box/sio.h> +#include <86box/isapnp.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + +enum { + ITE_IT8661F = 0x8661, + ITE_IT8671F = 0x8681 +}; + +#define CHIP_ID *((uint16_t *) &dev->global_regs[0]) + +static void it8671f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); +static void it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); + +static const struct { + uint16_t chip_id; + uint16_t unlock_id; + uint8_t gpio_ldn; + /* Fake ROMs to delegate all the logical device register handling over to the ISAPnP subsystem. + The actual ROMs/IDs used by real chips when those are set to ISAPnP mode remain to be seen. */ + uint8_t *pnp_rom; + + const isapnp_device_config_t *pnp_defaults; + + void (*pnp_config_changed)(uint8_t ld, isapnp_device_config_t *config, void *priv); +} it86x1f_models[] = { + { + .chip_id = ITE_IT8661F, + .unlock_id = 0x8661, + .gpio_ldn = 0x05, + .pnp_rom = (uint8_t[]) { + 0x26, 0x85, 0x86, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, /* ITE8661, dummy checksum (filled in by isapnp_add_card) */ + 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ + + 0x15, 0x41, 0xd0, 0x07, 0x00, 0x01, /* logical device PNP0700, can participate in boot */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x05, 0x01, 0x01, /* logical device PNP0501, can participate in boot */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x05, 0x01, 0x01, /* logical device PNP0501, can participate in boot */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x04, 0x00, 0x01, /* logical device PNP0400, can participate in boot */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x100-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ + + 0x15, 0x41, 0xd0, 0x05, 0x10, 0x01, /* logical device PNP0510, can participate in boot */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x23, 0xf8, 0x0f, 0x02, /* IRQ 3/4/5/6/7/8/9/10/11, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + }, + .pnp_defaults = (const isapnp_device_config_t[]) { + { + .activate = 0, + .io = { { .base = FDC_PRIMARY_ADDR }, }, + .irq = { { .irq = FDC_PRIMARY_IRQ }, }, + .dma = { { .dma = FDC_PRIMARY_DMA }, } + }, { + .activate = 0, + .io = { { .base = COM1_ADDR }, }, + .irq = { { .irq = COM1_IRQ }, } + }, { + .activate = 0, + .io = { { .base = COM2_ADDR }, }, + .irq = { { .irq = COM2_IRQ }, } + }, { + .activate = 0, + .io = { { .base = LPT1_ADDR }, { .base = 0x778 }, }, + .irq = { { .irq = LPT1_IRQ }, }, + .dma = { { .dma = 3 }, } + }, { + .activate = 0, + .io = { { .base = COM4_ADDR }, { .base = 0x300 }, }, + .irq = { { .irq = 10 }, { .irq = 11 }, }, + .dma = { { .dma = 1 }, { .dma = 0 }, } + }, { + .activate = -1 + } + }, + .pnp_config_changed = it8661f_pnp_config_changed + }, { + .chip_id = ITE_IT8671F, + .unlock_id = 0x8680, + .gpio_ldn = 0x07, + .pnp_rom = (uint8_t[]) { + 0x26, 0x85, 0x86, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, /* ITE8671, dummy checksum (filled in by isapnp_add_card) */ + 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ + + 0x15, 0x41, 0xd0, 0x07, 0x00, 0x01, /* logical device PNP0700, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x05, 0x01, 0x01, /* logical device PNP0501, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x05, 0x10, 0x01, /* logical device PNP0510, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + + 0x15, 0x41, 0xd0, 0x04, 0x00, 0x01, /* logical device PNP0400, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0xFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xfc, 0x0f, 0x04, 0x04, /* I/O 0x100-0xFFC, decodes 16-bit, 4-byte alignment, 4 addresses */ + + 0x15, 0x41, 0xd0, 0xff, 0xff, 0x00, /* logical device PNPFFFF (dummy to create APC gap in LDNs) */ + + 0x15, 0x41, 0xd0, 0x03, 0x03, 0x01, /* logical device PNP0303, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + 0x47, 0x01, 0x00, 0x00, 0xff, 0x0f, 0x01, 0x01, /* I/O 0x0-0xFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x00, 0x00, 0xff, 0x0f, 0x01, 0x01, /* I/O 0x0-0xFFF, decodes 16-bit, 1-byte alignment, 1 address */ + + 0x15, 0x41, 0xd0, 0x0f, 0x13, 0x01, /* logical device PNP0F13, can participate in boot */ + 0x23, 0xfa, 0x1f, 0x02, /* IRQ 1/3/4/5/6/7/8/9/10/11/12, low true edge sensitive */ + + 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + }, + .pnp_defaults = (const isapnp_device_config_t[]) { + { + .activate = 0, + .io = { { .base = FDC_PRIMARY_ADDR }, }, + .irq = { { .irq = FDC_PRIMARY_IRQ }, }, + .dma = { { .dma = FDC_PRIMARY_DMA }, } + }, { + .activate = 0, + .io = { { .base = COM1_ADDR }, }, + .irq = { { .irq = COM1_IRQ }, } + }, { + .activate = 0, + .io = { { .base = COM2_ADDR }, { .base = 0x300 }, }, + .irq = { { .irq = COM2_IRQ }, { .irq = 10 }, }, + .dma = { { .dma = 0 }, { .dma = 1 }, } + }, { + .activate = 0, + .io = { { .base = LPT1_ADDR }, { .base = 0x778 }, }, + .irq = { { .irq = LPT1_IRQ }, }, + .dma = { { .dma = 3 }, } + }, { + .activate = 0 + }, { + .activate = 1, + .io = { { .base = 0x60 }, { .base = 0x64 }, }, + .irq = { { .irq = 1 }, } + }, { + .activate = 0, + .irq = { { .irq = 12 }, } + }, { + .activate = -1 + } + }, + .pnp_config_changed = it8671f_pnp_config_changed + } +}; + +#ifdef ENABLE_IT86X1F_LOG +int it86x1f_do_log = ENABLE_IT86X1F_LOG; + +static void +it86x1f_log(const char *fmt, ...) +{ + va_list ap; + + if (it86x1f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define it86x1f_log(fmt, ...) +#endif + +typedef struct it86x1f_t { + uint8_t instance; + uint8_t locked; + uint8_t cur_ldn; + uint8_t cur_reg; + void *pnp_card; + uint8_t global_regs[16]; /* [0x20:0x2f] */ + uint8_t ldn_regs[8][16]; /* [0xf0:0xff] */ + uint8_t gpio_regs[36]; /* [0x60:0x7f] then [0xe0:0xe3] */ + uint8_t gpio_ldn; + + uint16_t unlock_id; + uint16_t addr_port; + uint16_t data_port; + uint8_t unlock_val; + uint8_t unlock_pos : 2; + uint8_t key_pos : 5; + + fdc_t *fdc; + serial_t *uart[2]; + void *gameport; +} it86x1f_t; + +static void it86x1f_remap(it86x1f_t *dev, uint16_t addr_port, uint16_t data_port); + +static void +it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + if (ld > 5) { + it86x1f_log("IT86x1F: Unknown logical device %d\n", ld); + return; + } + + it86x1f_t *dev = (it86x1f_t *) priv; + + switch (ld) { + case 0: + fdc_remove(dev->fdc); + + if (config->activate) { + it86x1f_log("IT86x1F: FDC enabled at port %04X IRQ %d DMA %d\n", config->io[0].base, config->irq[0].irq, (config->dma[0].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[0].dma); + + if (config->io[0].base != ISAPNP_IO_DISABLED) + fdc_set_base(dev->fdc, config->io[0].base); + + fdc_set_irq(dev->fdc, config->irq[0].irq); + fdc_set_dma_ch(dev->fdc, (config->dma[0].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[0].dma); + } else { + it86x1f_log("IT86x1F: FDC disabled\n"); + } + + break; + + case 1: + case 2: + serial_remove(dev->uart[ld - 1]); + + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { + it86x1f_log("IT86x1F: UART %d enabled at port %04X IRQ %d\n", ld - 1, config->io[0].base, config->irq[0].irq); + serial_setup(dev->uart[ld - 1], config->io[0].base, config->irq[0].irq); + } else { + it86x1f_log("IT86x1F: UART %d disabled\n", ld - 1); + } + + break; + + case 3: + lpt1_remove(); + + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { + it86x1f_log("IT86x1F: LPT enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq); + lpt1_init(config->io[0].base); + } else { + it86x1f_log("IT86x1F: LPT disabled\n"); + } + + break; + + case 4: + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { + it86x1f_log("IT86x1F: IR enabled at ports %04X %04X IRQs %d %d DMAs %d %d\n", config->io[0].base, config->io[1].base, config->irq[0].irq, config->irq[1].irq, (config->dma[0].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[0].dma, (config->dma[1].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[1].dma); + } else { + it86x1f_log("IT86x1F: IR disabled\n"); + } + break; + + default: + break; + } +} + +static void +it8671f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + + switch (ld) { + case 2: + it8661f_pnp_config_changed(4, config, dev); /* just for logging, should change if IR UART is implemented */ + fallthrough; + + case 0 ... 1: + case 3: + it8661f_pnp_config_changed(ld, config, dev); + break; + + case 5: + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED) && (config->io[1].base != ISAPNP_IO_DISABLED)) { + it86x1f_log("IT86x1F: KBC enabled at ports %04X %04X IRQ %d\n", config->io[0].base, config->io[1].base, config->irq[0].irq); + } else { + it86x1f_log("IT86x1F: KBC disabled\n"); + } + break; + + case 6: + if (config->activate) { + it86x1f_log("IT86x1F: KBC mouse enabled at IRQ %d\n", config->irq[0].irq); + } else { + it86x1f_log("IT86x1F: KBC mouse disabled\n"); + } + break; + + default: + break; + } +} + +static uint8_t +it86x1f_pnp_read_vendor_reg(uint8_t ld, uint8_t reg, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x20 ... 0x2f: + ret = dev->global_regs[reg & 0x0f]; + break; + + case 0x60 ... 0x7f: + if (ld != dev->gpio_ldn) + break; + + ret = dev->gpio_regs[reg & 0x1f]; + break; + + case 0xe0 ... 0xe3: + if (ld != dev->gpio_ldn) + break; + + ret = dev->gpio_regs[0x20 | (reg & 0x03)]; + break; + + case 0xf0 ... 0xff: + if (ld > dev->gpio_ldn) + break; + + ret = dev->ldn_regs[ld][reg & 0x0f]; + break; + + default: + break; + } + + it86x1f_log("IT86x1F: read_vendor_reg(%X, %02X) = %02X\n", ld, reg, ret); + + return ret; +} + +static void +it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + uint8_t effective_ldn; + + it86x1f_log("IT86x1F: write_vendor_reg(%X, %02X, %02X)\n", ld, reg, val); + + switch (reg) { + case 0x22: + if (CHIP_ID == ITE_IT8661F) { + dev->global_regs[reg & 0x0f] = (val & 0x30) | (dev->global_regs[reg & 0x0f] & ~0x30); + uint8_t mcc = (val & 0x30) >> 4; + if (mcc != dev->instance) { + it86x1f_log("IT86x1F: Instance %d unmapping as ID %d was written\n", dev->instance, mcc); + it86x1f_remap(dev, 0, 0); + } + } + break; + + case 0x23: + val &= (1 << dev->gpio_ldn) - 1; + dev->global_regs[reg & 0x0f] = val; +#ifdef ENABLE_IT86X1F_LOG + if (val) + it86x1f_log("IT86x1F: Warning: ISAPnP mode enabled.\n"); +#endif + break; + + case 0x24: + dev->global_regs[reg & 0x0f] = val & ((CHIP_ID == ITE_IT8661F) ? 0x03 : 0x5f); + break; + + case 0x25: + val &= (CHIP_ID == ITE_IT8661F) ? 0x1f : 0xf0; + fallthrough; + + case 0x26: + if (ld == dev->gpio_ldn) + dev->global_regs[reg & 0x0f] = val; + break; + + case 0x2e ... 0x2f: + if ((CHIP_ID == ITE_IT8671F) && (ld == 0xf4)) + dev->global_regs[reg & 0x0f] = val; + break; + + case 0x60 ... 0x7f: + if (ld != dev->gpio_ldn) + break; + + dev->gpio_regs[reg & 0x1f] = val; + break; + + case 0xe0 ... 0xe3: + if (ld != dev->gpio_ldn) + break; + + dev->gpio_regs[0x20 | (reg & 0x0f)] = val; + break; + + case 0xf0 ... 0xff: + /* Translate GPIO LDN to 7 for the switch block. */ + if (ld == dev->gpio_ldn) + effective_ldn = 7; + else if (ld == 7) + effective_ldn = 8; /* dummy */ + else + effective_ldn = ld; + + switch ((effective_ldn << 8) | reg) { + case 0x0f0: + dev->ldn_regs[ld][reg & 0x0f] = val & 0x0f; + fdc_set_swwp(dev->fdc, !!(val & 0x01)); + fdc_set_swap(dev->fdc, !!(val & 0x04)); + break; + + case 0x1f0: + dev->ldn_regs[ld][reg & 0x0f] = val & 0x03; + break; + + case 0x2f0: + dev->ldn_regs[ld][reg & 0x0f] = val & ((CHIP_ID == ITE_IT8661F) ? 0x03 : 0xf3); + break; + + case 0x2f1: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0xb7; + break; + + case 0x3f0: + dev->ldn_regs[ld][reg & 0x0f] = val & 0x07; + break; + + case 0x4f0: + if (CHIP_ID == ITE_IT8661F) + val &= 0x3f; + dev->ldn_regs[ld][reg & 0x0f] = val; + break; + + case 0x4f1: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0x7f; + break; + + case 0x4f2: + case 0x4f6: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val; + break; + + case 0x4f7: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0x7f; + break; + + case 0x4f8: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0x07; + break; + + case 0x5f0: + dev->ldn_regs[ld][reg & 0x0f] = val & 0x1f; + break; + + case 0x6f0: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0x03; + break; + + case 0x760: + case 0x762: + case 0x764: + case 0x766: + dev->gpio_regs[reg & 0x1f] = val & 0x0f; + break; + + case 0x772: + if (CHIP_ID != ITE_IT8671F) + break; + fallthrough; + + case 0x761: + case 0x763: + case 0x765: + case 0x767: + case 0x770: + dev->gpio_regs[reg & 0x1f] = val; + + case 0x771: + if (CHIP_ID == ITE_IT8671F) + dev->gpio_regs[reg & 0x1f] = val & 0xde; + break; + + case 0x7e0: + if (CHIP_ID == ITE_IT8671F) + dev->gpio_regs[0x20 | (reg & 0x03)] = val & 0xef; + break; + + case 0x7e1: + if (CHIP_ID == ITE_IT8671F) + dev->gpio_regs[0x20 | (reg & 0x03)] = val & 0x7f; + break; + + case 0x7e3: + if ((CHIP_ID == ITE_IT8671F) && (val & 0x80)) + *((uint16_t *) &dev->gpio_regs[0x22]) = 0x0000; + break; + + case 0x7fb: + if (CHIP_ID == ITE_IT8671F) + val &= 0x7f; + fallthrough; + + case 0x7f0 ... 0x7f5: + dev->ldn_regs[ld][reg & 0x0f] = val; + break; + + case 0x7f6: + dev->ldn_regs[ld][reg & 0x0f] = val & ((CHIP_ID == ITE_IT8661F) ? 0x3f : 0xcf); + break; + + case 0x7f7: + dev->ldn_regs[ld][reg & 0x0f] = val & ((CHIP_ID == ITE_IT8661F) ? 0x9f : 0xdf); + break; + + case 0x7f8 ... 0x7fa: + dev->ldn_regs[ld][reg & 0x0f] = val & ((CHIP_ID == ITE_IT8661F) ? 0x1f : 0x0f); + break; + + case 0x7fc: + if (CHIP_ID == ITE_IT8661F) + dev->ldn_regs[ld][reg & 0x0f] = val; + break; + + case 0x7ff: + if (CHIP_ID == ITE_IT8671F) + dev->ldn_regs[ld][reg & 0x0f] = val & 0x2f; + break; + + default: + break; + } + break; + + default: + break; + } +} + +static void +it86x1f_write_addr(uint16_t port, uint8_t val, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + + it86x1f_log("IT86x1F: write_addr(%04X, %02X)\n", port, val); + + if (dev->locked) { + if (val == isapnp_init_key[dev->key_pos]) { + if (++dev->key_pos == 0) { + it86x1f_log("IT86x1F: Unlocked\n"); + dev->locked = 0; + } + } else { + dev->key_pos = 0; + } + } else { + dev->cur_reg = val; + } +} + +static void +it86x1f_write_data(uint16_t port, uint8_t val, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + + it86x1f_log("IT86x1F: write_data(%04X, %02X)\n", port, val); + + if (dev->locked) + return; + + switch (dev->cur_reg) { + case 0x00 ... 0x01: + case 0x03 ... 0x06: + case 0x31: + case 0x71: + case 0x73: + break; /* ISAPnP-only */ + + case 0x07: + dev->cur_ldn = val; + break; + + case 0x02: + if (val & 0x02) { + it86x1f_log("IT86x1F: Locked => "); + dev->locked = 1; + it86x1f_remap(dev, 0, 0); + } + fallthrough; + + default: + isapnp_write_reg(dev->pnp_card, dev->cur_ldn, dev->cur_reg, val); + break; + } +} + +static uint8_t +it86x1f_read_addr(uint16_t port, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + uint8_t ret = dev->locked ? 0xff : dev->cur_reg; + + it86x1f_log("IT86x1F: read_addr(%04X) = %02X\n", port, ret); + + return ret; +} + +static uint8_t +it86x1f_read_data(uint16_t port, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + uint8_t ret = 0xff; + + switch (dev->cur_reg) { + case 0x00 ... 0x01: + case 0x03 ... 0x06: + case 0x31: + case 0x71: + case 0x73: + break; /* ISAPnP-only */ + + case 0x07: + ret = dev->cur_ldn; + break; + + default: + ret = isapnp_read_reg(dev->pnp_card, dev->cur_ldn, dev->cur_reg); + break; + } + + it86x1f_log("IT86x1F: read_data(%04X) = %02X\n", port, ret); + + return ret; +} + +static void +it86x1f_remap(it86x1f_t *dev, uint16_t addr_port, uint16_t data_port) +{ + if (dev->addr_port) + io_removehandler(dev->addr_port, 1, it86x1f_read_addr, NULL, NULL, it86x1f_write_addr, NULL, NULL, dev); + if (dev->data_port) + io_removehandler(dev->data_port, 1, it86x1f_read_data, NULL, NULL, it86x1f_write_data, NULL, NULL, dev); + + it86x1f_log("IT86x1F: remap(%04X, %04X)\n", addr_port, data_port); + dev->addr_port = addr_port; + dev->data_port = data_port; + + if (dev->addr_port) + io_sethandler(dev->addr_port, 1, it86x1f_read_addr, NULL, NULL, it86x1f_write_addr, NULL, NULL, dev); + if (dev->data_port) + io_sethandler(dev->data_port, 1, it86x1f_read_data, NULL, NULL, it86x1f_write_data, NULL, NULL, dev); +} + +static void +it86x1f_write_unlock(UNUSED(uint16_t port), uint8_t val, void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + + it86x1f_log("IT86x1F: write_unlock(%04X, %02X)\n", port, val); + + if (!dev->locked) + dev->unlock_pos = 0; + + switch (dev->unlock_pos++) { + case 0: + if (val != (dev->unlock_id >> 8)) + dev->unlock_pos = 0; + break; + + case 1: + if (val != (dev->unlock_id & 0xff)) + dev->unlock_pos = 0; + break; + + case 2: + if ((val != 0x55) && (val != 0xaa)) + dev->unlock_pos = 0; + else + dev->unlock_val = val; + break; + + case 3: + switch ((dev->unlock_val << 8) | val) { + case 0x5555: + it86x1f_remap(dev, 0x3f0, 0x3f1); + break; + + case 0x55aa: + it86x1f_remap(dev, 0x3bd, 0x3bf); + break; + + case 0xaa55: + it86x1f_remap(dev, 0x370, 0x371); + break; + + default: + it86x1f_remap(dev, 0, 0); + break; + } + dev->unlock_pos = 0; + break; + } +} + +void +it86x1f_reset(it86x1f_t *dev) +{ + it86x1f_log("IT86x1F: reset()\n"); + + fdc_reset(dev->fdc); + + serial_remove(dev->uart[0]); + + serial_remove(dev->uart[1]); + + lpt1_remove(); + + isapnp_enable_card(dev->pnp_card, ISAPNP_CARD_DISABLE); + + dev->locked = 1; + + isapnp_reset_card(dev->pnp_card); +} + +static void +it86x1f_close(void *priv) +{ + it86x1f_t *dev = (it86x1f_t *) priv; + + it86x1f_log("IT86x1F: close()\n"); + + free(dev); +} + +static void * +it86x1f_init(UNUSED(const device_t *info)) +{ + it86x1f_t *dev = (it86x1f_t *) malloc(sizeof(it86x1f_t)); + memset(dev, 0, sizeof(it86x1f_t)); + + uint8_t i; + for (i = 0; i < (sizeof(it86x1f_models) / sizeof(it86x1f_models[0])); i++) { + if (it86x1f_models[i].chip_id == info->local) + break; + } + if (i >= (sizeof(it86x1f_models) / sizeof(it86x1f_models[0]))) { +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + fatal("IT86x1F: Unknown type %04" PRIX64 " selected\n", info->local); +#else + fatal("IT86x1F: Unknown type %04X selected\n", info->local); +#endif + return NULL; + } +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + it86x1f_log("IT86x1F: init(%04" PRIX64 ")\n", info->local); +#else + it86x1f_log("IT86x1F: init(%04X)\n", info->local); +#endif + + /* Let the resource data parser figure out the ROM size. */ + dev->pnp_card = isapnp_add_card(it86x1f_models[i].pnp_rom, -1, it86x1f_models[i].pnp_config_changed, NULL, it86x1f_pnp_read_vendor_reg, it86x1f_pnp_write_vendor_reg, dev); + for (uint8_t j = 0; it86x1f_models[i].pnp_defaults[j].activate != (uint8_t) -1; j++) + isapnp_set_device_defaults(dev->pnp_card, j, &it86x1f_models[i].pnp_defaults[j]); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->gameport = gameport_add(&gameport_sio_device); + + dev->instance = device_get_instance(); + dev->gpio_ldn = it86x1f_models[i].gpio_ldn; + CHIP_ID = it86x1f_models[i].chip_id; + dev->unlock_id = it86x1f_models[i].unlock_id; + io_sethandler(0x279, 1, NULL, NULL, NULL, it86x1f_write_unlock, NULL, NULL, dev); + + it86x1f_reset(dev); + + return dev; +} + +const device_t it8661f_device = { + .name = "ITE IT8661F Super I/O", + .internal_name = "it8661f", + .flags = 0, + .local = ITE_IT8661F, + .init = it86x1f_init, + .close = it86x1f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t it8671f_device = { + .name = "ITE IT8671F Super I/O", + .internal_name = "it8671f", + .flags = 0, + .local = ITE_IT8671F, + .init = it86x1f_init, + .close = it86x1f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index 088467eeb4..ab7f8597e9 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -34,10 +34,14 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> - -typedef struct { - uint8_t tries, - regs[29], gpio[2]; +#include <86box/plat_unused.h> +#include <86box/machine.h> + +typedef struct pc87306_t { + uint8_t tries; + uint8_t regs[29]; + uint8_t gpio[2]; + uint16_t gpioba; int cur_reg; fdc_t *fdc; serial_t *uart[2]; @@ -48,37 +52,66 @@ static void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) { pc87306_t *dev = (pc87306_t *) priv; + uint32_t gpio = 0xffff0000; + + dev->gpio[port & 0x0001] = val; + + if (port & 0x0001) { + gpio |= ((uint32_t) val) << 8; + gpio |= dev->gpio[0]; + } else { + gpio |= ((uint32_t) dev->gpio[1]) << 8; + gpio |= val; + } - dev->gpio[port & 1] = val; + (void) machine_handle_gpio(1, gpio); } uint8_t pc87306_gpio_read(uint16_t port, void *priv) { - pc87306_t *dev = (pc87306_t *) priv; + uint32_t ret = machine_handle_gpio(0, 0xffffffff); - return dev->gpio[port & 1]; + if (port & 0x0001) + ret = (ret >> 8) & 0xff; + else + ret &= 0xff; + + return ret; } static void pc87306_gpio_remove(pc87306_t *dev) { - io_removehandler(dev->regs[0x0f] << 2, 0x0001, - pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); - io_removehandler((dev->regs[0x0f] << 2) + 1, 0x0001, - pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + if (dev->gpioba != 0x0000) { + io_removehandler(dev->gpioba, 0x0001, + pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + io_removehandler(dev->gpioba + 1, 0x0001, + pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + } } static void pc87306_gpio_init(pc87306_t *dev) { - if ((dev->regs[0x12]) & 0x10) - io_sethandler(dev->regs[0x0f] << 2, 0x0001, - pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + dev->gpioba = ((uint16_t) dev->regs[0x0f]) << 2; - if ((dev->regs[0x12]) & 0x20) - io_sethandler((dev->regs[0x0f] << 2) + 1, 0x0001, - pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + if (dev->gpioba != 0x0000) { + if ((dev->regs[0x12]) & 0x10) + io_sethandler(dev->gpioba, 0x0001, + pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + + if ((dev->regs[0x12]) & 0x20) + io_sethandler(dev->gpioba + 1, 0x0001, + pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, dev); + } +} + +static void +pc87306_gpio_handler(pc87306_t *dev) +{ + pc87306_gpio_remove(dev); + pc87306_gpio_init(dev); } static void @@ -112,6 +145,9 @@ lpt1_handler(pc87306_t *dev) lpt_port = 0x000; lpt_irq = 0xff; break; + + default: + break; } if (dev->regs[0x1b] & 0x10) @@ -165,6 +201,9 @@ serial_handler(pc87306_t *dev, int uart) case 3: serial_setup(dev->uart[uart], 0x220, irq); break; + + default: + break; } break; case 3: @@ -181,8 +220,14 @@ serial_handler(pc87306_t *dev, int uart) case 3: serial_setup(dev->uart[uart], 0x228, irq); break; + + default: + break; } break; + + default: + break; } } @@ -208,8 +253,6 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) if ((dev->cur_reg <= 28) && (dev->cur_reg != 8)) { if (dev->cur_reg == 0) val &= 0x5f; - if (((dev->cur_reg == 0x0F) || (dev->cur_reg == 0x12)) && valxor) - pc87306_gpio_remove(dev); dev->regs[dev->cur_reg] = val; } else return; @@ -220,7 +263,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } switch (dev->cur_reg) { - case 0: + case 0x00: if (valxor & 1) { lpt1_remove(); if ((val & 1) && !(dev->regs[2] & 1)) @@ -242,7 +285,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) fdc_set_base(dev->fdc, (val & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } break; - case 1: + case 0x01: if (valxor & 3) { lpt1_remove(); if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) @@ -259,7 +302,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) serial_handler(dev, 1); } break; - case 2: + case 0x02: if (valxor & 1) { lpt1_remove(); serial_remove(dev->uart[0]); @@ -283,19 +326,31 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) lpt1_handler(dev); } break; - case 9: + case 0x04: + if (valxor & 0x80) + nvr_lock_set(0x00, 256, !!(val & 0x80), dev->nvr); + break; + case 0x05: + if (valxor & 0x08) + nvr_at_handler(!!(val & 0x08), 0x0070, dev->nvr); + if (valxor & 0x20) + nvr_bank_set(0, !!(val & 0x20), dev->nvr); + break; + case 0x09: if (valxor & 0x44) { fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0); fdc_update_densel_polarity(dev->fdc, (val & 0x40) ? 1 : 0); } break; - case 0xF: + case 0x0f: if (valxor) - pc87306_gpio_init(dev); + pc87306_gpio_handler(dev); break; case 0x12: + if (valxor & 0x01) + nvr_wp_set(!!(val & 0x01), 0, dev->nvr); if (valxor & 0x30) - pc87306_gpio_init(dev); + pc87306_gpio_handler(dev); break; case 0x19: if (valxor) { @@ -324,6 +379,9 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) serial_handler(dev, 1); } break; + + default: + break; } } @@ -351,8 +409,10 @@ pc87306_read(uint16_t port, void *priv) } void -pc87306_reset(pc87306_t *dev) +pc87306_reset_common(void *priv) { + pc87306_t *dev = (pc87306_t *) priv; + memset(dev->regs, 0, 29); dev->regs[0x00] = 0x0B; @@ -366,9 +426,6 @@ pc87306_reset(pc87306_t *dev) dev->regs[0x12] = 0x30; dev->regs[0x19] = 0xEF; - dev->gpio[0] = 0xff; - dev->gpio[1] = 0xfb; - /* 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" @@ -381,6 +438,22 @@ pc87306_reset(pc87306_t *dev) serial_handler(dev, 1); fdc_reset(dev->fdc); pc87306_gpio_init(dev); + nvr_lock_set(0x00, 256, 0, dev->nvr); + nvr_at_handler(0, 0x0070, dev->nvr); + nvr_at_handler(1, 0x0070, dev->nvr); + nvr_bank_set(0, 0, dev->nvr); + nvr_wp_set(0, 0, dev->nvr); +} + +void +pc87306_reset(void *priv) +{ + pc87306_t *dev = (pc87306_t *) priv; + + pc87306_gpio_write(0x0000, 0xff, dev); + pc87306_gpio_write(0x0001, 0xff, dev); + + pc87306_reset_common(dev); } static void @@ -392,7 +465,7 @@ pc87306_close(void *priv) } static void * -pc87306_init(const device_t *info) +pc87306_init(UNUSED(const device_t *info)) { pc87306_t *dev = (pc87306_t *) malloc(sizeof(pc87306_t)); memset(dev, 0, sizeof(pc87306_t)); @@ -402,9 +475,11 @@ pc87306_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - // dev->nvr = device_add(&piix4_nvr_device); + dev->nvr = device_add(&at_mb_nvr_device); + + dev->gpio[0] = dev->gpio[1] = 0xff; - pc87306_reset(dev); + pc87306_reset_common(dev); io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, dev); @@ -419,7 +494,7 @@ const device_t pc87306_device = { .local = 0, .init = pc87306_init, .close = pc87306_close, - .reset = NULL, + .reset = pc87306_reset, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index 78cfdcd99a..63e19c03d5 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -35,13 +35,17 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t id, pm_idx, - regs[48], ld_regs[256][208], - pcregs[16], gpio[2][4], - pm[8]; - uint16_t gpio_base, gpio_base2, - pm_base; +typedef struct pc87307_t { + uint8_t id; + uint8_t pm_idx; + uint8_t regs[48]; + uint8_t ld_regs[256][208]; + uint8_t pcregs[16]; + uint8_t gpio[2][4]; + uint8_t pm[8]; + uint16_t gpio_base; + uint16_t gpio_base2; + uint16_t pm_base; int cur_reg; fdc_t *fdc; serial_t *uart[2]; @@ -63,17 +67,20 @@ pc87307_gpio_write(uint16_t port, uint8_t val, void *priv) uint8_t pc87307_gpio_read(uint16_t port, void *priv) { - pc87307_t *dev = (pc87307_t *) priv; - uint8_t pins = 0xff; - uint8_t bank = ((port & 0xfffc) == dev->gpio_base2); - uint8_t mask; - uint8_t ret = dev->gpio[bank][port & 0x0003]; + const pc87307_t *dev = (pc87307_t *) priv; + uint8_t pins = 0xff; + uint8_t bank = ((port & 0xfffc) == dev->gpio_base2); + uint8_t mask; + uint8_t ret = dev->gpio[bank][port & 0x0003]; switch (port & 0x0003) { case 0x0000: mask = dev->gpio[bank][0x0001]; ret = (ret & mask) | (pins & ~mask); break; + + default: + break; } return ret; @@ -122,6 +129,9 @@ pc87307_pm_write(uint16_t port, uint8_t val, void *priv) serial_handler(dev, 1); serial_handler(dev, 0); break; + + default: + break; } } } @@ -129,7 +139,7 @@ pc87307_pm_write(uint16_t port, uint8_t val, void *priv) uint8_t pc87307_pm_read(uint16_t port, void *priv) { - pc87307_t *dev = (pc87307_t *) priv; + const pc87307_t *dev = (pc87307_t *) priv; if (port & 1) return dev->pm[dev->pm_idx]; @@ -307,6 +317,9 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) case 0x08: pm_handler(dev); break; + + default: + break; } break; case 0x60: @@ -333,6 +346,9 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) case 0x08: pm_handler(dev); break; + + default: + break; } break; case 0x61: @@ -364,6 +380,9 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; pm_handler(dev); break; + + default: + break; } break; case 0x63: @@ -396,6 +415,9 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) case 0x08: pm_handler(dev); break; + + default: + break; } break; case 0xf0: @@ -416,21 +438,27 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) case 0x06: dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87; break; + + default: + break; } break; case 0xf1: if (dev->regs[0x07] == 0x03) dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; break; + + default: + break; } } uint8_t pc87307_read(uint16_t port, void *priv) { - pc87307_t *dev = (pc87307_t *) priv; - uint8_t ret = 0xff; - uint8_t index; + const pc87307_t *dev = (pc87307_t *) priv; + uint8_t ret = 0xff; + uint8_t index; index = (port & 1) ? 0 : 1; @@ -519,8 +547,10 @@ pc87307_reset(pc87307_t *dev) dev->ld_regs[0x08][0x44] = 0x04; dev->ld_regs[0x08][0x45] = 0x04; - // dev->gpio[0] = 0xff; - // dev->gpio[1] = 0xfb; +#if 0 + dev->gpio[0] = 0xff; + dev->gpio[1] = 0xfb; +#endif dev->gpio[0][0] = 0xff; dev->gpio[0][1] = 0x00; dev->gpio[0][2] = 0x00; diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index dfa41f601c..d10cb3e0bd 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -35,10 +35,12 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t id, pm_idx, - regs[48], ld_regs[256][208], - pm[8]; +typedef struct pc87309_t { + uint8_t id; + uint8_t pm_idx; + uint8_t regs[48]; + uint8_t ld_regs[256][208]; + uint8_t pm[8]; uint16_t pm_base; int cur_reg; fdc_t *fdc; @@ -64,6 +66,9 @@ pc87309_pm_write(uint16_t port, uint8_t val, void *priv) serial_handler(dev, 1); serial_handler(dev, 0); break; + + default: + break; } } else dev->pm_idx = val & 0x07; @@ -72,7 +77,7 @@ pc87309_pm_write(uint16_t port, uint8_t val, void *priv) uint8_t pc87309_pm_read(uint16_t port, void *priv) { - pc87309_t *dev = (pc87309_t *) priv; + const pc87309_t *dev = (pc87309_t *) priv; if (port & 1) return dev->pm[dev->pm_idx]; @@ -221,6 +226,9 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) case 0x04: pm_handler(dev); break; + + default: + break; } break; case 0x60: @@ -244,6 +252,9 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) case 0x04: pm_handler(dev); break; + + default: + break; } break; case 0x63: @@ -275,6 +286,9 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) case 0x06: dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; break; + + default: + break; } break; case 0x70: @@ -296,6 +310,9 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) case 0x04: pm_handler(dev); break; + + default: + break; } break; case 0xf0: @@ -316,21 +333,27 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) case 0x06: dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1; break; + + default: + break; } break; case 0xf1: if (dev->regs[0x07] == 0x00) dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; break; + + default: + break; } } uint8_t pc87309_read(uint16_t port, void *priv) { - pc87309_t *dev = (pc87309_t *) priv; - uint8_t ret = 0xff; - uint8_t index; + const pc87309_t *dev = (pc87309_t *) priv; + uint8_t ret = 0xff; + uint8_t index; index = (port & 1) ? 0 : 1; diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index eacbadf890..075b819ff5 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -8,15 +8,13 @@ * * Emulation of the NatSemi PC87310 Super I/O chip. * - * - * * Authors: Miran Grca, - * Tiseno100 - * EngiNerd + * EngiNerd, + * Tiseno100, * - * Copyright 2020 Miran Grca. - * Copyright 2020 Tiseno100 + * Copyright 2020-2024 Miran Grca. * Copyright 2021 EngiNerd. + * Copyright 2020 Tiseno100. */ #include #include @@ -40,8 +38,10 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> -#define HAS_IDE_FUNCTIONALITY dev->ide_function +#define FLAG_IDE 0x00000001 +#define FLAG_ALI 0x00000002 #ifdef ENABLE_PC87310_LOG int pc87310_do_log = ENABLE_PC87310_LOG; @@ -61,9 +61,10 @@ pc87310_log(const char *fmt, ...) # define pc87310_log(fmt, ...) #endif -typedef struct { - uint8_t tries, ide_function, - reg; +typedef struct pc87310_t { + uint8_t tries; + uint8_t flags; + uint8_t regs[2]; fdc_t *fdc; serial_t *uart[2]; } pc87310_t; @@ -81,7 +82,9 @@ lpt1_handler(pc87310_t *dev) * 10 278h * 11 disabled */ - temp = dev->reg & 3; + temp = dev->regs[1] & 0x03; + + lpt1_remove(); switch (temp) { case 0: @@ -97,6 +100,9 @@ lpt1_handler(pc87310_t *dev) lpt_port = 0x000; lpt_irq = 0xff; break; + + default: + break; } if (lpt_port) @@ -106,99 +112,138 @@ lpt1_handler(pc87310_t *dev) } static void -serial_handler(pc87310_t *dev, int uart) +serial_handler(pc87310_t *dev) { - int temp; - /* bit 2: disable serial port 1 - * bit 3: disable serial port 2 - * bit 4: swap serial ports + uint8_t temp, temp2 = 0x00; + uint16_t base1 = 0x0000, base2 = 0x0000; + uint8_t irq1, irq2; + /* - Bit 2: Disable serial port 1; + * - Bit 3: Disable serial port 2; + * - Bit 4: Swap serial ports. */ - temp = (dev->reg >> (2 + uart)) & 1; - - // current serial port is enabled - if (!temp) { - // configure serial port as COM2 - if (((dev->reg >> 4) & 1) ^ uart) - serial_setup(dev->uart[uart], COM2_ADDR, COM2_IRQ); - // configure serial port as COM1 - else - serial_setup(dev->uart[uart], COM1_ADDR, COM1_IRQ); + temp = (dev->regs[1] >> 2) & 0x07; + + /* - Bits 1, 0: 0, 0 = Normal (3F8 and 2F8); + * 0, 1 = 2E8 instead of 2F8; + * 1, 0 = 3E8 instead of 3F8 and 2E8 instead of 2F8; + * 1, 1 = 3E8 instead of 3F8. + * + * If we XOR bit 0 with bit 1, we get this: + * 0, 0 = Normal (3F8 and 2F8); + * 0, 1 = 2E8 instead of 2F8; + * 1, 0 = 3E8 instead of 3F8; + * 1, 1 = 3E8 instead of 3F8 and 2E8 instead of 2F8. + * + * Then they become simple toggle bits. + * Therefore, we do this for easier operation. + */ + if (dev->flags & FLAG_ALI) { + temp2 = dev->regs[0] & 0x03; + temp2 ^= ((temp2 & 0x02) >> 1); + } + + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + + if (!(temp & 0x01)) { + base1 = (temp & 0x04) ? COM2_ADDR : COM1_ADDR; + if ((base1 == COM1_ADDR) && (temp2 & 0x02)) + base1 = 0x03e8; + else if ((base1 == COM2_ADDR) && (temp2 & 0x01)) + base1 = 0x02e8; + irq1 = (temp & 0x04) ? COM2_IRQ : COM1_IRQ; + serial_setup(dev->uart[0], base1, irq1); + pc87310_log("UART 1 at %04X, IRQ %i\n", base1, irq1); + } + + if (!(temp & 0x02)) { + base2 = (temp & 0x04) ? COM1_ADDR : COM2_ADDR; + if ((base2 == COM1_ADDR) && (temp2 & 0x02)) + base2 = 0x03e8; + else if ((base2 == COM2_ADDR) && (temp2 & 0x01)) + base2 = 0x02e8; + irq2 = (temp & 0x04) ? COM1_IRQ : COM2_IRQ; + serial_setup(dev->uart[1], base2, irq2); + pc87310_log("UART 2 at %04X, IRQ %i\n", base2, irq2); } } static void -pc87310_write(uint16_t port, uint8_t val, void *priv) +pc87310_write(UNUSED(uint16_t port), uint8_t val, void *priv) { pc87310_t *dev = (pc87310_t *) priv; uint8_t valxor; + uint8_t idx = (uint8_t) ((port & 0x0002) >> 1); - // second write to config register - if (dev->tries) { - valxor = val ^ dev->reg; - dev->tries = 0; - dev->reg = val; - // first write to config register - } else { - dev->tries++; - return; - } - - pc87310_log("SIO: written %01X\n", val); + pc87310_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); - /* reconfigure parallel port */ - if (valxor & 0x03) { - lpt1_remove(); - /* bits 0-1: 11 disable parallel port */ - if (!((val & 1) && (val & 2))) - lpt1_handler(dev); - } - /* reconfigure serial ports */ - if (valxor & 0x1c) { - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - /* bit 2: 1 disable first serial port */ - if (!(val & 4)) - serial_handler(dev, 0); - /* bit 3: 1 disable second serial port */ - if (!(val & 8)) - serial_handler(dev, 1); - } - /* reconfigure IDE controller */ - if (valxor & 0x20) { - pc87310_log("SIO: HDC disabled\n"); - ide_pri_disable(); - /* bit 5: 1 disable ide controller */ - if (!(val & 0x20) && HAS_IDE_FUNCTIONALITY) { - pc87310_log("SIO: HDC enabled\n"); - ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - ide_pri_enable(); - } - } - /* reconfigure floppy disk controller */ - if (valxor & 0x40) { - pc87310_log("SIO: FDC disabled\n"); - fdc_remove(dev->fdc); - /* bit 6: 1 disable fdc */ - if (!(val & 0x40)) { - pc87310_log("SIO: FDC enabled\n"); - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + if (dev->tries) { + /* Second write to config register. */ + valxor = val ^ dev->regs[idx]; + dev->tries = 0; + dev->regs[idx] = val; + + if (idx) { + /* Register, common to both PC87310 and ALi M5105. */ + pc87310_log("SIO: Common register written %02X\n", val); + + /* Reconfigure parallel port. */ + if (valxor & 0x03) + /* Bits 1, 0: 1, 1 = Disable parallel port. */ + lpt1_handler(dev); + + /* Reconfigure serial ports. */ + if (valxor & 0x1c) + serial_handler(dev); + + /* Reconfigure IDE controller. */ + if ((dev->flags & FLAG_IDE) && (valxor & 0x20)) { + pc87310_log("SIO: HDC disabled\n"); + ide_pri_disable(); + /* Bit 5: 1 = Disable IDE controller. */ + if (!(val & 0x20)) { + pc87310_log("SIO: HDC enabled\n"); + ide_set_base(0, 0x1f0); + ide_set_side(0, 0x3f6); + ide_pri_enable(); + } + } + + /* Reconfigure floppy disk controller. */ + if (valxor & 0x40) { + pc87310_log("SIO: FDC disabled\n"); + fdc_remove(dev->fdc); + /* Bit 6: 1 = Disable FDC. */ + if (!(val & 0x40)) { + pc87310_log("SIO: FDC enabled\n"); + fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + } + } + } else { + /* ALi M5105 extension register. */ + pc87310_log("SIO: M5105 extension register written %02X\n", val); + + /* Reconfigure serial ports. */ + if (valxor & 0x03) + serial_handler(dev); } - } - return; + } else + /* First write to config register. */ + dev->tries++; } uint8_t -pc87310_read(uint16_t port, void *priv) +pc87310_read(UNUSED(uint16_t port), void *priv) { pc87310_t *dev = (pc87310_t *) priv; uint8_t ret = 0xff; + uint8_t idx = (uint8_t) ((port & 0x0002) >> 1); dev->tries = 0; - ret = dev->reg; + ret = dev->regs[idx]; - pc87310_log("SIO: read %01X\n", ret); + pc87310_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); return ret; } @@ -206,20 +251,18 @@ pc87310_read(uint16_t port, void *priv) void pc87310_reset(pc87310_t *dev) { - dev->reg = 0x0; - dev->tries = 0; - /* - 0 = 360 rpm @ 500 kbps for 3.5" - 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" - */ - lpt1_remove(); + dev->regs[0] = 0x00; + dev->regs[1] = 0x00; + + dev->tries = 0; + lpt1_handler(dev); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - serial_handler(dev, 0); - serial_handler(dev, 1); + serial_handler(dev); + if (dev->flags & FLAG_IDE) { + ide_pri_disable(); + ide_pri_enable(); + } fdc_reset(dev->fdc); - // ide_pri_enable(); } static void @@ -233,25 +276,28 @@ pc87310_close(void *priv) static void * pc87310_init(const device_t *info) { - pc87310_t *dev = (pc87310_t *) malloc(sizeof(pc87310_t)); - memset(dev, 0, sizeof(pc87310_t)); + pc87310_t *dev = (pc87310_t *) calloc(1, sizeof(pc87310_t)); /* Avoid conflicting with machines that make no use of the PC87310 Internal IDE */ - HAS_IDE_FUNCTIONALITY = info->local; + dev->flags = info->local; dev->fdc = device_add(&fdc_at_nsc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); - if (HAS_IDE_FUNCTIONALITY) - device_add(&ide_isa_device); + if (dev->flags & FLAG_IDE) + device_add((dev->flags & FLAG_ALI) ? &ide_vlb_device : &ide_isa_device); pc87310_reset(dev); io_sethandler(0x3f3, 0x0001, pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); + if (dev->flags & FLAG_ALI) + io_sethandler(0x3f1, 0x0001, + pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); + return dev; } @@ -273,7 +319,21 @@ const device_t pc87310_ide_device = { .name = "National Semiconductor PC87310 Super I/O with IDE functionality", .internal_name = "pc87310_ide", .flags = 0, - .local = 1, + .local = FLAG_IDE, + .init = pc87310_init, + .close = pc87310_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ali5105_device = { + .name = "ALi M5105 Super I/O", + .internal_name = "ali5105", + .flags = 0, + .local = FLAG_ALI, .init = pc87310_init, .close = pc87310_close, .reset = NULL, diff --git a/src/sio/sio_pc87311.c b/src/sio/sio_pc87311.c index c795da8a94..9740753d11 100644 --- a/src/sio/sio_pc87311.c +++ b/src/sio/sio_pc87311.c @@ -32,6 +32,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> #define HAS_IDE_FUNCTIONALITY dev->ide_function @@ -64,10 +65,13 @@ pc87311_log(const char *fmt, ...) # define pc87311_log(fmt, ...) #endif -typedef struct -{ - uint8_t index, regs[256], cfg_lock, ide_function; - uint16_t base, irq; +typedef struct pc87311_t { + uint8_t index; + uint8_t regs[256]; + uint8_t cfg_lock; + uint8_t ide_function; + uint16_t base; + uint16_t irq; fdc_t *fdc_controller; serial_t *uart[2]; @@ -102,17 +106,23 @@ pc87311_write(uint16_t addr, uint8_t val, void *priv) case 0x02: POWER_TEST = val; break; + + default: + break; } break; + + default: + break; } pc87311_enable(dev); } static uint8_t -pc87311_read(uint16_t addr, void *priv) +pc87311_read(UNUSED(uint16_t addr), void *priv) { - pc87311_t *dev = (pc87311_t *) priv; + const pc87311_t *dev = (pc87311_t *) priv; return dev->regs[dev->index]; } @@ -181,6 +191,9 @@ pc87311_uart_handler(uint8_t num, pc87311_t *dev) dev->base = com4(dev); dev->irq = COM4_IRQ; break; + + default: + break; } serial_setup(dev->uart[num & 1], dev->base, dev->irq); pc87311_log("PC87311-UART%01x: BASE %04x IRQ %01x\n", num & 1, dev->base, dev->irq); @@ -203,6 +216,9 @@ pc87311_lpt_handler(pc87311_t *dev) dev->base = LPT2_ADDR; dev->irq = LPT2_IRQ; break; + + default: + break; } lpt1_init(dev->base); lpt1_irq(dev->irq); diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c index 7f48b899b7..5cbf9f694b 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc87332.c @@ -35,9 +35,11 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct { - uint8_t tries, has_ide, - fdc_on, regs[15]; +typedef struct pc87332_t { + uint8_t tries; + uint8_t has_ide; + uint8_t fdc_on; + uint8_t regs[15]; int cur_reg; fdc_t *fdc; serial_t *uart[2]; @@ -69,6 +71,9 @@ lpt1_handler(pc87332_t *dev) lpt_port = 0x000; lpt_irq = 0xff; break; + + default: + break; } if (lpt_port) @@ -105,6 +110,9 @@ serial_handler(pc87332_t *dev, int uart) case 3: serial_setup(dev->uart[uart], 0x220, COM3_IRQ); break; + + default: + break; } break; case 3: @@ -121,8 +129,14 @@ serial_handler(pc87332_t *dev, int uart) case 3: serial_setup(dev->uart[uart], 0x228, COM4_IRQ); break; + + default: + break; } break; + + default: + break; } } @@ -238,6 +252,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) lpt1_handler(dev); } break; + + default: + break; } } diff --git a/src/sio/sio_prime3b.c b/src/sio/sio_prime3b.c index a204fde5b6..c93630516e 100644 --- a/src/sio/sio_prime3b.c +++ b/src/sio/sio_prime3b.c @@ -32,6 +32,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> #define FSR dev->regs[0xa0] #define ASR dev->regs[0xa1] @@ -56,10 +57,13 @@ prime3b_log(const char *fmt, ...) # define prime3b_log(fmt, ...) #endif -typedef struct -{ - uint8_t index, regs[256], cfg_lock, ide_function; - uint16_t com3_addr, com4_addr; +typedef struct prime3b_t { + uint8_t index; + uint8_t regs[256]; + uint8_t cfg_lock; + uint8_t ide_function; + uint16_t com3_addr; + uint16_t com4_addr; fdc_t *fdc_controller; serial_t *uart[2]; @@ -121,19 +125,25 @@ prime3b_write(uint16_t addr, uint8_t val, void *priv) dev->com3_addr = 0x220; dev->com4_addr = 0x228; break; + + default: + break; } break; case 0xa5: /* ECP Register */ dev->regs[0xa5] = val; break; + + default: + break; } } } static uint8_t -prime3b_read(uint16_t addr, void *priv) +prime3b_read(UNUSED(uint16_t addr), void *priv) { - prime3b_t *dev = (prime3b_t *) priv; + const prime3b_t *dev = (prime3b_t *) priv; return dev->regs[dev->index]; } diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c index eae3fe1b21..b19f861bf8 100644 --- a/src/sio/sio_prime3c.c +++ b/src/sio/sio_prime3c.c @@ -32,6 +32,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_unused.h> #ifdef ENABLE_PRIME3C_LOG int prime3c_do_log = ENABLE_PRIME3C_LOG; @@ -75,9 +76,11 @@ prime3c_log(const char *fmt, ...) /* IDE functionality(Note on Init) */ #define HAS_IDE_FUNCTIONALITY dev->ide_function -typedef struct -{ - uint8_t index, regs[256], cfg_lock, ide_function; +typedef struct prime3c_t { + uint8_t index; + uint8_t regs[256]; + uint8_t cfg_lock; + uint8_t ide_function; fdc_t *fdc_controller; serial_t *uart[2]; @@ -189,16 +192,22 @@ prime3c_write(uint16_t addr, uint8_t val, void *priv) case 0xd8: dev->regs[dev->index] = val; break; + + default: + break; } } break; + + default: + break; } } static uint8_t -prime3c_read(uint16_t addr, void *priv) +prime3c_read(UNUSED(uint16_t addr), void *priv) { - prime3c_t *dev = (prime3c_t *) priv; + const prime3c_t *dev = (prime3c_t *) priv; return dev->regs[dev->index]; } diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c new file mode 100644 index 0000000000..7391b029f1 --- /dev/null +++ b/src/sio/sio_um8663f.c @@ -0,0 +1,366 @@ +/* + * 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. + * + * Implementation of the UMC UMF8663F Super I/O chip. + * + * Authors: Miran Grca, + * + * Copyright 2024 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/gameport.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/sio.h> +#include <86box/random.h> +#include <86box/plat_unused.h> + +#ifdef ENABLE_UM8663F_LOG +int um8663f_do_log = ENABLE_UM8663F_LOG; + +static void +um8663f_log(const char *fmt, ...) +{ + va_list ap; + + if (um8663f_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define um8663f_log(fmt, ...) +#endif + +typedef struct um8663f_t { + uint8_t max_reg; + uint8_t ide; + uint8_t locked; + uint8_t cur_reg; + uint8_t regs[5]; + + fdc_t *fdc; + serial_t *uart[2]; +} um8663f_t; + +static void +um8663f_fdc_handler(um8663f_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0] & 0x01) + fdc_set_base(dev->fdc, (dev->regs[1] & 0x01) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); +} + +static void +um8663f_uart_handler(um8663f_t *dev, int port) +{ + uint8_t shift = (port + 1); + + serial_remove(dev->uart[port]); + if (dev->regs[0] & (2 << port)) { + switch ((dev->regs[1] >> shift) & 0x01) { + case 0x00: + if (port == 1) + serial_setup(dev->uart[port], COM4_ADDR, COM4_IRQ); + else + serial_setup(dev->uart[port], COM3_ADDR, COM1_IRQ); + break; + case 0x01: + if (port == 1) + serial_setup(dev->uart[port], COM2_ADDR, COM2_IRQ); + else + serial_setup(dev->uart[port], COM1_ADDR, COM1_IRQ); + break; + + default: + break; + } + } +} + +static void +um8663f_lpt_handler(um8663f_t *dev) +{ + lpt1_remove(); + if (dev->regs[0] & 0x08) { + switch ((dev->regs[1] >> 3) & 0x01) { + case 0x01: + lpt1_init(LPT1_ADDR); + lpt1_irq(7); + break; + case 0x00: + lpt1_init(LPT2_ADDR); + lpt1_irq(5); + break; + + default: + break; + } + } +} + +static void +um8663f_ide_handler(um8663f_t *dev) +{ + int board = dev->ide - 1; + + if (dev->ide > 0) { + ide_handlers(board, 0); + ide_set_base(board, (dev->regs[1] & 0x10) ? 0x01f0 : 0x0170); + ide_set_side(board, (dev->regs[1] & 0x10) ? 0x03f6 : 0x0376); + if (dev->regs[0] & 0x10) + ide_handlers(board, 1); + } +} + +static void +um8663f_write(uint16_t port, uint8_t val, void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + uint8_t valxor; + + um8663f_log("UM8663F: write(%04X, %02X)\n", port, val); + + if (dev->locked) { + if ((port == 0x108) && (val == 0xaa)) + dev->locked = 0; + } else { + if (port == 0x108) { + if (val == 0x55) + dev->locked = 1; + else + dev->cur_reg = val; + } else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + valxor = (dev->regs[dev->cur_reg - 0xc0] ^ val); + dev->regs[dev->cur_reg - 0xc0] = val; + switch (dev->cur_reg - 0xc0) { + /* Port enable register. */ + case 0x00: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + /* + Port configuration register: + - Bits 7, 6: + - 0, 0 = LPT 1 is none; + - 0, 1 = LPT 1 is EPP; + - 1, 0 = LPT 1 is SPP; + - 1, 1 = LPT 1 is ECP; + - Bit 4 = 0 = IDE is secondary, 1 = IDE is primary; + - Bit 3 = 0 = LPT 1 is 278h, 1 = LPT 1 is 378h; + - Bit 2 = 0 = UART 2 is COM4, 1 = UART 2 is COM2; + - Bit 1 = 0 = UART 1 is COM3, 1 = UART 2 is COM1; + - Bit 0 = 0 = FDC is 370h, 1 = UART 2 is 3f0h. + */ + case 0x01: + if (valxor & 0x10) + um8663f_ide_handler(dev); + if (valxor & 0x08) + um8663f_lpt_handler(dev); + if (valxor & 0x04) + um8663f_uart_handler(dev, 1); + if (valxor & 0x02) + um8663f_uart_handler(dev, 0); + if (valxor & 0x01) + um8663f_fdc_handler(dev); + break; + } + } + } +} + +static uint8_t +um8663f_read(uint16_t port, void *priv) +{ + const um8663f_t *dev = (um8663f_t *) priv; + uint8_t ret = 0xff; + + if (!dev->locked) { + if (port == 0x108) + ret = dev->cur_reg; /* ??? */ + else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= dev->max_reg)) { + ret = dev->regs[dev->cur_reg - 0xc0]; + if (dev->cur_reg == 0xc0) + ret = (ret & 0x1f) | ((random_generate() & 0x07) << 5); + } + } + + um8663f_log("UM8663F: read(%04X) = %02X\n", port, ret); + + return ret; +} + +static void +um8663f_reset(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + + lpt1_remove(); + lpt1_init(LPT1_ADDR); + + fdc_reset(dev->fdc); + fdc_remove(dev->fdc); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x00] = (dev->ide > 0) ? 0x1f : 0x0f; + dev->regs[0x01] = (dev->ide == 2) ? 0x0f : 0x1f; + + um8663f_fdc_handler(dev); + um8663f_uart_handler(dev, 0); + um8663f_uart_handler(dev, 1); + um8663f_lpt_handler(dev); + um8663f_ide_handler(dev); + + dev->locked = 1; +} + +static void +um8663f_close(void *priv) +{ + um8663f_t *dev = (um8663f_t *) priv; + + free(dev); +} + +static void * +um8663f_init(UNUSED(const device_t *info)) +{ + um8663f_t *dev = (um8663f_t *) calloc(1, sizeof(um8663f_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->ide = info->local & 0xff; + if (dev->ide < IDE_BUS_MAX) + device_add(&ide_isa_device); + + dev->max_reg = info->local >> 8; + + io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + + um8663f_reset(dev); + + return dev; +} + +const device_t um8663af_device = { + .name = "UMC UM8663AF Super I/O", + .internal_name = "um8663af", + .flags = 0, + .local = 0xc300, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_device = { + .name = "UMC UM8663AF Super I/O (With IDE)", + .internal_name = "um8663af_ide", + .flags = 0, + .local = 0xc301, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663af_ide_sec_device = { + .name = "UMC UM8663AF Super I/O (With Secondary IDE)", + .internal_name = "um8663af_ide_sec", + .flags = 0, + .local = 0xc302, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_device = { + .name = "UMC UM8663BF Super I/O", + .internal_name = "um8663bf", + .flags = 0, + .local = 0xc400, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_device = { + .name = "UMC UM8663BF Super I/O (With IDE)", + .internal_name = "um8663bf_ide", + .flags = 0, + .local = 0xc401, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8663bf_ide_sec_device = { + .name = "UMC UM8663BF Super I/O (With Secondary IDE)", + .internal_name = "um8663bf_ide_sec", + .flags = 0, + .local = 0xc402, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index bd153a9e42..136b1add6e 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -18,6 +18,35 @@ * Copyright 2016-2021 Miran Grca. * Copyright 2021 RichardG. */ + +/* + UMC UM8669F non-PnP register definitions + + C0: + [7] Infrared half duplex + [4:3] LPT mode: + 00 SPP + 01 EPP + 10 ECP + 11 ECP + EPP + + C1: + [7] Enable PnP access + [6:0] Always set regardless of PnP access enabled/disabled + + C2: + [6:5] Potentially pin muxing mode: (names from AMI "IR group" setup option) + 00 Reserved + 01 A (no IDE) + 10 B (no IDE) + 11 C + [4:3] Infrared mode: + 00 Reserved + 01 HPSIR + 10 ASKIR + 11 Disabled +*/ + #include #include #include @@ -35,10 +64,15 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/gameport.h> -#include <86box/sio.h> +#include <86box/hdc.h> #include <86box/isapnp.h> +#include <86box/hdc_ide.h> +#include <86box/sio.h> +#include <86box/plat_unused.h> -/* This ROM was reconstructed out of many assumptions, some of which based on the IT8671F. */ +/* Real chips don't have a PnP ROM and instead rely on the BIOS going in blind. + We create a fake ROM here (with values based on the IT8671F) to delegate + all the logical device register handling over to the ISAPnP subsystem. */ static uint8_t um8669f_pnp_rom[] = { 0x55, 0xa3, 0x86, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, /* UMC8669, dummy checksum (filled in by isapnp_add_card) */ 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ @@ -60,7 +94,9 @@ static uint8_t um8669f_pnp_rom[] = { 0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */ 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ - 0x15, 0x41, 0xd0, 0xff, 0xff, 0x00, /* logical device PNPFFFF (just a dummy to create a gap in LDNs) */ + 0x15, 0x41, 0xd0, 0x06, 0x00, 0x01, /* logical device PNP0600, can participate in boot */ + 0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */ + 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ 0x15, 0x41, 0xd0, 0xb0, 0x2f, 0x01, /* logical device PNPB02F, can participate in boot */ 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ @@ -86,7 +122,9 @@ static const isapnp_device_config_t um8669f_pnp_defaults[] = { .io = { { .base = LPT1_ADDR }, }, .irq = { { .irq = LPT1_IRQ }, } }, { - .activate = 0 + .activate = 0, + .io = { { .base = 0x1f0 }, }, + .irq = { { .irq = 14 }, } }, { .activate = 0, .io = { { .base = 0x200 }, } @@ -112,14 +150,14 @@ um8669f_log(const char *fmt, ...) #endif typedef struct um8669f_t { - int locked, cur_reg_108; - void *pnp_card; - isapnp_device_config_t *pnp_config[5]; - - uint8_t regs_108[256]; + uint8_t locked; + uint8_t cur_reg; + void *pnp_card; + uint8_t regs[3]; fdc_t *fdc; serial_t *uart[2]; + uint8_t ide; void *gameport; } um8669f_t; @@ -176,6 +214,22 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri break; + case 4: + if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) + um8669f_log("UM8669F: IDE enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq); + else + um8669f_log("UM8669F: IDE disabled\n"); + + if (dev->ide < IDE_BUS_MAX) { + config->io[1].base = config->io[0].base + 0x206; /* status port apparently fixed */ +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + ide_pnp_config_changed(0, config, (void *) (int64_t) dev->ide); +#else + ide_pnp_config_changed(0, config, (void *) (int) dev->ide); +#endif + } + break; + case 5: if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { um8669f_log("UM8669F: Game port enabled at port %04X\n", config->io[0].base); @@ -184,6 +238,10 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri um8669f_log("UM8669F: Game port disabled\n"); gameport_remap(dev->gameport, 0); } + break; + + default: + break; } } @@ -202,11 +260,11 @@ um8669f_write(uint16_t port, uint8_t val, void *priv) if (val == 0x55) dev->locked = 1; else - dev->cur_reg_108 = val; - } else { - dev->regs_108[dev->cur_reg_108] = val; + dev->cur_reg = val; + } else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= 0xc2)) { + dev->regs[dev->cur_reg & 3] = val; - if (dev->cur_reg_108 == 0xc1) { + if (dev->cur_reg == 0xc1) { um8669f_log("UM8669F: ISAPnP %sabled\n", (val & 0x80) ? "en" : "dis"); isapnp_enable_card(dev->pnp_card, (val & 0x80) ? ISAPNP_CARD_FORCE_CONFIG : ISAPNP_CARD_DISABLE); } @@ -217,14 +275,14 @@ um8669f_write(uint16_t port, uint8_t val, void *priv) uint8_t um8669f_read(uint16_t port, void *priv) { - um8669f_t *dev = (um8669f_t *) priv; - uint8_t ret = 0xff; + const um8669f_t *dev = (um8669f_t *) priv; + uint8_t ret = 0xff; if (!dev->locked) { if (port == 0x108) - ret = dev->cur_reg_108; /* ??? */ - else - ret = dev->regs_108[dev->cur_reg_108]; + ret = dev->cur_reg; /* ??? */ + else if ((dev->cur_reg >= 0xc0) && (dev->cur_reg <= 0xc2)) + ret = dev->regs[dev->cur_reg & 3]; } um8669f_log("UM8669F: read(%04X) = %02X\n", port, ret); @@ -245,6 +303,9 @@ um8669f_reset(um8669f_t *dev) lpt1_remove(); + if (dev->ide < IDE_BUS_MAX) + ide_remove_handlers(dev->ide); + isapnp_enable_card(dev->pnp_card, ISAPNP_CARD_DISABLE); dev->locked = 1; @@ -265,7 +326,7 @@ um8669f_close(void *priv) static void * um8669f_init(const device_t *info) { - um8669f_log("UM8669F: init()\n"); + um8669f_log("UM8669F: init(%02X)\n", info->local); um8669f_t *dev = (um8669f_t *) malloc(sizeof(um8669f_t)); memset(dev, 0, sizeof(um8669f_t)); @@ -279,6 +340,10 @@ um8669f_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->ide = info->local; + if (dev->ide < IDE_BUS_MAX) + device_add(&ide_isa_device); + dev->gameport = gameport_add(&gameport_sio_device); io_sethandler(0x0108, 0x0002, @@ -293,6 +358,20 @@ const device_t um8669f_device = { .name = "UMC UM8669F Super I/O", .internal_name = "um8669f", .flags = 0, + .local = 0xff, + .init = um8669f_init, + .close = um8669f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um8669f_ide_device = { + .name = "UMC UM8669F Super I/O (With IDE)", + .internal_name = "um8669f_ide", + .flags = 0, .local = 0, .init = um8669f_init, .close = um8669f_close, @@ -302,3 +381,17 @@ const device_t um8669f_device = { .force_redraw = NULL, .config = NULL }; + +const device_t um8669f_ide_sec_device = { + .name = "UMC UM8669F Super I/O (With Secondary IDE)", + .internal_name = "um8669f_ide_sec", + .flags = 0, + .local = 1, + .init = um8669f_init, + .close = um8669f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_vt82c686.c b/src/sio/sio_vt82c686.c index b03207041d..f22af07df5 100644 --- a/src/sio/sio_vt82c686.c +++ b/src/sio/sio_vt82c686.c @@ -31,10 +31,17 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> - -typedef struct { - uint8_t cur_reg, last_val, regs[25], - fdc_dma, fdc_irq, uart_irq[2], lpt_dma, lpt_irq; +#include <86box/plat_unused.h> + +typedef struct vt82c686_t { + uint8_t cur_reg; + uint8_t last_val; + uint8_t regs[25]; + uint8_t fdc_dma; + uint8_t fdc_irq; + uint8_t uart_irq[2]; + uint8_t lpt_dma; + uint8_t lpt_irq; fdc_t *fdc; serial_t *uart[2]; } vt82c686_t; @@ -189,6 +196,9 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv) dev->regs[reg] &= 0xf7; vt82c686_fdc_handler(dev); break; + + default: + break; } } @@ -242,6 +252,9 @@ vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv) if (val & 0x02) io_sethandler(FDC_PRIMARY_ADDR, 2, vt82c686_read, NULL, NULL, vt82c686_write, NULL, NULL, dev); break; + + default: + break; } } @@ -272,7 +285,7 @@ vt82c686_close(void *priv) } static void * -vt82c686_init(const device_t *info) +vt82c686_init(UNUSED(const device_t *info)) { vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); memset(dev, 0, sizeof(vt82c686_t)); diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 280bab6e9d..2e4b820598 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -74,13 +74,16 @@ w83787_log(const char *fmt, ...) #define HAS_IDE_FUNCTIONALITY dev->ide_function -typedef struct { - uint8_t tries, regs[42]; +typedef struct w83787f_t { + uint8_t tries; + uint8_t regs[42]; uint16_t reg_init; - int locked, rw_locked, - cur_reg, - key, ide_function, - ide_start; + int locked; + int rw_locked; + int cur_reg; + int key; + int ide_function; + int ide_start; fdc_t *fdc; serial_t *uart[2]; void *gameport; @@ -212,8 +215,9 @@ static void w83787f_fdc_handler(w83787f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08)) + if (!(dev->regs[0] & 0x20)) fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -255,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->locked) { - if (dev->rw_locked) + if (dev->rw_locked && (dev->cur_reg <= 0x0b)) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -342,6 +346,9 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x20) w83787f_remap(dev); break; + + default: + break; } } @@ -357,7 +364,7 @@ w83787f_read(uint16_t port, void *priv) else if (port == 0x252) { if (dev->cur_reg == 7) ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); - else if (!dev->rw_locked) + else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) ret = dev->regs[dev->cur_reg]; } } @@ -368,6 +375,8 @@ w83787f_read(uint16_t port, void *priv) static void w83787f_reset(w83787f_t *dev) { + uint16_t hefere = dev->reg_init & 0x0100; + lpt1_remove(); lpt1_init(LPT1_ADDR); lpt1_irq(LPT1_IRQ); @@ -398,13 +407,14 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x00] = 0xd0; fdc_reset(dev->fdc); + w83787f_fdc_handler(dev); dev->regs[0x01] = 0x2C; dev->regs[0x03] = 0x70; dev->regs[0x07] = 0xF5; dev->regs[0x09] = dev->reg_init & 0xff; dev->regs[0x0a] = 0x1F; - dev->regs[0x0c] = 0x2C; + dev->regs[0x0c] = 0x0C | (hefere >> 3); dev->regs[0x0d] = 0xA3; gameport_remap(dev->gameport, 0); @@ -414,7 +424,7 @@ w83787f_reset(w83787f_t *dev) w83787f_lpt_handler(dev); - dev->key = 0x89; + dev->key = 0x88 | (hefere >> 8); w83787f_remap(dev); @@ -450,17 +460,31 @@ w83787f_init(const device_t *info) dev->ide_start = !!(info->local & 0x40); - dev->reg_init = info->local & 0x0f; + dev->reg_init = info->local & 0x010f; w83787f_reset(dev); return dev; } +const device_t w83787f_88h_device = { + .name = "Winbond W83787F/IF Super I/O", + .internal_name = "w83787f", + .flags = 0, + .local = 0x0009, + .init = w83787f_init, + .close = w83787f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t w83787f_device = { .name = "Winbond W83787F/IF Super I/O", .internal_name = "w83787f", .flags = 0, - .local = 0x09, + .local = 0x0109, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -474,7 +498,7 @@ const device_t w83787f_ide_device = { .name = "Winbond W83787F/IF Super I/O (With IDE)", .internal_name = "w83787f_ide", .flags = 0, - .local = 0x19, + .local = 0x0119, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -488,7 +512,7 @@ const device_t w83787f_ide_en_device = { .name = "Winbond W83787F/IF Super I/O (With IDE Enabled)", .internal_name = "w83787f_ide_en", .flags = 0, - .local = 0x59, + .local = 0x0159, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -502,7 +526,7 @@ const device_t w83787f_ide_sec_device = { .name = "Winbond W83787F/IF Super I/O (With Secondary IDE)", .internal_name = "w83787f_ide_sec", .flags = 0, - .local = 0x39, + .local = 0x0139, .init = w83787f_init, .close = w83787f_close, .reset = NULL, diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index 4f8b451181..c9a437630e 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -56,13 +56,16 @@ #define PRTIQS (dev->regs[0x27] & 0x0f) #define ECPIRQ ((dev->regs[0x27] >> 5) & 0x07) -typedef struct { - uint8_t tries, regs[42]; - uint16_t reg_init; - int locked, rw_locked, - cur_reg, - base_address, key, - key_times; +typedef struct w83877f_t { + uint8_t tries; + uint8_t regs[42]; + uint16_t reg_init; + int locked; + int rw_locked; + int cur_reg; + int base_address; + int key; + int key_times; fdc_t *fdc; serial_t *uart[2]; } w83877f_t; @@ -75,12 +78,12 @@ w83877f_remap(w83877f_t *dev) { uint8_t hefras = HEFRAS; - io_removehandler(0x250, 0x0002, + io_removehandler(0x250, 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); io_removehandler(FDC_PRIMARY_ADDR, 0x0002, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250); - io_sethandler(dev->base_address, 0x0002, + io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003, w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); dev->key_times = hefras + 1; dev->key = (hefras ? 0x86 : 0x88) | HEFERE; @@ -140,6 +143,9 @@ make_port(w83877f_t *dev, uint8_t reg) if ((p < 0x100) || (p > 0x3F8)) p = COM2_ADDR; break; + + default: + break; } return p; @@ -149,8 +155,9 @@ static void w83877f_fdc_handler(w83877f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); + if (dev->regs[0x20] & 0xc0) + fdc_set_base(dev->fdc, make_port(dev, 0x20)); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); } static void @@ -246,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0x29) return; if (dev->cur_reg == 6) - val &= 0xF3; + val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -358,6 +365,9 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) w83877f_serial_handler(dev, 0); } break; + + default: + break; } } diff --git a/src/sio/sio_w83977f.c b/src/sio/sio_w83977f.c index 30a4c8b52b..063f0ca694 100644 --- a/src/sio/sio_w83977f.c +++ b/src/sio/sio_w83977f.c @@ -36,13 +36,17 @@ #define HEFRAS (dev->regs[0x26] & 0x40) -typedef struct { - uint8_t id, tries, - regs[48], - dev_regs[256][208]; - int locked, rw_locked, - cur_reg, base_address, - type, hefras; +typedef struct w83977f_t { + uint8_t id; + uint8_t tries; + uint8_t regs[48]; + uint8_t dev_regs[256][208]; + int locked; + int rw_locked; + int cur_reg; + int base_address; + int type; + int hefras; fdc_t *fdc; serial_t *uart[2]; } w83977f_t; @@ -145,6 +149,9 @@ w83977f_serial_handler(w83977f_t *dev, int uart) case 0x03: clock_src = 24000000.0 / 1.625; break; + + default: + break; } serial_set_clock_src(dev->uart[uart], clock_src); @@ -194,8 +201,10 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0x02: - /* if (valxor & 0x02) - softresetx86(); */ +#if 0 + if (valxor & 0x02) + softresetx86(); +#endif break; case 0x22: if (valxor & 0x20) @@ -226,6 +235,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) case 0x03: w83977f_serial_handler(dev, ld - 2); break; + + default: + break; } break; case 0x60: @@ -242,6 +254,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) case 0x03: w83977f_serial_handler(dev, ld - 2); break; + + default: + break; } break; case 0x70: @@ -257,6 +272,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) case 0x03: w83977f_serial_handler(dev, ld - 2); break; + + default: + break; } break; case 0xf0: @@ -281,6 +299,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x03) w83977f_serial_handler(dev, ld - 2); break; + + default: + break; } break; case 0xf1: @@ -298,6 +319,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (!dev->id && (valxor & 0x01)) fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); break; + + default: + break; } break; case 0xf2: @@ -315,6 +339,9 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (!dev->id && (valxor & 0x03)) fdc_update_rwc(dev->fdc, 0, val & 0x03); break; + + default: + break; } break; case 0xf4: @@ -329,8 +356,14 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (!dev->id && (valxor & 0x18)) fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); break; + + default: + break; } break; + + default: + break; } } diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index c530d7ac8a..72f05ff6dc 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -85,12 +85,13 @@ if(RTMIDI) endif() if(FLUIDSYNTH) - if(APPLE) - find_library(FLUIDSYNTH_LIB fluidsynth) - if (NOT FLUIDSYNTH_LIB) - message(WARNING "Could not find fluid synth. The library will not be bundled and any related features will not work.") - endif() - endif () + find_package(PkgConfig REQUIRED) + pkg_check_modules(FLUIDSYNTH REQUIRED IMPORTED_TARGET fluidsynth) + target_link_libraries(86Box PkgConfig::FLUIDSYNTH) + if(STATIC_BUILD) + target_link_libraries(86Box -static ${FLUIDSYNTH_STATIC_LIBRARIES} -fopenmp) + endif() + target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) target_sources(snd PRIVATE midi_fluidsynth.c) endif() @@ -124,5 +125,10 @@ if(GUSMAX) target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() +if(OPL4ML) + target_compile_definitions(snd PRIVATE USE_OPL4ML) + target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) +endif() + add_subdirectory(resid-fp) target_link_libraries(86Box resid-fp) diff --git a/src/sound/midi.c b/src/sound/midi.c index 50ddaaeb4e..bb107acbf9 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -10,12 +10,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Bit, * DOSBox Team, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * Copyright 2016-2020 Bit. * Copyright 2008-2020 DOSBox Team. @@ -101,6 +99,9 @@ static const MIDI_OUT_DEVICE devices[] = { #endif #ifdef USE_RTMIDI { &rtmidi_output_device }, +#endif +#if defined(DEV_BRANCH) && defined(USE_OPL4ML) + { &opl4_midi_device }, #endif { NULL } // clang-format on @@ -153,7 +154,7 @@ midi_out_device_has_config(int card) return devices[card].device->config ? 1 : 0; } -char * +const char * midi_out_device_get_internal_name(int card) { return device_get_internal_name(devices[card].device); @@ -176,7 +177,7 @@ midi_out_device_get_from_internal_name(char *s) void midi_out_device_init(void) { - if (devices[midi_output_device_current].device) + if ((midi_output_device_current > 0) && devices[midi_output_device_current].device) device_add(devices[midi_output_device_current].device); midi_output_device_last = midi_output_device_current; } @@ -271,7 +272,7 @@ midi_in_device_has_config(int card) return midi_in_devices[card].device->config ? 1 : 0; } -char * +const char * midi_in_device_get_internal_name(int card) { return device_get_internal_name(midi_in_devices[card].device); @@ -294,7 +295,7 @@ midi_in_device_get_from_internal_name(char *s) void midi_in_device_init(void) { - if (midi_in_devices[midi_input_device_current].device) + if ((midi_input_device_current > 0) && midi_in_devices[midi_input_device_current].device) device_add(midi_in_devices[midi_input_device_current].device); midi_input_device_last = midi_input_device_current; } @@ -408,7 +409,7 @@ midi_clear_buffer(void) } void -midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p) +midi_in_handler(int set, void (*msg)(void *priv, uint8_t *msg, uint32_t len), int (*sysex)(void *priv, uint8_t *buffer, uint32_t len, int abort), void *priv) { midi_in_handler_t *temp = NULL; midi_in_handler_t *next; @@ -425,7 +426,7 @@ midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int ( memset(temp, 0, sizeof(midi_in_handler_t)); temp->msg = msg; temp->sysex = sysex; - temp->p = p; + temp->priv = priv; if (mih_last == NULL) mih_first = mih_last = temp; @@ -440,7 +441,7 @@ midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int ( if (temp == NULL) break; - if ((temp->msg == msg) && (temp->sysex == sysex) && (temp->p == p)) { + if ((temp->msg == msg) && (temp->sysex == sysex) && (temp->priv == priv)) { if (temp->prev != NULL) temp->prev->next = temp->next; @@ -500,7 +501,7 @@ midi_in_msg(uint8_t *msg, uint32_t len) break; if (temp->msg) - temp->msg(temp->p, msg, len); + temp->msg(temp->priv, msg, len); temp = temp->next; @@ -548,9 +549,9 @@ midi_do_sysex(void) ret = 0; if (temp->sysex) { if (temp->cnt == 0) - ret = temp->sysex(temp->p, temp->buf, 0, 0); + ret = temp->sysex(temp->priv, temp->buf, 0, 0); else - ret = temp->sysex(temp->p, temp->buf, temp->len, 0); + ret = temp->sysex(temp->priv, temp->buf, temp->len, 0); } /* If count is 0 and length is 0, then this is just a finishing diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 2372203d73..c1b9956d08 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -1,111 +1,40 @@ /* some code borrowed from scummvm */ -#ifdef USE_FLUIDSYNTH -# include -# include -# include -# include -# include -# ifdef __unix__ -# include -# endif - -# include <86box/86box.h> -# include <86box/config.h> -# include <86box/device.h> -# include <86box/midi.h> -# include <86box/plat.h> -# include <86box/plat_dynld.h> -# include <86box/thread.h> -# include <86box/sound.h> -# include <86box/ui.h> - -# define FLUID_CHORUS_DEFAULT_N 3 -# define FLUID_CHORUS_DEFAULT_LEVEL 2.0f -# define FLUID_CHORUS_DEFAULT_SPEED 0.3f -# define FLUID_CHORUS_DEFAULT_DEPTH 8.0f -# define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE - -# define RENDER_RATE 100 -# define BUFFER_SEGMENTS 10 - -enum fluid_chorus_mod { - FLUID_CHORUS_MOD_SINE = 0, - FLUID_CHORUS_MOD_TRIANGLE = 1 -}; - -enum fluid_interp { - FLUID_INTERP_NONE = 0, - FLUID_INTERP_LINEAR = 1, - FLUID_INTERP_DEFAULT = 4, - FLUID_INTERP_4THORDER = 4, - FLUID_INTERP_7THORDER = 7, - FLUID_INTERP_HIGHEST = 7 -}; +#include +#include +#include +#include +#include +#ifdef __unix__ +# include +#endif +#define FLUIDSYNTH_NOT_A_DLL +#include + +#include <86box/86box.h> +#include <86box/config.h> +#include <86box/device.h> +#include <86box/midi.h> +#include <86box/thread.h> +#include <86box/sound.h> +#include <86box/plat_unused.h> + +#define RENDER_RATE 100 +#define BUFFER_SEGMENTS 10 + +/* Check the FluidSynth version to determine wheteher to use the older reverb/chorus + control functions that were deprecated in 2.2.0, or their newer replacements */ +#if (FLUIDSYNTH_VERSION_MAJOR < 2) || ((FLUIDSYNTH_VERSION_MAJOR == 2) && (FLUIDSYNTH_VERSION_MINOR < 2)) +# define USE_OLD_FLUIDSYNTH_API +#endif extern void givealbuffer_midi(void *buf, uint32_t size); extern void al_set_midi(int freq, int buf_size); -static void *fluidsynth_handle; /* handle to FluidSynth DLL */ - -/* Pointers to the real functions. */ -// clang-format off -static void *(*f_new_fluid_settings)(void); -static void (*f_delete_fluid_settings)(void *settings); -static int (*f_fluid_settings_setnum)(void *settings, const char *name, double val); -static int (*f_fluid_settings_getnum)(void *settings, const char *name, double *val); -static void *(*f_new_fluid_synth)(void *settings); -static int (*f_delete_fluid_synth)(void *synth); -static int (*f_fluid_synth_noteon)(void *synth, int chan, int key, int vel); -static int (*f_fluid_synth_noteoff)(void *synth, int chan, int key); -static int (*f_fluid_synth_cc)(void *synth, int chan, int ctrl, int val); -static int (*f_fluid_synth_channel_pressure)(void *synth, int chan, int val); -static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun); -static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val); -static int (*f_fluid_synth_program_change)(void *synth, int chan, int program); -static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets); -static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method); -static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level); -static void (*f_fluid_synth_set_reverb_on)(void *synth, int on); -static void (*f_fluid_synth_set_chorus)(void *synth, int nr, double level, double speed, double depth_ms, int type); -static void (*f_fluid_synth_set_chorus_on)(void *synth, int on); -static int (*f_fluid_synth_write_s16)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static int (*f_fluid_synth_write_float)(void *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr); -static char *(*f_fluid_version_str)(void); -// clang-format on - -static dllimp_t fluidsynth_imports[] = { - // clang-format off - { "new_fluid_settings", &f_new_fluid_settings }, - { "delete_fluid_settings", &f_delete_fluid_settings }, - { "fluid_settings_setnum", &f_fluid_settings_setnum }, - { "fluid_settings_getnum", &f_fluid_settings_getnum }, - { "new_fluid_synth", &f_new_fluid_synth }, - { "delete_fluid_synth", &f_delete_fluid_synth }, - { "fluid_synth_noteon", &f_fluid_synth_noteon }, - { "fluid_synth_noteoff", &f_fluid_synth_noteoff }, - { "fluid_synth_cc", &f_fluid_synth_cc }, - { "fluid_synth_channel_pressure", &f_fluid_synth_channel_pressure }, - { "fluid_synth_sysex", &f_fluid_synth_sysex }, - { "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend }, - { "fluid_synth_program_change", &f_fluid_synth_program_change }, - { "fluid_synth_sfload", &f_fluid_synth_sfload }, - { "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method }, - { "fluid_synth_set_reverb", &f_fluid_synth_set_reverb }, - { "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on }, - { "fluid_synth_set_chorus", &f_fluid_synth_set_chorus }, - { "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on }, - { "fluid_synth_write_s16", &f_fluid_synth_write_s16 }, - { "fluid_synth_write_float", &f_fluid_synth_write_float }, - { "fluid_version_str", &f_fluid_version_str }, - { NULL, NULL }, - // clang-format on -}; - typedef struct fluidsynth { - void *settings; - void *synth; - int samplerate; - int sound_font; + fluid_settings_t *settings; + fluid_synth_t *synth; + int samplerate; + int sound_font; thread_t *thread_h; event_t *event, *start_event; @@ -153,7 +82,7 @@ fluidsynth_thread(void *param) float *buf = (float *) ((uint8_t *) data->buffer + buf_pos); memset(buf, 0, buf_size); if (data->synth) - f_fluid_synth_write_float(data->synth, buf_size / (2 * sizeof(float)), buf, 0, 2, buf, 1, 2); + fluid_synth_write_float(data->synth, buf_size / (2 * sizeof(float)), buf, 0, 2, buf, 1, 2); buf_pos += buf_size; if (buf_pos >= data->buf_size) { givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); @@ -163,7 +92,7 @@ fluidsynth_thread(void *param) int16_t *buf = (int16_t *) ((uint8_t *) data->buffer_int16 + buf_pos); memset(buf, 0, buf_size); if (data->synth) - f_fluid_synth_write_s16(data->synth, buf_size / (2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); + fluid_synth_write_s16(data->synth, buf_size / (2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2); buf_pos += buf_size; if (buf_pos >= data->buf_size) { givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); @@ -187,24 +116,24 @@ fluidsynth_msg(uint8_t *msg) switch (cmd) { case 0x80: /* Note Off */ - f_fluid_synth_noteoff(data->synth, chan, param1); + fluid_synth_noteoff(data->synth, chan, param1); break; case 0x90: /* Note On */ - f_fluid_synth_noteon(data->synth, chan, param1, param2); + fluid_synth_noteon(data->synth, chan, param1, param2); break; case 0xA0: /* Aftertouch */ break; case 0xB0: /* Control Change */ - f_fluid_synth_cc(data->synth, chan, param1, param2); + fluid_synth_cc(data->synth, chan, param1, param2); break; case 0xC0: /* Program Change */ - f_fluid_synth_program_change(data->synth, chan, param1); + fluid_synth_program_change(data->synth, chan, param1); break; case 0xD0: /* Channel Pressure */ - f_fluid_synth_channel_pressure(data->synth, chan, param1); + fluid_synth_channel_pressure(data->synth, chan, param1); break; case 0xE0: /* Pitch Bend */ - f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1); + fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1); break; case 0xF0: /* SysEx */ break; @@ -218,53 +147,38 @@ fluidsynth_sysex(uint8_t *data, unsigned int len) { fluidsynth_t *d = &fsdev; - f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); + fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); } void * -fluidsynth_init(const device_t *info) +fluidsynth_init(UNUSED(const device_t *info)) { fluidsynth_t *data = &fsdev; midi_device_t *dev; memset(data, 0, sizeof(fluidsynth_t)); - /* Try loading the DLL. */ -# ifdef _WIN32 -# if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports); -# else - fluidsynth_handle = dynld_module("libfluidsynth64.dll", fluidsynth_imports); -# endif -# elif defined __APPLE__ - fluidsynth_handle = dynld_module("libfluidsynth.dylib", fluidsynth_imports); -# else - fluidsynth_handle = dynld_module("libfluidsynth.so.3", fluidsynth_imports); - if (fluidsynth_handle == NULL) - fluidsynth_handle = dynld_module("libfluidsynth.so.2", fluidsynth_imports); -# endif - if (fluidsynth_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2134); - return NULL; - } + data->settings = new_fluid_settings(); - data->settings = f_new_fluid_settings(); + fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); + fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f); - f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); - f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f); + data->synth = new_fluid_synth(data->settings); - data->synth = f_new_fluid_synth(data->settings); - - const char *sound_font = (char *) device_get_config_string("sound_font"); -# ifdef __unix__ + const char *sound_font = device_get_config_string("sound_font"); +#ifdef __unix__ if (!sound_font || sound_font[0] == 0) sound_font = (access("/usr/share/sounds/sf2/FluidR3_GM.sf2", F_OK) == 0 ? "/usr/share/sounds/sf2/FluidR3_GM.sf2" : (access("/usr/share/soundfonts/default.sf2", F_OK) == 0 ? "/usr/share/soundfonts/default.sf2" : "")); -# endif - data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1); +#endif + data->sound_font = fluid_synth_sfload(data->synth, sound_font, 1); if (device_get_config_int("chorus")) { - f_fluid_synth_set_chorus_on(data->synth, 1); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_chorus_on(data->synth, -1, 1); +#else + fluid_synth_set_chorus_on(data->synth, 1); +#endif int chorus_voices = device_get_config_int("chorus_voices"); double chorus_level = device_get_config_int("chorus_level") / 100.0; @@ -277,21 +191,48 @@ fluidsynth_init(const device_t *info) else chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE; - f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_set_chorus_group_nr(data->synth, -1, chorus_voices); + fluid_synth_set_chorus_group_level(data->synth, -1, chorus_level); + fluid_synth_set_chorus_group_speed(data->synth, -1, chorus_speed); + fluid_synth_set_chorus_group_depth(data->synth, -1, chorus_depth); + fluid_synth_set_chorus_group_type(data->synth, -1, chorus_waveform); +#else + fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); +#endif } else - f_fluid_synth_set_chorus_on(data->synth, 0); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_chorus_on(data->synth, -1, 0); +#else + fluid_synth_set_chorus_on(data->synth, 0); +#endif if (device_get_config_int("reverb")) { - f_fluid_synth_set_reverb_on(data->synth, 1); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_reverb_on(data->synth, -1, 1); +#else + fluid_synth_set_reverb_on(data->synth, 1); +#endif double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0; double reverb_damping = device_get_config_int("reverb_damping") / 100.0; - int reverb_width = device_get_config_int("reverb_width"); + double reverb_width = device_get_config_int("reverb_width") / 10.0; double reverb_level = device_get_config_int("reverb_level") / 100.0; - f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_set_reverb_group_roomsize(data->synth, -1, reverb_room_size); + fluid_synth_set_reverb_group_damp(data->synth, -1, reverb_damping); + fluid_synth_set_reverb_group_width(data->synth, -1, reverb_width); + fluid_synth_set_reverb_group_level(data->synth, -1, reverb_level); +#else + fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); +#endif } else - f_fluid_synth_set_reverb_on(data->synth, 0); +#ifndef USE_OLD_FLUIDSYNTH_API + fluid_synth_reverb_on(data->synth, -1, 0); +#else + fluid_synth_set_reverb_on(data->synth, 0); +#endif int interpolation = device_get_config_int("interpolation"); int fs_interpolation = FLUID_INTERP_4THORDER; @@ -305,10 +246,10 @@ fluidsynth_init(const device_t *info) else if (interpolation == 3) fs_interpolation = FLUID_INTERP_7THORDER; - f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation); + fluid_synth_set_interp_method(data->synth, -1, fs_interpolation); double samplerate; - f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); + fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate); data->samplerate = (int) samplerate; if (sound_is_float) { data->buf_size = (data->samplerate / RENDER_RATE) * 2 * sizeof(float) * BUFFER_SEGMENTS; @@ -345,9 +286,9 @@ fluidsynth_init(const device_t *info) } void -fluidsynth_close(void *p) +fluidsynth_close(void *priv) { - if (!p) + if (!priv) return; fluidsynth_t *data = &fsdev; @@ -357,12 +298,12 @@ fluidsynth_close(void *p) thread_wait(data->thread_h); if (data->synth) { - f_delete_fluid_synth(data->synth); + delete_fluid_synth(data->synth); data->synth = NULL; } if (data->settings) { - f_delete_fluid_settings(data->settings); + delete_fluid_settings(data->settings); data->settings = NULL; } @@ -375,12 +316,6 @@ fluidsynth_close(void *p) free(data->buffer_int16); data->buffer_int16 = NULL; } - - /* Unload the DLL if possible. */ - if (fluidsynth_handle != NULL) { - dynld_close(fluidsynth_handle); - fluidsynth_handle = NULL; - } } static const device_config_t fluidsynth_config[] = { @@ -407,7 +342,7 @@ static const device_config_t fluidsynth_config[] = { .name = "chorus", .description = "Chorus", .type = CONFIG_BINARY, - .default_int = 0 + .default_int = 1 }, { .name = "chorus_voices", @@ -429,7 +364,7 @@ static const device_config_t fluidsynth_config[] = { .min = 0, .max = 100 }, - .default_int = 100 + .default_int = 20 }, { .name = "chorus_speed", @@ -437,7 +372,7 @@ static const device_config_t fluidsynth_config[] = { .type = CONFIG_SPINNER, .spinner = { - .min = 30, + .min = 10, .max = 500 }, .default_int = 30 @@ -449,7 +384,7 @@ static const device_config_t fluidsynth_config[] = { .spinner = { .min = 0, - .max = 210 + .max = 2560 }, .default_int = 80 }, @@ -474,7 +409,7 @@ static const device_config_t fluidsynth_config[] = { .name = "reverb", .description = "Reverb", .type = CONFIG_BINARY, - .default_int = 0 + .default_int = 1 }, { .name = "reverb_room_size", @@ -483,7 +418,7 @@ static const device_config_t fluidsynth_config[] = { .spinner = { .min = 0, - .max = 120 + .max = 100 }, .default_int = 20 }, @@ -505,9 +440,9 @@ static const device_config_t fluidsynth_config[] = { .spinner = { .min = 0, - .max = 100 + .max = 1000 }, - .default_int = 1 + .default_int = 5 }, { .name = "reverb_level", @@ -563,4 +498,3 @@ const device_t fluidsynth_device = { .config = fluidsynth_config }; -#endif /*USE_FLUIDSYNTH*/ diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 230914d72e..91d85e438a 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -110,7 +110,7 @@ static mt32emu_context context = NULL; static int roms_present[2] = { -1, -1 }; mt32emu_return_code -mt32_check(const char *func, mt32emu_return_code ret, mt32emu_return_code expected) +mt32_check(UNUSED(const char *func), mt32emu_return_code ret, mt32emu_return_code expected) { if (ret != expected) { return 0; @@ -165,13 +165,13 @@ static int16_t *buffer_int16 = NULL; static int midi_pos = 0; static mt32emu_report_handler_version -get_mt32_report_handler_version(mt32emu_report_handler_i i) +get_mt32_report_handler_version(UNUSED(mt32emu_report_handler_i i)) { return MT32EMU_REPORT_HANDLER_VERSION_0; } static void -display_mt32_message(void *instance_data, const char *message) +display_mt32_message(UNUSED(void *instance_data), const char *message) { int sz = 0; char *ui_msg = NULL; @@ -209,7 +209,7 @@ mt32_poll(void) } static void -mt32_thread(void *param) +mt32_thread(UNUSED(void *param)) { int buf_pos = 0; int bsize = buf_size / BUFFER_SEGMENTS; @@ -321,33 +321,33 @@ mt32emu_init(char *control_rom, char *pcm_rom) } void * -mt32_old_init(const device_t *info) +mt32_old_init(UNUSED(const device_t *info)) { return mt32emu_init(MT32_OLD_CTRL_ROM, MT32_OLD_PCM_ROM); } void * -mt32_new_init(const device_t *info) +mt32_new_init(UNUSED(const device_t *info)) { return mt32emu_init(MT32_NEW_CTRL_ROM, MT32_NEW_PCM_ROM); } void * -cm32l_init(const device_t *info) +cm32l_init(UNUSED(const device_t *info)) { return mt32emu_init(CM32L_CTRL_ROM, CM32L_PCM_ROM); } void * -cm32ln_init(const device_t *info) +cm32ln_init(UNUSED(const device_t *info)) { return mt32emu_init(CM32LN_CTRL_ROM, CM32LN_PCM_ROM); } void -mt32_close(void *p) +mt32_close(void *priv) { - if (!p) + if (!priv) return; mt32_on = 0; diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c new file mode 100644 index 0000000000..9708db1506 --- /dev/null +++ b/src/sound/midi_opl4.c @@ -0,0 +1,731 @@ +// Based off ROBOPLAY's OPL4 MID player code, with some fixes and modifications to make it work well. + +#include +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/midi.h> +#include <86box/plat.h> +#include <86box/thread.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/ui.h> +#include <86box/snd_opl.h> +#include <86box/opl4_defines.h> + +#include "yrw801.h" + +#define NR_OF_MIDI_CHANNELS 16 +#define NR_OF_WAVE_CHANNELS 24 + +#define DRUM_CHANNEL 9 + +typedef struct +{ + uint8_t instrument; + uint8_t panpot; + uint8_t vibrato; + bool drum_channel; +} MIDI_CHANNEL_DATA; + +typedef struct +{ + bool is_active; + uint64_t activated; + + uint8_t number; + MIDI_CHANNEL_DATA *midi_channel; + uint8_t note; + uint8_t velocity; + const YRW801_WAVE_DATA *wave_data; + uint8_t level_direct; + uint8_t reg_f_number; + uint8_t reg_misc; + uint8_t reg_lfo_vibrato; +} VOICE_DATA; + +static const int16_t g_wave_pitch_map[0x600] = { + 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003, + 0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x006, 0x007, + 0x007, 0x008, 0x008, 0x009, 0x009, 0x00a, 0x00a, 0x00b, + 0x00b, 0x00c, 0x00c, 0x00d, 0x00d, 0x00d, 0x00e, 0x00e, + 0x00f, 0x00f, 0x010, 0x010, 0x011, 0x011, 0x012, 0x012, + 0x013, 0x013, 0x014, 0x014, 0x015, 0x015, 0x015, 0x016, + 0x016, 0x017, 0x017, 0x018, 0x018, 0x019, 0x019, 0x01a, + 0x01a, 0x01b, 0x01b, 0x01c, 0x01c, 0x01d, 0x01d, 0x01e, + 0x01e, 0x01e, 0x01f, 0x01f, 0x020, 0x020, 0x021, 0x021, + 0x022, 0x022, 0x023, 0x023, 0x024, 0x024, 0x025, 0x025, + 0x026, 0x026, 0x027, 0x027, 0x028, 0x028, 0x029, 0x029, + 0x029, 0x02a, 0x02a, 0x02b, 0x02b, 0x02c, 0x02c, 0x02d, + 0x02d, 0x02e, 0x02e, 0x02f, 0x02f, 0x030, 0x030, 0x031, + 0x031, 0x032, 0x032, 0x033, 0x033, 0x034, 0x034, 0x035, + 0x035, 0x036, 0x036, 0x037, 0x037, 0x038, 0x038, 0x038, + 0x039, 0x039, 0x03a, 0x03a, 0x03b, 0x03b, 0x03c, 0x03c, + 0x03d, 0x03d, 0x03e, 0x03e, 0x03f, 0x03f, 0x040, 0x040, + 0x041, 0x041, 0x042, 0x042, 0x043, 0x043, 0x044, 0x044, + 0x045, 0x045, 0x046, 0x046, 0x047, 0x047, 0x048, 0x048, + 0x049, 0x049, 0x04a, 0x04a, 0x04b, 0x04b, 0x04c, 0x04c, + 0x04d, 0x04d, 0x04e, 0x04e, 0x04f, 0x04f, 0x050, 0x050, + 0x051, 0x051, 0x052, 0x052, 0x053, 0x053, 0x054, 0x054, + 0x055, 0x055, 0x056, 0x056, 0x057, 0x057, 0x058, 0x058, + 0x059, 0x059, 0x05a, 0x05a, 0x05b, 0x05b, 0x05c, 0x05c, + 0x05d, 0x05d, 0x05e, 0x05e, 0x05f, 0x05f, 0x060, 0x060, + 0x061, 0x061, 0x062, 0x062, 0x063, 0x063, 0x064, 0x064, + 0x065, 0x065, 0x066, 0x066, 0x067, 0x067, 0x068, 0x068, + 0x069, 0x069, 0x06a, 0x06a, 0x06b, 0x06b, 0x06c, 0x06c, + 0x06d, 0x06d, 0x06e, 0x06e, 0x06f, 0x06f, 0x070, 0x071, + 0x071, 0x072, 0x072, 0x073, 0x073, 0x074, 0x074, 0x075, + 0x075, 0x076, 0x076, 0x077, 0x077, 0x078, 0x078, 0x079, + 0x079, 0x07a, 0x07a, 0x07b, 0x07b, 0x07c, 0x07c, 0x07d, + 0x07d, 0x07e, 0x07e, 0x07f, 0x07f, 0x080, 0x081, 0x081, + 0x082, 0x082, 0x083, 0x083, 0x084, 0x084, 0x085, 0x085, + 0x086, 0x086, 0x087, 0x087, 0x088, 0x088, 0x089, 0x089, + 0x08a, 0x08a, 0x08b, 0x08b, 0x08c, 0x08d, 0x08d, 0x08e, + 0x08e, 0x08f, 0x08f, 0x090, 0x090, 0x091, 0x091, 0x092, + 0x092, 0x093, 0x093, 0x094, 0x094, 0x095, 0x096, 0x096, + 0x097, 0x097, 0x098, 0x098, 0x099, 0x099, 0x09a, 0x09a, + 0x09b, 0x09b, 0x09c, 0x09c, 0x09d, 0x09d, 0x09e, 0x09f, + 0x09f, 0x0a0, 0x0a0, 0x0a1, 0x0a1, 0x0a2, 0x0a2, 0x0a3, + 0x0a3, 0x0a4, 0x0a4, 0x0a5, 0x0a6, 0x0a6, 0x0a7, 0x0a7, + 0x0a8, 0x0a8, 0x0a9, 0x0a9, 0x0aa, 0x0aa, 0x0ab, 0x0ab, + 0x0ac, 0x0ad, 0x0ad, 0x0ae, 0x0ae, 0x0af, 0x0af, 0x0b0, + 0x0b0, 0x0b1, 0x0b1, 0x0b2, 0x0b2, 0x0b3, 0x0b4, 0x0b4, + 0x0b5, 0x0b5, 0x0b6, 0x0b6, 0x0b7, 0x0b7, 0x0b8, 0x0b8, + 0x0b9, 0x0ba, 0x0ba, 0x0bb, 0x0bb, 0x0bc, 0x0bc, 0x0bd, + 0x0bd, 0x0be, 0x0be, 0x0bf, 0x0c0, 0x0c0, 0x0c1, 0x0c1, + 0x0c2, 0x0c2, 0x0c3, 0x0c3, 0x0c4, 0x0c4, 0x0c5, 0x0c6, + 0x0c6, 0x0c7, 0x0c7, 0x0c8, 0x0c8, 0x0c9, 0x0c9, 0x0ca, + 0x0cb, 0x0cb, 0x0cc, 0x0cc, 0x0cd, 0x0cd, 0x0ce, 0x0ce, + 0x0cf, 0x0d0, 0x0d0, 0x0d1, 0x0d1, 0x0d2, 0x0d2, 0x0d3, + 0x0d3, 0x0d4, 0x0d5, 0x0d5, 0x0d6, 0x0d6, 0x0d7, 0x0d7, + 0x0d8, 0x0d8, 0x0d9, 0x0da, 0x0da, 0x0db, 0x0db, 0x0dc, + 0x0dc, 0x0dd, 0x0de, 0x0de, 0x0df, 0x0df, 0x0e0, 0x0e0, + 0x0e1, 0x0e1, 0x0e2, 0x0e3, 0x0e3, 0x0e4, 0x0e4, 0x0e5, + 0x0e5, 0x0e6, 0x0e7, 0x0e7, 0x0e8, 0x0e8, 0x0e9, 0x0e9, + 0x0ea, 0x0eb, 0x0eb, 0x0ec, 0x0ec, 0x0ed, 0x0ed, 0x0ee, + 0x0ef, 0x0ef, 0x0f0, 0x0f0, 0x0f1, 0x0f1, 0x0f2, 0x0f3, + 0x0f3, 0x0f4, 0x0f4, 0x0f5, 0x0f5, 0x0f6, 0x0f7, 0x0f7, + 0x0f8, 0x0f8, 0x0f9, 0x0f9, 0x0fa, 0x0fb, 0x0fb, 0x0fc, + 0x0fc, 0x0fd, 0x0fd, 0x0fe, 0x0ff, 0x0ff, 0x100, 0x100, + 0x101, 0x101, 0x102, 0x103, 0x103, 0x104, 0x104, 0x105, + 0x106, 0x106, 0x107, 0x107, 0x108, 0x108, 0x109, 0x10a, + 0x10a, 0x10b, 0x10b, 0x10c, 0x10c, 0x10d, 0x10e, 0x10e, + 0x10f, 0x10f, 0x110, 0x111, 0x111, 0x112, 0x112, 0x113, + 0x114, 0x114, 0x115, 0x115, 0x116, 0x116, 0x117, 0x118, + 0x118, 0x119, 0x119, 0x11a, 0x11b, 0x11b, 0x11c, 0x11c, + 0x11d, 0x11e, 0x11e, 0x11f, 0x11f, 0x120, 0x120, 0x121, + 0x122, 0x122, 0x123, 0x123, 0x124, 0x125, 0x125, 0x126, + 0x126, 0x127, 0x128, 0x128, 0x129, 0x129, 0x12a, 0x12b, + 0x12b, 0x12c, 0x12c, 0x12d, 0x12e, 0x12e, 0x12f, 0x12f, + 0x130, 0x131, 0x131, 0x132, 0x132, 0x133, 0x134, 0x134, + 0x135, 0x135, 0x136, 0x137, 0x137, 0x138, 0x138, 0x139, + 0x13a, 0x13a, 0x13b, 0x13b, 0x13c, 0x13d, 0x13d, 0x13e, + 0x13e, 0x13f, 0x140, 0x140, 0x141, 0x141, 0x142, 0x143, + 0x143, 0x144, 0x144, 0x145, 0x146, 0x146, 0x147, 0x148, + 0x148, 0x149, 0x149, 0x14a, 0x14b, 0x14b, 0x14c, 0x14c, + 0x14d, 0x14e, 0x14e, 0x14f, 0x14f, 0x150, 0x151, 0x151, + 0x152, 0x153, 0x153, 0x154, 0x154, 0x155, 0x156, 0x156, + 0x157, 0x157, 0x158, 0x159, 0x159, 0x15a, 0x15b, 0x15b, + 0x15c, 0x15c, 0x15d, 0x15e, 0x15e, 0x15f, 0x160, 0x160, + 0x161, 0x161, 0x162, 0x163, 0x163, 0x164, 0x165, 0x165, + 0x166, 0x166, 0x167, 0x168, 0x168, 0x169, 0x16a, 0x16a, + 0x16b, 0x16b, 0x16c, 0x16d, 0x16d, 0x16e, 0x16f, 0x16f, + 0x170, 0x170, 0x171, 0x172, 0x172, 0x173, 0x174, 0x174, + 0x175, 0x175, 0x176, 0x177, 0x177, 0x178, 0x179, 0x179, + 0x17a, 0x17a, 0x17b, 0x17c, 0x17c, 0x17d, 0x17e, 0x17e, + 0x17f, 0x180, 0x180, 0x181, 0x181, 0x182, 0x183, 0x183, + 0x184, 0x185, 0x185, 0x186, 0x187, 0x187, 0x188, 0x188, + 0x189, 0x18a, 0x18a, 0x18b, 0x18c, 0x18c, 0x18d, 0x18e, + 0x18e, 0x18f, 0x190, 0x190, 0x191, 0x191, 0x192, 0x193, + 0x193, 0x194, 0x195, 0x195, 0x196, 0x197, 0x197, 0x198, + 0x199, 0x199, 0x19a, 0x19a, 0x19b, 0x19c, 0x19c, 0x19d, + 0x19e, 0x19e, 0x19f, 0x1a0, 0x1a0, 0x1a1, 0x1a2, 0x1a2, + 0x1a3, 0x1a4, 0x1a4, 0x1a5, 0x1a6, 0x1a6, 0x1a7, 0x1a8, + 0x1a8, 0x1a9, 0x1a9, 0x1aa, 0x1ab, 0x1ab, 0x1ac, 0x1ad, + 0x1ad, 0x1ae, 0x1af, 0x1af, 0x1b0, 0x1b1, 0x1b1, 0x1b2, + 0x1b3, 0x1b3, 0x1b4, 0x1b5, 0x1b5, 0x1b6, 0x1b7, 0x1b7, + 0x1b8, 0x1b9, 0x1b9, 0x1ba, 0x1bb, 0x1bb, 0x1bc, 0x1bd, + 0x1bd, 0x1be, 0x1bf, 0x1bf, 0x1c0, 0x1c1, 0x1c1, 0x1c2, + 0x1c3, 0x1c3, 0x1c4, 0x1c5, 0x1c5, 0x1c6, 0x1c7, 0x1c7, + 0x1c8, 0x1c9, 0x1c9, 0x1ca, 0x1cb, 0x1cb, 0x1cc, 0x1cd, + 0x1cd, 0x1ce, 0x1cf, 0x1cf, 0x1d0, 0x1d1, 0x1d1, 0x1d2, + 0x1d3, 0x1d3, 0x1d4, 0x1d5, 0x1d5, 0x1d6, 0x1d7, 0x1d7, + 0x1d8, 0x1d9, 0x1d9, 0x1da, 0x1db, 0x1db, 0x1dc, 0x1dd, + 0x1dd, 0x1de, 0x1df, 0x1df, 0x1e0, 0x1e1, 0x1e1, 0x1e2, + 0x1e3, 0x1e4, 0x1e4, 0x1e5, 0x1e6, 0x1e6, 0x1e7, 0x1e8, + 0x1e8, 0x1e9, 0x1ea, 0x1ea, 0x1eb, 0x1ec, 0x1ec, 0x1ed, + 0x1ee, 0x1ee, 0x1ef, 0x1f0, 0x1f0, 0x1f1, 0x1f2, 0x1f3, + 0x1f3, 0x1f4, 0x1f5, 0x1f5, 0x1f6, 0x1f7, 0x1f7, 0x1f8, + 0x1f9, 0x1f9, 0x1fa, 0x1fb, 0x1fb, 0x1fc, 0x1fd, 0x1fe, + 0x1fe, 0x1ff, 0x200, 0x200, 0x201, 0x202, 0x202, 0x203, + 0x204, 0x205, 0x205, 0x206, 0x207, 0x207, 0x208, 0x209, + 0x209, 0x20a, 0x20b, 0x20b, 0x20c, 0x20d, 0x20e, 0x20e, + 0x20f, 0x210, 0x210, 0x211, 0x212, 0x212, 0x213, 0x214, + 0x215, 0x215, 0x216, 0x217, 0x217, 0x218, 0x219, 0x21a, + 0x21a, 0x21b, 0x21c, 0x21c, 0x21d, 0x21e, 0x21e, 0x21f, + 0x220, 0x221, 0x221, 0x222, 0x223, 0x223, 0x224, 0x225, + 0x226, 0x226, 0x227, 0x228, 0x228, 0x229, 0x22a, 0x22b, + 0x22b, 0x22c, 0x22d, 0x22d, 0x22e, 0x22f, 0x230, 0x230, + 0x231, 0x232, 0x232, 0x233, 0x234, 0x235, 0x235, 0x236, + 0x237, 0x237, 0x238, 0x239, 0x23a, 0x23a, 0x23b, 0x23c, + 0x23c, 0x23d, 0x23e, 0x23f, 0x23f, 0x240, 0x241, 0x241, + 0x242, 0x243, 0x244, 0x244, 0x245, 0x246, 0x247, 0x247, + 0x248, 0x249, 0x249, 0x24a, 0x24b, 0x24c, 0x24c, 0x24d, + 0x24e, 0x24f, 0x24f, 0x250, 0x251, 0x251, 0x252, 0x253, + 0x254, 0x254, 0x255, 0x256, 0x257, 0x257, 0x258, 0x259, + 0x259, 0x25a, 0x25b, 0x25c, 0x25c, 0x25d, 0x25e, 0x25f, + 0x25f, 0x260, 0x261, 0x262, 0x262, 0x263, 0x264, 0x265, + 0x265, 0x266, 0x267, 0x267, 0x268, 0x269, 0x26a, 0x26a, + 0x26b, 0x26c, 0x26d, 0x26d, 0x26e, 0x26f, 0x270, 0x270, + 0x271, 0x272, 0x273, 0x273, 0x274, 0x275, 0x276, 0x276, + 0x277, 0x278, 0x279, 0x279, 0x27a, 0x27b, 0x27c, 0x27c, + 0x27d, 0x27e, 0x27f, 0x27f, 0x280, 0x281, 0x282, 0x282, + 0x283, 0x284, 0x285, 0x285, 0x286, 0x287, 0x288, 0x288, + 0x289, 0x28a, 0x28b, 0x28b, 0x28c, 0x28d, 0x28e, 0x28e, + 0x28f, 0x290, 0x291, 0x291, 0x292, 0x293, 0x294, 0x294, + 0x295, 0x296, 0x297, 0x298, 0x298, 0x299, 0x29a, 0x29b, + 0x29b, 0x29c, 0x29d, 0x29e, 0x29e, 0x29f, 0x2a0, 0x2a1, + 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a5, 0x2a6, 0x2a7, + 0x2a8, 0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ab, 0x2ac, 0x2ad, + 0x2ae, 0x2af, 0x2af, 0x2b0, 0x2b1, 0x2b2, 0x2b2, 0x2b3, + 0x2b4, 0x2b5, 0x2b5, 0x2b6, 0x2b7, 0x2b8, 0x2b9, 0x2b9, + 0x2ba, 0x2bb, 0x2bc, 0x2bc, 0x2bd, 0x2be, 0x2bf, 0x2c0, + 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c4, 0x2c5, 0x2c6, + 0x2c7, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cb, 0x2cc, + 0x2cd, 0x2ce, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d2, + 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d6, 0x2d7, 0x2d8, 0x2d9, + 0x2da, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2dd, 0x2de, 0x2df, + 0x2e0, 0x2e1, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e5, + 0x2e6, 0x2e7, 0x2e8, 0x2e9, 0x2e9, 0x2ea, 0x2eb, 0x2ec, + 0x2ed, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f1, 0x2f2, + 0x2f3, 0x2f4, 0x2f5, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x2f9, + 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fd, 0x2fe, 0x2ff, + 0x300, 0x301, 0x302, 0x302, 0x303, 0x304, 0x305, 0x306, + 0x306, 0x307, 0x308, 0x309, 0x30a, 0x30a, 0x30b, 0x30c, + 0x30d, 0x30e, 0x30f, 0x30f, 0x310, 0x311, 0x312, 0x313, + 0x313, 0x314, 0x315, 0x316, 0x317, 0x318, 0x318, 0x319, + 0x31a, 0x31b, 0x31c, 0x31c, 0x31d, 0x31e, 0x31f, 0x320, + 0x321, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x326, + 0x327, 0x328, 0x329, 0x32a, 0x32a, 0x32b, 0x32c, 0x32d, + 0x32e, 0x32f, 0x32f, 0x330, 0x331, 0x332, 0x333, 0x334, + 0x334, 0x335, 0x336, 0x337, 0x338, 0x339, 0x339, 0x33a, + 0x33b, 0x33c, 0x33d, 0x33e, 0x33e, 0x33f, 0x340, 0x341, + 0x342, 0x343, 0x343, 0x344, 0x345, 0x346, 0x347, 0x348, + 0x349, 0x349, 0x34a, 0x34b, 0x34c, 0x34d, 0x34e, 0x34e, + 0x34f, 0x350, 0x351, 0x352, 0x353, 0x353, 0x354, 0x355, + 0x356, 0x357, 0x358, 0x359, 0x359, 0x35a, 0x35b, 0x35c, + 0x35d, 0x35e, 0x35f, 0x35f, 0x360, 0x361, 0x362, 0x363, + 0x364, 0x364, 0x365, 0x366, 0x367, 0x368, 0x369, 0x36a, + 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f, 0x370, 0x370, + 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, 0x377, + 0x378, 0x379, 0x37a, 0x37b, 0x37c, 0x37d, 0x37d, 0x37e, + 0x37f, 0x380, 0x381, 0x382, 0x383, 0x383, 0x384, 0x385, + 0x386, 0x387, 0x388, 0x389, 0x38a, 0x38a, 0x38b, 0x38c, + 0x38d, 0x38e, 0x38f, 0x390, 0x391, 0x391, 0x392, 0x393, + 0x394, 0x395, 0x396, 0x397, 0x398, 0x398, 0x399, 0x39a, + 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, 0x39f, 0x3a0, 0x3a1, + 0x3a2, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a7, 0x3a8, + 0x3a9, 0x3aa, 0x3ab, 0x3ac, 0x3ad, 0x3ae, 0x3ae, 0x3af, + 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b6, + 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, + 0x3bf, 0x3bf, 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, + 0x3c6, 0x3c7, 0x3c7, 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, + 0x3cd, 0x3ce, 0x3cf, 0x3d0, 0x3d1, 0x3d1, 0x3d2, 0x3d3, + 0x3d4, 0x3d5, 0x3d6, 0x3d7, 0x3d8, 0x3d9, 0x3da, 0x3da, + 0x3db, 0x3dc, 0x3dd, 0x3de, 0x3df, 0x3e0, 0x3e1, 0x3e2, + 0x3e3, 0x3e4, 0x3e4, 0x3e5, 0x3e6, 0x3e7, 0x3e8, 0x3e9, + 0x3ea, 0x3eb, 0x3ec, 0x3ed, 0x3ee, 0x3ef, 0x3ef, 0x3f0, + 0x3f1, 0x3f2, 0x3f3, 0x3f4, 0x3f5, 0x3f6, 0x3f7, 0x3f8, + 0x3f9, 0x3fa, 0x3fa, 0x3fb, 0x3fc, 0x3fd, 0x3fe, 0x3ff +}; + +/* + * Attenuation according to GM recommendations, in -0.375 dB units. + * table[v] = 40 * log(v / 127) / -0.375 + */ +static const uint8_t g_volume_table[128] = { + 255, 224, 192, 173, 160, 150, 141, 134, + 128, 122, 117, 113, 109, 105, 102, 99, + 96, 93, 90, 88, 85, 83, 81, 79, + 77, 75, 73, 71, 70, 68, 67, 65, + 64, 62, 61, 59, 58, 57, 56, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 39, + 38, 37, 36, 35, 34, 34, 33, 32, + 31, 31, 30, 29, 29, 28, 27, 27, + 26, 25, 25, 24, 24, 23, 22, 22, + 21, 21, 20, 19, 19, 18, 18, 17, + 17, 16, 16, 15, 15, 14, 14, 13, + 13, 12, 12, 11, 11, 10, 10, 9, + 9, 9, 8, 8, 7, 7, 6, 6, + 6, 5, 5, 4, 4, 4, 3, 3, + 2, 2, 2, 1, 1, 0, 0, 0 +}; + +#define BUFFER_SEGMENTS 10 +#define RENDER_RATE (48000 / 100) + +typedef struct opl4_midi { + fm_drv_t opl4; + MIDI_CHANNEL_DATA midi_channel_data[16]; + VOICE_DATA voice_data[24]; + int16_t buffer[(48000 / 100) * 2 * BUFFER_SEGMENTS]; + float buffer_float[(48000 / 100) * 2 * BUFFER_SEGMENTS]; + uint32_t midi_pos; + bool on; + atomic_bool gen_in_progress; + thread_t *thread; + event_t *wait_event; +} opl4_midi_t; + +static opl4_midi_t *opl4_midi_cur; + +static void +opl4_write_wave_register(const uint8_t reg, const uint8_t value, opl4_midi_t *opl4_midi) +{ + opl4_midi->opl4.write(0x380, reg, opl4_midi->opl4.priv); + opl4_midi->opl4.write(0x381, value, opl4_midi->opl4.priv); +} + +VOICE_DATA * +get_voice(const YRW801_WAVE_DATA *wave_data, opl4_midi_t *opl4_midi) +{ + VOICE_DATA *free_voice = &opl4_midi->voice_data[0]; + VOICE_DATA *oldest_voice = &opl4_midi->voice_data[0]; + for (uint8_t voice = 0; voice < 24; voice++) { + if (opl4_midi_cur->voice_data[voice].is_active) { + if (opl4_midi_cur->voice_data[voice].activated < oldest_voice->activated) + oldest_voice = &opl4_midi_cur->voice_data[voice]; + } else { + if (opl4_midi_cur->voice_data[voice].wave_data == wave_data) { + free_voice = &opl4_midi_cur->voice_data[voice]; + break; + } + + if (opl4_midi_cur->voice_data[voice].activated < free_voice->activated) { + free_voice = &opl4_midi_cur->voice_data[voice]; + break; + } + } + } + + /* If no free voice is found, look for one with the same instrument */ + if (free_voice->is_active) { + for (uint8_t voice = 0; voice < 24; voice++) { + if (opl4_midi_cur->voice_data[voice].is_active + && opl4_midi_cur->voice_data[voice].wave_data == wave_data) { + free_voice = &opl4_midi_cur->voice_data[voice]; + free_voice->is_active = 0; + free_voice->activated = 0; + + free_voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc, opl4_midi); + return free_voice; + } + } + } + + /* If still no free voice found, deactivate the 'oldest' */ + if (free_voice->is_active) { + free_voice = oldest_voice; + free_voice->is_active = 0; + free_voice->activated = 0; + + free_voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc, opl4_midi); + } + + return free_voice; +} + +static void +update_pan(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int8_t pan = voice->wave_data->panpot; + + if (!voice->midi_channel->drum_channel) + pan += voice->midi_channel->panpot; + if (pan < -7) + pan = -7; + else if (pan > 7) + pan = 7; + + voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK) | (pan & OPL4_PAN_POT_MASK); + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); +} + +void +update_pitch(VOICE_DATA *voice, uint16_t pitch_bend, opl4_midi_t *opl4_midi) +{ + int32_t pitch = voice->midi_channel->drum_channel ? 0 : (voice->note - 60) * 128; + pitch = pitch * (int) voice->wave_data->key_scaling / 100; + pitch = pitch + 7680; + pitch += voice->wave_data->pitch_offset; + pitch += pitch_bend * 256 / 0x2000; + if (pitch < 0) + pitch = 0; + else if (pitch > 0x5FFF) + pitch = 0x5FFF; + + int8_t octave = pitch / 0x600 - 8; + uint16_t fnumber = g_wave_pitch_map[pitch % 0x600]; + + opl4_write_wave_register(OPL4_REG_OCTAVE + voice->number, (octave << 4) | ((fnumber >> 7) & 0x07), opl4_midi); + voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8) | ((fnumber << 1) & OPL4_F_NUMBER_LOW_MASK); + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number, opl4_midi); +} + +void +update_volume(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int16_t att = voice->wave_data->tone_attenuate; + + att += g_volume_table[voice->velocity]; + att = 0x7F - (0x7F - att) * (voice->wave_data->volume_factor) / 0xFE; + att -= 16; + if (att < 0) + att = 0; + else if (att > 0x7E) + att = 0x7E; + + opl4_write_wave_register(OPL4_REG_LEVEL + voice->number, (att << 1) | voice->level_direct, opl4_midi); + voice->level_direct = 0; +} + +void +note_off(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + /* Velocity not used */ + (void) velocity; + + while (opl4_midi->gen_in_progress) { } + for (uint8_t i = 0; i < 24; i++) { + VOICE_DATA *voice = &opl4_midi->voice_data[i]; + if (voice->is_active && voice->midi_channel == midi_channel && voice->note == note) { + voice->is_active = false; + voice->activated = 0; + + voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); + } + } +} + +void +update_vibrato_depth(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + uint16_t depth; + + depth = (7 - voice->wave_data->vibrato) * (voice->midi_channel->vibrato & 0x7F); + depth = (depth >> 7) + voice->wave_data->vibrato; + voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK; + voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK; + opl4_write_wave_register(OPL4_REG_LFO_VIBRATO + voice->number, voice->reg_lfo_vibrato, opl4_midi); +} + +void +note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + const YRW801_REGION_DATA_PTR *region_ptr = &snd_yrw801_regions[0]; + const YRW801_WAVE_DATA *wave_data[2]; + VOICE_DATA *voice[2]; + uint8_t i = 0, voices = 0; + + while (opl4_midi->gen_in_progress) { } + + if (midi_channel->drum_channel) + wave_data[voices++] = ®ion_ptr[0x80].regions[note - 0x1A].wave_data; + else { + /* Determine the number of voices and voice parameters */ + const YRW801_REGION_DATA *region = region_ptr[midi_channel->instrument & 0x7F].regions; + + while (i < region_ptr[midi_channel->instrument & 0x7F].count) { + if (note >= region[i].key_min && note <= region[i].key_max) { + wave_data[voices] = ®ion[i].wave_data; + if (++voices >= 2) + break; + } + i++; + } + } + + /* Allocate and initialize needed voices */ + for (i = 0; i < voices; i++) { + voice[i] = get_voice(wave_data[i], opl4_midi); + voice[i]->is_active = true; + voice[i]->activated = plat_get_ticks(); + + voice[i]->midi_channel = midi_channel; + voice[i]->note = note; + voice[i]->velocity = velocity & 0x7F; + } + + for (i = 0; i < voices; i++) { + voice[i]->reg_f_number = (wave_data[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8; + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice[i]->number, voice[i]->reg_f_number, opl4_midi); + + bool new_wave = (voice[i]->wave_data != wave_data[i]); + /* Set tone number (triggers header loading) */ + if (new_wave) { + opl4_write_wave_register(OPL4_REG_TONE_NUMBER + voice[i]->number, wave_data[i]->tone & 0xFF, opl4_midi); + voice[i]->wave_data = wave_data[i]; + } + + voice[i]->reg_misc = OPL4_LFO_RESET_BIT; + update_pan(voice[i], opl4_midi); + update_pitch(voice[i], 0, opl4_midi); + voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT; + update_volume(voice[i], opl4_midi); + if (new_wave) { + /* Set remaining parameters */ + opl4_write_wave_register(OPL4_REG_ATTACK_DECAY1 + voice[i]->number, voice[i]->wave_data->reg_attack_decay1, opl4_midi); + opl4_write_wave_register(OPL4_REG_LEVEL_DECAY2 + voice[i]->number, voice[i]->wave_data->reg_level_decay2, opl4_midi); + opl4_write_wave_register(OPL4_REG_RELEASE_CORRECTION + voice[i]->number, voice[i]->wave_data->reg_release_correction, opl4_midi); + opl4_write_wave_register(OPL4_REG_TREMOLO + voice[i]->number, voice[i]->wave_data->reg_tremolo, opl4_midi); + + voice[i]->reg_lfo_vibrato = voice[i]->wave_data->reg_lfo_vibrato; + + if (!midi_channel->drum_channel) + update_vibrato_depth(voice[i], opl4_midi); + } + } + + /* Finally, switch on all voices */ + for (i = 0; i < voices; i++) { + voice[i]->reg_misc = (voice[i]->reg_misc & 0x1F) | OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice[i]->number, voice[i]->reg_misc, opl4_midi); + } +} + +void +control_change(uint8_t midi_channel, uint8_t id, uint8_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + switch (id) { + case 10: + /* Change stereo panning */ + if (midi_channel != DRUM_CHANNEL) { + opl4_midi->midi_channel_data[midi_channel].panpot = (value - 0x40) >> 3; + for (i = 0; i < NR_OF_WAVE_CHANNELS; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pan(&opl4_midi->voice_data[i], opl4_midi); + } + } + } + break; + } +} + +void +pitch_wheel(uint8_t midi_channel, uint16_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + + for (i = 0; i < 24; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pitch(&opl4_midi->voice_data[i], value, opl4_midi); + } + } +} + +void +channel_pressure(uint8_t midi_channel, uint8_t pressure) +{ + (void) midi_channel; + (void) pressure; +} + +void +key_pressure(uint8_t midi_channel, uint8_t note, uint8_t pressure) +{ + (void) midi_channel; + (void) note; + (void) pressure; +} + +void +program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) +{ + opl4_midi->midi_channel_data[midi_channel].instrument = program; +} + +static void +opl4_midi_thread(void *arg) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + uint32_t i = 0; + uint32_t buf_size = RENDER_RATE * 2; + uint32_t buf_size_segments = buf_size * BUFFER_SEGMENTS; + uint32_t buf_pos = 0; + + int32_t buffer[RENDER_RATE * 2]; + + extern void givealbuffer_midi(void *buf, uint32_t size); + while (opl4_midi->on) { + thread_wait_event(opl4_midi->wait_event, -1); + thread_reset_event(opl4_midi->wait_event); + if (!opl4_midi->on) + break; + atomic_store(&opl4_midi->gen_in_progress, true); + opl4_midi->opl4.generate(opl4_midi->opl4.priv, buffer, RENDER_RATE); + atomic_store(&opl4_midi->gen_in_progress, false); + if (sound_is_float) { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer_float[(i + buf_pos) * 2] = buffer[i * 2] / 32768.0; + opl4_midi->buffer_float[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer_float, buf_size_segments); + buf_pos = 0; + } + } else { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer[(i + buf_pos) * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer, buf_size_segments); + buf_pos = 0; + } + } + } +} + +static void +opl4_midi_poll(void) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + opl4_midi->midi_pos++; + if (opl4_midi->midi_pos == RENDER_RATE) { + opl4_midi->midi_pos = 0; + thread_set_event(opl4_midi->wait_event); + } +} + +void +opl4_midi_msg(uint8_t *val) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + + uint32_t msg = *(uint32_t *) (val); + uint8_t data_byte_1 = msg & 0xFF; + uint8_t data_byte_2 = (msg >> 8) & 0xFF; + uint8_t data_byte_3 = (msg >> 16) & 0xFF; + + uint8_t midi_channel = data_byte_1 & 0x0F; + uint8_t midi_command = data_byte_1 >> 4; + + switch (midi_command) { + case 0x8: // Note OFF + note_off(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0x9: // Note ON + note_on(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0xA: // Key after-touch + break; + case 0xB: // Control change + control_change(midi_channel, data_byte_2, data_byte_3, opl4_midi); + break; + case 0xC: // Program change + program_change(midi_channel, data_byte_2 & 0x7F, opl4_midi); + break; + case 0xD: // Channel after-touch + break; + case 0xE: // Pitch wheel + pitch_wheel(midi_channel, ((data_byte_3 <<= 7) | data_byte_2), opl4_midi); + break; + } +} + +void +opl4_midi_sysex(uint8_t *data, unsigned int len) +{ +} + +void * +opl4_init(const device_t *info) +{ + midi_device_t *dev; + extern void al_set_midi(int freq, int buf_size); + + dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = opl4_midi_msg; + dev->play_sysex = opl4_midi_sysex; + dev->poll = opl4_midi_poll; + + al_set_midi(48000, 4800); + + opl4_midi_cur = calloc(1, sizeof(opl4_midi_t)); + + fm_driver_get(FM_YMF278B, &opl4_midi_cur->opl4); + + opl4_midi_cur->opl4.write(0x38A, 0x05, opl4_midi_cur->opl4.priv); + opl4_midi_cur->opl4.write(0x389, 0x3, opl4_midi_cur->opl4.priv); + midi_out_init(dev); + + opl4_midi_cur->on = true; + opl4_midi_cur->midi_channel_data[9].drum_channel = true; + atomic_init(&opl4_midi_cur->gen_in_progress, 0); + + for (uint8_t voice = 0; voice < NR_OF_WAVE_CHANNELS; voice++) { + opl4_midi_cur->voice_data[voice].number = voice; + opl4_midi_cur->voice_data[voice].is_active = false; + opl4_midi_cur->voice_data[voice].activated = 0; + opl4_midi_cur->voice_data[voice].midi_channel = NULL; + opl4_midi_cur->voice_data[voice].note = 0; + opl4_midi_cur->voice_data[voice].velocity = 0; + opl4_midi_cur->voice_data[voice].wave_data = NULL; + opl4_midi_cur->voice_data[voice].level_direct = 0; + opl4_midi_cur->voice_data[voice].reg_f_number = 0; + opl4_midi_cur->voice_data[voice].reg_misc = 0; + opl4_midi_cur->voice_data[voice].reg_lfo_vibrato = 0; + } + opl4_midi_cur->wait_event = thread_create_event(); + opl4_midi_cur->thread = thread_create(opl4_midi_thread, NULL); + return dev; +} + +void +opl4_close(void *p) +{ + if (!p) + return; + + opl4_midi_cur->on = false; + thread_set_event(opl4_midi_cur->wait_event); + thread_wait(opl4_midi_cur->thread); + free(opl4_midi_cur); + opl4_midi_cur = NULL; +} + +static int +opl4_midi_available(void) +{ + return rom_present("roms/sound/yamaha/yrw801.rom"); +} + +const device_t opl4_midi_device = { + .name = "OPL4-ML Daughterboard", + .internal_name = "opl4-ml", + .flags = 0, + .local = 0, + .init = opl4_init, + .close = opl4_close, + .reset = NULL, + { .available = opl4_midi_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/midi_opl4_yrw801.c b/src/sound/midi_opl4_yrw801.c new file mode 100644 index 0000000000..96822b9af6 --- /dev/null +++ b/src/sound/midi_opl4_yrw801.c @@ -0,0 +1,1042 @@ +/* Table taken from linux/sound/drivers/opl4/yrw801.c */ +/* Macros from Linux source code as well */ + +#include "yrw801.h" + +static const YRW801_REGION_DATA regions_00[] = { + /* Acoustic Grand Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_01[] = { + /* Bright Acoustic Piano */ + { 0x14, 0x2d, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2081, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1444, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_02[] = { + /* Electric Grand Piano */ + { 0x14, 0x2d, { 0x12c, 7476, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x13, 0x07, 0x0 } }, + { 0x2e, 0x33, { 0x12d, 6818, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x34, 0x39, { 0x12e, 5901, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x3a, 0x3f, { 0x12f, 5292, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x40, 0x45, { 0x130, 4262, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x46, 0x4b, { 0x131, 3627, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x4c, 0x52, { 0x132, 3118, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x53, 0x58, { 0x133, 2083, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x17, 0x0 } }, + { 0x59, 0x5e, { 0x134, 1446, 100, 1, 0, 0x00, 0xae, 0x20, 0xf3, 0x14, 0x17, 0x0 } }, + { 0x5f, 0x6d, { 0x135, 1917, 100, 1, 0, 0x00, 0xae, 0x20, 0xf4, 0x15, 0x07, 0x0 } }, + { 0x00, 0x7f, { 0x06c, 6375, 100, -1, 0, 0x00, 0xc2, 0x28, 0xf4, 0x23, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_03[] = { + /* Honky-Tonk Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x27, { 0x12c, 7486, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6803, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5912, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5275, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4274, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3611, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3129, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2074, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1457, 100, 0, 0, 0x01, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1903, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_04[] = { + /* Electric Piano 1 */ + { 0x15, 0x6c, { 0x00b, 6570, 100, 0, 0, 0x00, 0x28, 0x38, 0xf0, 0x00, 0x0c, 0x0 }}, + { 0x00, 0x7f, { 0x06c, 6375, 100, 0, 2, 0x00, 0xb0, 0x22, 0xf4, 0x23, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_05[] = { + /* Electric Piano 2 */ + { 0x14, 0x27, { 0x12c, 7476, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6818, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5901, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5292, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4262, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3627, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3118, 100, 0, 3, 0x04, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2083, 100, 0, 3, 0x03, 0xa2, 0x1b, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1446, 100, 0, 3, 0x07, 0xa2, 0x1b, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1917, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x2d, { 0x12c, 7472, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6814, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5897, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5288, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4258, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3623, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3114, 100, 0, 0, 0x04, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2079, 100, 0, 0, 0x07, 0xa2, 0x18, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1442, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1913, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_06[] = { + /* Harpsichord */ + { 0x15, 0x39, { 0x080, 5158, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x24, 0x19, 0x0 }}, + { 0x3a, 0x3f, { 0x081, 4408, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x40, 0x45, { 0x082, 3622, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x46, 0x4d, { 0x083, 2843, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x19, 0x0 }}, + { 0x4e, 0x6c, { 0x084, 1307, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x29, 0x0 }} +}; +static const YRW801_REGION_DATA regions_07[] = { + /* Clavinet */ + { 0x15, 0x51, { 0x027, 5009, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x2b, 0x0 }}, + { 0x52, 0x6c, { 0x028, 3495, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x3b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_08[] = { + /* Celesta */ + { 0x15, 0x6c, { 0x02b, 3267, 100, 0, 0, 0x00, 0xdc, 0x20, 0xf4, 0x15, 0x07, 0x3 }} +}; +static const YRW801_REGION_DATA regions_09[] = { + /* Glockenspiel */ + { 0x15, 0x78, { 0x0f3, 285, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf6, 0x25, 0x25, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0a[] = { + /* Music Box */ + { 0x15, 0x6c, { 0x0f3, 3362, 100, 0, 0, 0x00, 0xb6, 0x20, 0xa6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x6c, { 0x101, 4773, 100, 0, 0, 0x00, 0xaa, 0x20, 0xd4, 0x14, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0b[] = { + /* Vibraphone */ + { 0x15, 0x6c, { 0x101, 4778, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf4, 0x14, 0x16, 0x4 }} +}; +static const YRW801_REGION_DATA regions_0c[] = { + /* Marimba */ + { 0x15, 0x3f, { 0x0f4, 4778, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x40, 0x4c, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x4d, 0x5a, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x08, 0x0 }}, + { 0x5b, 0x7f, { 0x0f5, 3218, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0d[] = { + /* Xylophone */ + { 0x00, 0x7f, { 0x136, 1729, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x06, 0x36, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0e[] = { + /* Tubular Bell */ + { 0x01, 0x7f, { 0x0ff, 3999, 100, 0, 1, 0x00, 0x90, 0x21, 0xf4, 0xa3, 0x25, 0x1 }} +}; +static const YRW801_REGION_DATA regions_0f[] = { + /* Dulcimer */ + { 0x00, 0x7f, { 0x03f, 4236, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf5, 0x16, 0x07, 0x0 }}, + { 0x00, 0x7f, { 0x040, 4236, 100, 0, 2, 0x0e, 0x94, 0x2a, 0xf5, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_10[] = { + /* Drawbar Organ */ + { 0x01, 0x7f, { 0x08e, 4394, 100, 0, 2, 0x14, 0xc2, 0x3a, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_11[] = { + /* Percussive Organ */ + { 0x15, 0x3b, { 0x08c, 6062, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3c, 0x6c, { 0x08d, 2984, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_12[] = { + /* Rock Organ */ + { 0x15, 0x30, { 0x128, 6574, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x31, 0x3c, { 0x129, 5040, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3d, 0x48, { 0x12a, 3498, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x49, 0x54, { 0x12b, 1957, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x55, 0x6c, { 0x127, 423, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_13[] = { + /* Church Organ */ + { 0x15, 0x29, { 0x087, 7466, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x30, { 0x088, 6456, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x31, 0x38, { 0x089, 5428, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x41, { 0x08a, 4408, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x42, 0x6c, { 0x08b, 3406, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_14[] = { + /* Reed Organ */ + { 0x00, 0x53, { 0x0ac, 5570, 100, 0, 0, 0x06, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x54, 0x7f, { 0x0ad, 2497, 100, 0, 0, 0x00, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_15[] = { + /* Accordion */ + { 0x15, 0x4c, { 0x006, 4261, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x4d, 0x6c, { 0x007, 1530, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x070, 4391, 100, 0, 3, 0x00, 0x8a, 0x23, 0xa0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_16[] = { + /* Harmonica */ + { 0x15, 0x6c, { 0x070, 4408, 100, 0, 0, 0x00, 0xae, 0x30, 0xa0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_17[] = { + /* Tango Accordion */ + { 0x00, 0x53, { 0x0ac, 5573, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x54, 0x7f, { 0x0ad, 2500, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x041, 8479, 100, 0, 2, 0x00, 0x6a, 0x3a, 0x75, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_18[] = { + /* Nylon Guitar */ + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 0, 0x05, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 0, 0x0c, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x09, 0x0 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_19[] = { + /* Steel Guitar */ + { 0x15, 0x31, { 0x00c, 6937, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x04, 0x19, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5410, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x05, 0x09, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4379, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf5, 0x94, 0x09, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2843, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf6, 0x95, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1a[] = { + /* Jazz Guitar */ + { 0x15, 0x31, { 0x05a, 6832, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x32, 0x3f, { 0x05b, 4897, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x05c, 3218, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1b[] = { + /* Clean Guitar */ + { 0x15, 0x2c, { 0x061, 7053, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x2d, 0x31, { 0x060, 6434, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x32, 0x38, { 0x063, 5764, 100, 0, 1, 0x00, 0xbe, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x39, 0x3f, { 0x062, 4627, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x40, 0x44, { 0x065, 3963, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x45, 0x4b, { 0x064, 3313, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x4c, 0x54, { 0x066, 2462, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x2a, 0x0 }}, + { 0x55, 0x6c, { 0x067, 1307, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf6, 0x56, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1c[] = { + /* Muted Guitar */ + { 0x01, 0x7f, { 0x068, 4408, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1d[] = { + /* Overdriven Guitar */ + { 0x00, 0x40, { 0x0a5, 6589, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5428, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1e[] = { + /* Distortion Guitar */ + { 0x15, 0x2a, { 0x051, 6928, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2b, 0x2e, { 0x052, 6433, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2f, 0x32, { 0x053, 5944, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x33, 0x36, { 0x054, 5391, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x37, 0x3a, { 0x055, 4897, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3b, 0x3e, { 0x056, 4408, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3f, 0x42, { 0x057, 3892, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x43, 0x46, { 0x058, 3361, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x47, 0x6c, { 0x059, 2784, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1f[] = { + /* Guitar Harmonics */ + { 0x15, 0x44, { 0x05e, 5499, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x45, 0x49, { 0x05d, 4850, 100, 0, 0, 0x00, 0xe2, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x05f, 4259, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_20[] = { + /* Acoustic Bass */ + { 0x15, 0x30, { 0x004, 8053, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }}, + { 0x31, 0x6c, { 0x005, 4754, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_21[] = { + /* Fingered Bass */ + { 0x01, 0x20, { 0x04a, 8762, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x21, 0x25, { 0x04b, 8114, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x26, 0x2a, { 0x04c, 7475, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x2b, 0x7f, { 0x04d, 6841, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_22[] = { + /* Picked Bass */ + { 0x15, 0x23, { 0x04f, 7954, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x0a, 0x0 }}, + { 0x24, 0x2a, { 0x050, 7318, 100, 0, 0, 0x05, 0xcc, 0x18, 0xf3, 0x90, 0x1a, 0x0 }}, + { 0x2b, 0x2f, { 0x06b, 6654, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x2a, 0x0 }}, + { 0x30, 0x47, { 0x069, 6031, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }}, + { 0x48, 0x6c, { 0x06a, 5393, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_23[] = { + /* Fretless Bass */ + { 0x01, 0x7f, { 0x04e, 5297, 100, 0, 0, 0x00, 0xd2, 0x10, 0xf3, 0x63, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_24[] = { + /* Slap Bass 1 */ + { 0x15, 0x6c, { 0x0a3, 7606, 100, 0, 1, 0x00, 0xde, 0x19, 0xf5, 0x32, 0x1a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_25[] = { + /* Slap Bass 2 */ + { 0x01, 0x7f, { 0x0a2, 6694, 100, 0, 0, 0x00, 0xda, 0x20, 0xb0, 0x02, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_26[] = { + /* Synth Bass 1 */ + { 0x15, 0x6c, { 0x0be, 7466, 100, 0, 1, 0x00, 0xb8, 0x39, 0xf4, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_27[] = { + /* Synth Bass 2 */ + { 0x00, 0x7f, { 0x117, 8103, 100, 0, 1, 0x00, 0xca, 0x39, 0xf3, 0x50, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_28[] = { + /* Violin */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_29[] = { + /* Viola */ + { 0x15, 0x32, { 0x103, 5780, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x33, 0x35, { 0x104, 5534, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x36, 0x38, { 0x105, 5158, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x39, 0x3d, { 0x102, 4754, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x3e, 0x3f, { 0x106, 4132, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x42, { 0x107, 4033, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x43, 0x45, { 0x108, 3580, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x46, 0x48, { 0x10a, 2957, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x49, 0x4a, { 0x10b, 2724, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10c, 2530, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4f, { 0x10d, 2166, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x50, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2a[] = { + /* Cello */ + { 0x15, 0x2d, { 0x112, 6545, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x2e, 0x37, { 0x113, 5764, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x38, 0x3e, { 0x115, 4378, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x3f, 0x44, { 0x116, 3998, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x45, 0x6c, { 0x114, 3218, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2b[] = { + /* Contrabass */ + { 0x15, 0x29, { 0x110, 7713, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x6c, { 0x111, 6162, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2c[] = { + /* Tremolo Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 0, 0x0a, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 } } +}; +static const YRW801_REGION_DATA regions_2d[] = { + /* Pizzicato Strings */ + { 0x15, 0x32, { 0x0b8, 6186, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x33, 0x3b, { 0x0b9, 5031, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x3c, 0x42, { 0x0bb, 4146, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x43, 0x48, { 0x0ba, 3245, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x49, 0x6c, { 0x0bc, 2352, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2e[] = { + /* Harp */ + { 0x15, 0x46, { 0x07e, 3740, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }}, + { 0x47, 0x6c, { 0x07f, 2319, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2f[] = { + /* Timpani */ + { 0x15, 0x6c, { 0x100, 6570, 100, 0, 0, 0x00, 0xf8, 0x28, 0xf0, 0x05, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_30[] = { + /* Strings */ + { 0x15, 0x3b, { 0x13c, 4806, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x13e, 4035, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x13d, 3122, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x13f, 2629, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x140, 950, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_31[] = { + /* Slow Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 1, 0x0a, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_32[] = { + /* Synth Strings 1 */ + { 0x05, 0x71, { 0x002, 6045, 100, -2, 0, 0x00, 0xa6, 0x20, 0x93, 0x22, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x0ae, 3261, 100, 2, 0, 0x00, 0xc6, 0x20, 0x70, 0x01, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_33[] = { + /* Synth Strings 2 */ + { 0x15, 0x6c, { 0x002, 4513, 100, 5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 } }, + { 0x15, 0x6c, { 0x002, 4501, 100, -5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_34[] = { + /* Choir Aahs */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_35[] = { + /* Voice Oohs */ + { 0x15, 0x6c, { 0x029, 3596, 100, 0, 0, 0x00, 0xe6, 0x20, 0xf7, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_36[] = { + /* Synth Voice */ + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 1, 0x00, 0xc2, 0x19, 0x85, 0x21, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_37[] = { + /* Orchestra Hit */ + { 0x15, 0x6c, { 0x049, 4394, 100, 0, 0, 0x00, 0xfe, 0x30, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_38[] = { + /* Trumpet */ + { 0x15, 0x3c, { 0x0f6, 4706, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x0f8, 3894, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x44, 0x48, { 0x0f7, 3118, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x49, 0x4e, { 0x0fa, 2322, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4f, 0x55, { 0x0f9, 1634, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x0fb, 786, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_39[] = { + /* Trombone */ + { 0x15, 0x3a, { 0x0f0, 5053, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x0f1, 4290, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x0f2, 3580, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3a[] = { + /* Tuba */ + { 0x15, 0x2d, { 0x085, 7096, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }}, + { 0x2e, 0x6c, { 0x086, 6014, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3b[] = { + /* Muted Trumpet */ + { 0x15, 0x45, { 0x0b1, 4135, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf3, 0x10, 0x0a, 0x1 }}, + { 0x46, 0x6c, { 0x0b2, 2599, 100, 0, 0, 0x00, 0xcc, 0x28, 0x83, 0x10, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_3c[] = { + /* French Horns */ + { 0x15, 0x49, { 0x07c, 3624, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x07d, 2664, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3d[] = { + /* Brass Section */ + { 0x15, 0x42, { 0x0fc, 4375, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x43, 0x6c, { 0x0fd, 2854, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3e[] = { + /* Synth Brass 1 */ + { 0x01, 0x27, { 0x0d3, 9094, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8335, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7558, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6785, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6042, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5257, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4493, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3741, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3012, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2167, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1421, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -115, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9103, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8340, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7565, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6804, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6042, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5277, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4520, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3741, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3012, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2166, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1421, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -115, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } } +}; +static const YRW801_REGION_DATA regions_3f[] = { + /* Synth Brass 2 */ + { 0x01, 0x27, { 0x118, 9113, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8350, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7575, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6814, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6052, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5287, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4530, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3751, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3022, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2176, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1431, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -105, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x00, 0x7f, { 0x124, 4034, 100, -3, 2, 0x00, 0xea, 0x22, 0x85, 0x23, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_40[] = { + /* Soprano Sax */ + { 0x15, 0x3f, { 0x0e3, 4228, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x0e4, 3495, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x0e5, 2660, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x0e6, 2002, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x59, { 0x0e7, 1186, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x59, 0x6c, { 0x0e8, 1730, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_41[] = { + /* Alto Sax */ + { 0x15, 0x32, { 0x092, 6204, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x33, 0x35, { 0x096, 5812, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x36, 0x3a, { 0x099, 5318, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3b, 0x3b, { 0x08f, 5076, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3c, 0x3e, { 0x093, 4706, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3f, 0x41, { 0x097, 4321, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x42, 0x44, { 0x09a, 3893, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x45, 0x47, { 0x090, 3497, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x48, 0x4a, { 0x094, 3119, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4b, 0x4d, { 0x098, 2726, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4e, 0x50, { 0x09b, 2393, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x51, 0x53, { 0x091, 2088, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x54, 0x6c, { 0x095, 1732, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_42[] = { + /* Tenor Sax */ + { 0x24, 0x30, { 0x0e9, 6301, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x31, 0x34, { 0x0ea, 5781, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x35, 0x3a, { 0x0eb, 5053, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x3b, 0x41, { 0x0ed, 4165, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x42, 0x47, { 0x0ec, 3218, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x48, 0x51, { 0x0ee, 2462, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x52, 0x6c, { 0x0ef, 1421, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_43[] = { + /* Baritone Sax */ + { 0x15, 0x2d, { 0x0df, 6714, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x2e, 0x34, { 0x0e1, 5552, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x35, 0x39, { 0x0e2, 5178, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3a, 0x6c, { 0x0e0, 4437, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_44[] = { + /* Oboe */ + { 0x15, 0x3c, { 0x042, 4493, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x044, 3702, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x44, 0x49, { 0x043, 2956, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x4a, 0x4f, { 0x046, 2166, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x50, 0x55, { 0x045, 1420, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x047, 630, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_45[] = { + /* English Horn */ + { 0x15, 0x38, { 0x03c, 5098, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x3e, { 0x03b, 4291, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x6c, { 0x03d, 3540, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_46[] = { + /* Bassoon */ + { 0x15, 0x22, { 0x038, 7833, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x23, 0x2e, { 0x03a, 7070, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x2f, 0x6c, { 0x039, 6302, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_47[] = { + /* Clarinet */ + { 0x15, 0x3b, { 0x09e, 5900, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3c, 0x41, { 0x0a0, 5158, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x42, 0x4a, { 0x09f, 4260, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4b, 0x6c, { 0x0a1, 2957, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_48[] = { + /* Piccolo */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x53, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x54, 0x5f, { 0x074, 2085, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x60, 0x6c, { 0x075, 1421, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_49[] = { + /* Flute */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x6c, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4a[] = { + /* Recorder */ + { 0x15, 0x6f, { 0x0bd, 4897, 100, 0, 0, 0x00, 0xec, 0x30, 0x70, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_4b[] = { + /* Pan Flute */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x09, 0x3 }} +}; +static const YRW801_REGION_DATA regions_4c[] = { + /* Bottle Blow */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xc8, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x125, 7372, 100, 0, 0, 0x1e, 0x80, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4d[] = { + /* Shakuhachi */ + { 0x00, 0x7f, { 0x0ab, 4548, 100, 0, 0, 0x00, 0xd6, 0x30, 0xf0, 0x00, 0x0a, 0x3 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xa2, 0x28, 0x70, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4e[] = { + /* Whistle */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 4, 0x00, 0xd2, 0x2c, 0x70, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4f[] = { + /* Ocarina */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 1, 0x00, 0xce, 0x29, 0x90, 0x00, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_50[] = { + /* Square Lead */ + { 0x01, 0x2a, { 0x0cc, 9853, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x2b, 0x36, { 0x0cd, 6785, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x37, 0x42, { 0x0ca, 5248, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x43, 0x4e, { 0x0cf, 3713, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x4f, 0x5a, { 0x0ce, 2176, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x5b, 0x7f, { 0x0cb, 640, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x01, 0x2a, { 0x0cc, 9844, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x2b, 0x36, { 0x0cd, 6776, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x37, 0x42, { 0x0ca, 5239, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x43, 0x4e, { 0x0cf, 3704, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x4f, 0x5a, { 0x0ce, 2167, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x5b, 0x7f, { 0x0cb, 631, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 } } +}; +static const YRW801_REGION_DATA regions_51[] = { + /* Sawtooth Lead */ + { 0x01, 0x27, { 0x118, 9108, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8345, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7570, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6809, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6047, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5282, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4525, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3746, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3017, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2171, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1426, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -110, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_52[] = { + /* Calliope Lead */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 0, 0x00, 0xc2, 0x28, 0x90, 0x00, 0x0a, 0x2 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xb6, 0x28, 0xb0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_53[] = { + /* Chiffer Lead */ + { 0x00, 0x7f, { 0x13a, 3665, 100, 0, 2, 0x00, 0xcc, 0x2a, 0xf0, 0x10, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x0fe, 3660, 100, 0, 0, 0x00, 0xbe, 0x28, 0xf3, 0x10, 0x17, 0x0 }} +}; +static const YRW801_REGION_DATA regions_54[] = { + /* Charang Lead */ + { 0x00, 0x40, { 0x0a5, 6594, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5433, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }} +}; +static const YRW801_REGION_DATA regions_55[] = { + /* Voice Lead */ + { 0x00, 0x7f, { 0x0aa, 1739, 100, 0, 6, 0x00, 0x8c, 0x2e, 0x90, 0x00, 0x0a, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3474, 100, 0, 1, 0x00, 0xd8, 0x29, 0xf0, 0x05, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_56[] = { + /* 5ths Lead */ + { 0x01, 0x27, { 0x118, 8468, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x119, 7705, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 6930, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6169, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 5407, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x11d, 4642, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 3885, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3106, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x120, 2377, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x121, 1531, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x5e, 0x64, { 0x122, 786, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -750, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x05, 0x71, { 0x002, 4503, 100, 0, 1, 0x00, 0xb8, 0x31, 0xb3, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_57[] = { + /* Bass & Lead */ + { 0x00, 0x7f, { 0x117, 8109, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf3, 0x50, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9097, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8334, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7559, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6798, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6036, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5271, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4514, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3735, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3006, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2160, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1415, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -121, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_58[] = { + /* New Age Pad */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 4, 0x00, 0xa4, 0x24, 0x80, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 4253, 100, 0, 3, 0x00, 0x8c, 0x23, 0xa2, 0x14, 0x06, 0x1 }} +}; +static const YRW801_REGION_DATA regions_59[] = { + /* Warm Pad */ + { 0x15, 0x6c, { 0x04e, 5306, 100, 2, 2, 0x00, 0x92, 0x2a, 0x34, 0x23, 0x05, 0x2 } }, + { 0x15, 0x6c, { 0x029, 3575, 100, -2, 2, 0x00, 0xbe, 0x22, 0x31, 0x23, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5a[] = { + /* Polysynth Pad */ + { 0x01, 0x27, { 0x118, 9111, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x28, 0x2d, { 0x119, 8348, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x2e, 0x33, { 0x11a, 7573, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x34, 0x39, { 0x11b, 6812, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x3a, 0x3f, { 0x11c, 6050, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x40, 0x45, { 0x11d, 5285, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x46, 0x4b, { 0x11e, 4528, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x4c, 0x51, { 0x11f, 3749, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x52, 0x57, { 0x120, 3020, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x58, 0x5d, { 0x121, 2174, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x5e, 0x66, { 0x122, 1429, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x67, 0x7f, { 0x123, -107, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x00, 0x7f, { 0x124, 4024, 100, 0, 2, 0x00, 0xae, 0x22, 0xe5, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5b[] = { + /* Choir Pad */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 4, 0x00, 0x98, 0x24, 0x65, 0x21, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5c[] = { + /* Bowed Pad */ + { 0x15, 0x6c, { 0x101, 4790, 100, -1, 1, 0x00, 0xbe, 0x19, 0x44, 0x14, 0x16, 0x0 }}, + { 0x00, 0x7f, { 0x0aa, 1720, 100, 1, 1, 0x00, 0x94, 0x19, 0x40, 0x00, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_5d[] = { + /* Metallic Pad */ + { 0x15, 0x31, { 0x00c, 6943, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5416, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4385, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2849, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x03f, 4224, 100, 0, 1, 0x00, 0x9c, 0x31, 0x65, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5e[] = { + /* Halo Pad */ + { 0x00, 0x7f, { 0x124, 4038, 100, 0, 2, 0x00, 0xa6, 0x1a, 0x85, 0x23, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3471, 100, 0, 3, 0x00, 0xc0, 0x1b, 0xc0, 0x05, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5f[] = { + /* Sweep Pad */ + { 0x01, 0x27, { 0x0d3, 9100, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8341, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7564, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6791, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6048, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5263, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4499, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3747, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3018, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2173, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1427, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -109, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x01, 0x27, { 0x0d3, 9088, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8329, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7552, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6779, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6036, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5251, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4487, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3735, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3006, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2161, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1415, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -121, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_60[] = { + /* Ice Rain */ + { 0x01, 0x7f, { 0x04e, 9345, 100, 0, 2, 0x00, 0xcc, 0x22, 0xa3, 0x63, 0x17, 0x0 }}, + { 0x00, 0x7f, { 0x143, 5586, 20, 0, 2, 0x00, 0x6e, 0x2a, 0xf0, 0x05, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_61[] = { + /* Soundtrack */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 2, 0x00, 0xb6, 0x2a, 0x60, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 1160, 100, 0, 5, 0x00, 0xa8, 0x2d, 0x52, 0x14, 0x06, 0x2 }} +}; +static const YRW801_REGION_DATA regions_62[] = { + /* Crystal */ + { 0x15, 0x6c, { 0x0f3, 1826, 100, 0, 3, 0x00, 0xb8, 0x33, 0xf6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x2c, { 0x06d, 7454, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x2d, 0x36, { 0x06e, 5925, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x37, 0x6c, { 0x06f, 4403, 100, 0, 3, 0x09, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_63[] = { + /* Atmosphere */ + { 0x05, 0x71, { 0x002, 4509, 100, 0, 2, 0x00, 0xc8, 0x32, 0x73, 0x22, 0x06, 0x1 }}, + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 2, 0x05, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 2, 0x0c, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x34, 0x07, 0x2 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x07, 0x2 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x17, 0x2 }} +}; +static const YRW801_REGION_DATA regions_64[] = { + /* Brightness */ + { 0x00, 0x7f, { 0x137, 5285, 100, 0, 2, 0x00, 0xbe, 0x2a, 0xa5, 0x18, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3481, 100, 0, 1, 0x00, 0xc8, 0x29, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_65[] = { + /* Goblins */ + { 0x15, 0x6c, { 0x002, 4501, 100, -1, 2, 0x00, 0xca, 0x2a, 0x40, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x009, 9679, 20, 1, 4, 0x00, 0x3c, 0x0c, 0x22, 0x11, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_66[] = { + /* Echoes */ + { 0x15, 0x6c, { 0x02a, 3487, 100, 0, 3, 0x00, 0xae, 0x2b, 0xf5, 0x21, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x124, 4027, 100, 0, 3, 0x00, 0xae, 0x2b, 0x85, 0x23, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_67[] = { + /* Sci-Fi */ + { 0x15, 0x31, { 0x00c, 6940, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x32, 0x38, { 0x00d, 5413, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x39, 0x47, { 0x00e, 4382, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x48, 0x6c, { 0x00f, 2846, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x15, 0x6c, { 0x002, 4498, 100, 0, 2, 0x00, 0xd4, 0x22, 0x80, 0x01, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_68[] = { + /* Sitar */ + { 0x00, 0x7f, { 0x10f, 4408, 100, 0, 2, 0x00, 0xc4, 0x32, 0xf4, 0x15, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_69[] = { + /* Banjo */ + { 0x15, 0x34, { 0x013, 5685, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x35, 0x38, { 0x014, 5009, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x39, 0x3c, { 0x012, 4520, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x3d, 0x44, { 0x015, 3622, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x45, 0x4c, { 0x017, 2661, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x4d, 0x6d, { 0x016, 1632, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6a[] = { + /* Shamisen */ + { 0x15, 0x6c, { 0x10e, 3273, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf7, 0x76, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6b[] = { + /* Koto */ + { 0x00, 0x7f, { 0x0a9, 4033, 100, 0, 0, 0x00, 0xc6, 0x20, 0xf0, 0x06, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6c[] = { + /* Kalimba */ + { 0x00, 0x7f, { 0x137, 3749, 100, 0, 0, 0x00, 0xce, 0x38, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6d[] = { + /* Bagpipe */ + { 0x15, 0x39, { 0x0a4, 7683, 100, 0, 4, 0x00, 0xc0, 0x1c, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x39, { 0x0a7, 7680, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3a, 0x6c, { 0x0a8, 3697, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6e[] = { + /* Fiddle */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6f[] = { + /* Shanai */ + { 0x15, 0x6c, { 0x041, 6946, 100, 0, 1, 0x00, 0xc4, 0x31, 0x95, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_70[] = { + /* Tinkle Bell */ + { 0x15, 0x73, { 0x0f3, 1821, 100, 0, 3, 0x00, 0xc8, 0x3b, 0xd6, 0x25, 0x25, 0x0 }}, + { 0x00, 0x7f, { 0x137, 5669, 100, 0, 3, 0x00, 0x66, 0x3b, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_71[] = { + /* Agogo */ + { 0x15, 0x74, { 0x00b, 2474, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_72[] = { + /* Steel Drums */ + { 0x01, 0x7f, { 0x0fe, 3670, 100, 0, 0, 0x00, 0xca, 0x38, 0xf3, 0x06, 0x17, 0x1 }}, + { 0x15, 0x6c, { 0x100, 9602, 100, 0, 0, 0x00, 0x54, 0x38, 0xb0, 0x05, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_73[] = { + /* Woodblock */ + { 0x15, 0x6c, { 0x02c, 2963, 50, 0, 0, 0x07, 0xd4, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_74[] = { + /* Taiko Drum */ + { 0x13, 0x6c, { 0x03e, 1194, 50, 0, 0, 0x00, 0xaa, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_75[] = { + /* Melodic Tom */ + { 0x15, 0x6c, { 0x0c7, 6418, 50, 0, 0, 0x00, 0xe4, 0x38, 0xf0, 0x05, 0x01, 0x0 }} +}; +static const YRW801_REGION_DATA regions_76[] = { + /* Synth Drum */ + { 0x15, 0x6c, { 0x026, 3898, 50, 0, 0, 0x00, 0xd0, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_77[] = { + /* Reverse Cymbal */ + { 0x15, 0x6c, { 0x031, 4138, 50, 0, 0, 0x00, 0xfe, 0x38, 0x3a, 0xf0, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_78[] = { + /* Guitar Fret Noise */ + { 0x15, 0x6c, { 0x138, 5266, 100, 0, 0, 0x00, 0xa0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_79[] = { + /* Breath Noise */ + { 0x01, 0x7f, { 0x125, 4269, 100, 0, 0, 0x1e, 0xd0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7a[] = { + /* Seashore */ + { 0x15, 0x6c, { 0x008, 2965, 20, -2, 0, 0x00, 0xfe, 0x00, 0x20, 0x03, 0x04, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 20, 2, 0, 0x14, 0xfe, 0x00, 0x20, 0x04, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7b[] = { + /* Bird Tweet */ + { 0x15, 0x6c, { 0x009, 8078, 5, -4, 7, 0x00, 0xc2, 0x0f, 0x22, 0x12, 0x07, 0x0 }}, + { 0x15, 0x6c, { 0x009, 3583, 5, 4, 5, 0x00, 0xae, 0x15, 0x72, 0x12, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7c[] = { + /* Telephone Ring */ + { 0x15, 0x6c, { 0x003, 3602, 10, 0, 0, 0x00, 0xce, 0x00, 0xf0, 0x00, 0x0f, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7d[] = { + /* Helicopter */ + { 0x0c, 0x7f, { 0x001, 2965, 10, -2, 0, 0x00, 0xe0, 0x08, 0x30, 0x01, 0x07, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 10, 2, 0, 0x44, 0x76, 0x00, 0x30, 0x01, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7e[] = { + /* Applause */ + { 0x15, 0x6c, { 0x036, 8273, 20, -6, 7, 0x00, 0xc4, 0x0f, 0x70, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x036, 8115, 5, 6, 7, 0x00, 0xc6, 0x07, 0x70, 0x01, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7f[] = { + /* Gun Shot */ + { 0x15, 0x6c, { 0x139, 2858, 20, 0, 0, 0x00, 0xbe, 0x38, 0xf0, 0x03, 0x00, 0x0 }} +}; +static const YRW801_REGION_DATA regions_drums[] = { + { 0x18, 0x18, { 0x0cb, 6397, 100, 3, 0, 0x00, 0xf4, 0x38, 0xc9, 0x1c, 0x0c, 0x0 } }, + { 0x19, 0x19, { 0x0c4, 3714, 100, 0, 0, 0x00, 0xe0, 0x00, 0x97, 0x19, 0x09, 0x0 } }, + { 0x1a, 0x1a, { 0x0c4, 3519, 100, 0, 0, 0x00, 0xea, 0x00, 0x61, 0x01, 0x07, 0x0 } }, + { 0x1b, 0x1b, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0xf7, 0x19, 0x09, 0x0 } }, + { 0x1c, 0x1c, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0x81, 0x01, 0x07, 0x0 } }, + { 0x1e, 0x1e, { 0x0c3, 4783, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x1f, 0x1f, { 0x0d1, 4042, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x20, 0x20, { 0x0d2, 5943, 100, 0, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x21, 0x21, { 0x011, 3842, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x23, 0x23, { 0x011, 4098, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x24, 0x24, { 0x011, 4370, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x25, 0x25, { 0x0d2, 4404, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x26, 0x26, { 0x0d1, 4298, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x27, 0x27, { 0x00a, 4403, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x28, 0x28, { 0x0d1, 4554, 100, 0, 0, 0x00, 0xdc, 0x00, 0xf0, 0x07, 0x07, 0x0 } }, + { 0x29, 0x29, { 0x0c8, 4242, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2a, 0x2a, { 0x079, 6160, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf5, 0x19, 0x09, 0x0 } }, + { 0x2b, 0x2b, { 0x0c8, 4626, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2c, 0x2c, { 0x07b, 6039, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x2d, 0x2d, { 0x0c8, 5394, 100, -2, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2e, 0x2e, { 0x07a, 5690, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x05, 0x0 } }, + { 0x2f, 0x2f, { 0x0c7, 5185, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x30, 0x30, { 0x0c7, 5650, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x31, 0x31, { 0x031, 4395, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x32, 0x32, { 0x0c7, 6162, 100, 4, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x33, 0x33, { 0x02e, 4391, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x34, 0x34, { 0x07a, 3009, 100, -2, 0, 0x00, 0xea, 0x00, 0xf2, 0x15, 0x05, 0x0 }}, + { 0x35, 0x35, { 0x021, 4522, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x36, 0x36, { 0x025, 5163, 100, 1, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x37, 0x37, { 0x031, 5287, 100, -1, 0, 0x00, 0xea, 0x00, 0xf5, 0x16, 0x06, 0x0 }}, + { 0x38, 0x38, { 0x01d, 4395, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x39, 0x39, { 0x031, 4647, 100, -2, 0, 0x00, 0xea, 0x00, 0xf4, 0x16, 0x06, 0x0 }}, + { 0x3a, 0x3a, { 0x09d, 4426, 100, -4, 0, 0x00, 0xe0, 0x00, 0xf4, 0x17, 0x07, 0x0 }}, + { 0x3b, 0x3b, { 0x02e, 4659, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x06, 0x06, 0x0 }}, + { 0x3c, 0x3c, { 0x01c, 4769, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3d, 0x3d, { 0x01c, 4611, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3e, 0x3e, { 0x01e, 4402, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x3f, { 0x01f, 4387, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x40, { 0x01f, 3983, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x41, 0x41, { 0x09c, 4526, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x42, 0x42, { 0x09c, 4016, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x43, 0x43, { 0x00b, 4739, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x44, 0x44, { 0x00b, 4179, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x45, 0x45, { 0x02f, 4787, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x46, 0x46, { 0x030, 4665, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x47, 0x47, { 0x144, 4519, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x48, 0x48, { 0x144, 4111, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x49, 0x49, { 0x024, 6408, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4a, 0x4a, { 0x024, 4144, 100, 3, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4b, 0x4b, { 0x020, 4001, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4c, 0x4c, { 0x02c, 4402, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4d, 0x4d, { 0x02c, 3612, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4e, 0x4e, { 0x022, 4129, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4f, 0x4f, { 0x023, 4147, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x50, 0x50, { 0x032, 4412, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x08, 0x09, 0x0 }}, + { 0x51, 0x51, { 0x032, 4385, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x52, 0x52, { 0x02f, 5935, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define REGION(num) \ + { \ + ARRAY_SIZE(regions##num), regions##num \ + } +const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81] = { + REGION(_00), REGION(_01), REGION(_02), REGION(_03), + REGION(_04), REGION(_05), REGION(_06), REGION(_07), + REGION(_08), REGION(_09), REGION(_0a), REGION(_0b), + REGION(_0c), REGION(_0d), REGION(_0e), REGION(_0f), + REGION(_10), REGION(_11), REGION(_12), REGION(_13), + REGION(_14), REGION(_15), REGION(_16), REGION(_17), + REGION(_18), REGION(_19), REGION(_1a), REGION(_1b), + REGION(_1c), REGION(_1d), REGION(_1e), REGION(_1f), + REGION(_20), REGION(_21), REGION(_22), REGION(_23), + REGION(_24), REGION(_25), REGION(_26), REGION(_27), + REGION(_28), REGION(_29), REGION(_2a), REGION(_2b), + REGION(_2c), REGION(_2d), REGION(_2e), REGION(_2f), + REGION(_30), REGION(_31), REGION(_32), REGION(_33), + REGION(_34), REGION(_35), REGION(_36), REGION(_37), + REGION(_38), REGION(_39), REGION(_3a), REGION(_3b), + REGION(_3c), REGION(_3d), REGION(_3e), REGION(_3f), + REGION(_40), REGION(_41), REGION(_42), REGION(_43), + REGION(_44), REGION(_45), REGION(_46), REGION(_47), + REGION(_48), REGION(_49), REGION(_4a), REGION(_4b), + REGION(_4c), REGION(_4d), REGION(_4e), REGION(_4f), + REGION(_50), REGION(_51), REGION(_52), REGION(_53), + REGION(_54), REGION(_55), REGION(_56), REGION(_57), + REGION(_58), REGION(_59), REGION(_5a), REGION(_5b), + REGION(_5c), REGION(_5d), REGION(_5e), REGION(_5f), + REGION(_60), REGION(_61), REGION(_62), REGION(_63), + REGION(_64), REGION(_65), REGION(_66), REGION(_67), + REGION(_68), REGION(_69), REGION(_6a), REGION(_6b), + REGION(_6c), REGION(_6d), REGION(_6e), REGION(_6f), + REGION(_70), REGION(_71), REGION(_72), REGION(_73), + REGION(_74), REGION(_75), REGION(_76), REGION(_77), + REGION(_78), REGION(_79), REGION(_7a), REGION(_7b), + REGION(_7c), REGION(_7d), REGION(_7e), REGION(_7f), + REGION(_drums) +}; \ No newline at end of file diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index 354c7f61b5..72df8fd32d 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -35,6 +35,7 @@ extern "C" { #include <86box/midi_rtmidi.h> #include <86box/ini.h> #include <86box/config.h> +#include <86box/plat_unused.h> // Disable c99-designator to avoid the warnings in rtmidi_*_device #ifdef __clang__ @@ -50,7 +51,7 @@ static int midi_out_id = 0, midi_in_id = 0; static const int midi_lengths[8] = { 3, 3, 3, 3, 2, 2, 3, 1 }; int -rtmidi_write(uint8_t val) +rtmidi_write(UNUSED(uint8_t val)) { return 0; } @@ -70,7 +71,7 @@ rtmidi_play_sysex(uint8_t *sysex, unsigned int len) } void * -rtmidi_output_init(const device_t *info) +rtmidi_output_init(UNUSED(const device_t *info)) { midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); @@ -110,7 +111,7 @@ rtmidi_output_init(const device_t *info) } void -rtmidi_output_close(void *p) +rtmidi_output_close(UNUSED(void *priv)) { if (!midiout) return; @@ -144,7 +145,7 @@ rtmidi_out_get_dev_name(int num, char *s) } void -rtmidi_input_callback(double timeStamp, std::vector *message, void *userData) +rtmidi_input_callback(UNUSED(double timeStamp), std::vector *message, UNUSED(void *userData)) { if (message->front() == 0xF0) midi_in_sysex(message->data(), message->size()); @@ -153,7 +154,7 @@ rtmidi_input_callback(double timeStamp, std::vector *message, voi } void * -rtmidi_input_init(const device_t *info) +rtmidi_input_init(UNUSED(const device_t *info)) { midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); @@ -198,7 +199,7 @@ rtmidi_input_init(const device_t *info) } void -rtmidi_input_close(void *p) +rtmidi_input_close(UNUSED(void *priv)) { midiin->cancelCallback(); midiin->closePort(); diff --git a/src/sound/munt/CMakeLists.txt b/src/sound/munt/CMakeLists.txt index 37d9e07cce..d0438aa5be 100644 --- a/src/sound/munt/CMakeLists.txt +++ b/src/sound/munt/CMakeLists.txt @@ -22,5 +22,5 @@ add_library(mt32emu STATIC Analog.cpp BReverbModel.cpp Display.cpp File.cpp File srchelper/srctools/src/LinearResampler.cpp srchelper/srctools/src/ResamplerModel.cpp srchelper/srctools/src/SincResampler.cpp - srchelper/InternalResampler.cpp Synth.cpp Tables.cpp TVA.cpp TVF.cpp + srchelper/InternalResampler.cpp Synth.cpp Tables.cpp TVA.cpp TVF.cpp TVP.cpp sha1/sha1.cpp c_interface/c_interface.cpp) \ No newline at end of file diff --git a/src/sound/munt/MidiStreamParser.cpp b/src/sound/munt/MidiStreamParser.cpp index 7b64f97f9f..f91a81828d 100644 --- a/src/sound/munt/MidiStreamParser.cpp +++ b/src/sound/munt/MidiStreamParser.cpp @@ -191,7 +191,7 @@ Bit32u MidiStreamParserImpl::parseShortMessageDataBytes(const Bit8u stream[], Bi } else if (dataByte < 0xF8) { // Discard invalid bytes and start over char s[128]; - sprintf(s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); + snprintf(s, sizeof(s), "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); midiReporter.printDebug(s); streamBufferSize = 0; // Clear streamBuffer return parsedLength; diff --git a/src/sound/munt/Part.cpp b/src/sound/munt/Part.cpp index 5888b97b2d..f536f2ab81 100644 --- a/src/sound/munt/Part.cpp +++ b/src/sound/munt/Part.cpp @@ -54,7 +54,7 @@ Part::Part(Synth *useSynth, unsigned int usePartNum) { // Nasty hack for rhythm timbreTemp = NULL; } else { - sprintf(name, "Part %d", partNum + 1); + snprintf(name, sizeof(name), "Part %d", partNum + 1); timbreTemp = &synth->mt32ram.timbreTemp[partNum]; } currentInstr[0] = 0; diff --git a/src/sound/openal.c b/src/sound/openal.c index 8fe101d648..76656c66e0 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -33,6 +33,7 @@ #include <86box/86box.h> #include <86box/midi.h> #include <86box/sound.h> +#include <86box/plat_unused.h> #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN @@ -58,7 +59,7 @@ al_set_midi(int freq, int buf_size) void closeal(void); ALvoid -alutInit(ALint *argc, ALbyte **argv) +alutInit(UNUSED(ALint *argc), UNUSED(ALbyte **argv)) { /* Open device */ Device = alcOpenDevice((ALCchar *) ""); @@ -118,8 +119,8 @@ inital(void) int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - char *mdn; - int init_midi = 0; + const char *mdn; + int init_midi = 0; if (initialized) return; diff --git a/src/sound/resid-fp/sid.cc b/src/sound/resid-fp/sid.cc index 6f75444238..ad72d9d518 100644 --- a/src/sound/resid-fp/sid.cc +++ b/src/sound/resid-fp/sid.cc @@ -91,6 +91,7 @@ static int host_cpu_features_by_cpuid(void) return features; } +#if (RESID_USE_SSE==1) static int host_cpu_features(void) { static int features = 0; @@ -152,6 +153,7 @@ static int host_cpu_features(void) return 0; } #endif +#endif float SIDFP::kinked_dac(const int x, const float nonlinearity, const int max) { diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index 464e86f778..d302db6ae3 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -25,83 +25,91 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/snd_ac97.h> +#include <86box/plat_fallthrough.h> static const struct { - const uint32_t vendor_id, min_rate, max_rate, misc_flags; /* definitions for misc_flags in snd_ac97.h */ - const uint16_t reset_flags, extid_flags, /* definitions in snd_ac97.h */ - powerdown_mask; /* bits [7:0] => register 26 bits [15:8]; bits [11:8] => register 2A bits [14:11] */ - const ac97_vendor_reg_t *vendor_regs; /* bits [11:8] of index are the page number if applicable (registers [60:6F]) */ - const device_t *device; + const device_t *device; + + /* Definitions for *_flags and vendor_regs in snd_ac97.h */ + uint32_t min_rate; + uint32_t max_rate; + uint32_t misc_flags; + uint16_t reset_flags; + uint16_t extid_flags; + uint8_t pcsr_mask; /* register 26 bits [15:8] */ + uint8_t eascr_mask; /* register 2A bits [14:11] */ + + const ac97_vendor_reg_t *vendor_regs; } ac97_codecs[] = { // clang-format off - [AC97_CODEC_AD1881] = { - .vendor_id = AC97_VENDOR_ID('A', 'D', 'S', 0x40), + { + .device = &ad1881_device, .min_rate = 7000, .max_rate = 48000, .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ .extid_flags = AC97_VRA, - .powerdown_mask = 0x0bf, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x74, 0x0000, 0xff07}, {0x76, 0x0404, 0xdde5}, {0x78, 48000, 0x0000}, {0x7a, 48000, 0x0000}, {0}}, - .device = &ad1881_device + .pcsr_mask = 0xbf, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x74, 0x0000, 0xff07}, {0, 0x76, 0x0404, 0xdde5}, {0, 0x78, 48000, 0x0000}, {0, 0x7a, 48000, 0x0000}, {0}} }, - [AC97_CODEC_AK4540] = { - .vendor_id = AC97_VENDOR_ID('A', 'K', 'M', 0x00), + { + .device = &ak4540_device, .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .powerdown_mask = 0x01f, - .device = &ak4540_device + .pcsr_mask = 0x1f }, - [AC97_CODEC_ALC100] = { - .vendor_id = AC97_VENDOR_ID('A', 'L', 'C', 0x20), + { + .device = &alc100_device, .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, .reset_flags = (22 << AC97_3D_SHIFT), .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0bf, - .device = &alc100_device + .pcsr_mask = 0xbf }, - [AC97_CODEC_CS4297] = { - .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x03), + { + .device = &cs4297_device, .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B, .extid_flags = 0, - .powerdown_mask = 0x07f, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5a, 0x0301, 0x0000}, {0}}, - .device = &cs4297_device + .pcsr_mask = 0x7f, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5a, 0x0301, 0x0000}, {0}} }, - [AC97_CODEC_CS4297A] = { - .vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x11), + { + .device = &cs4297a_device, .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0ff, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0x5e, 0x0000, 0x01b0}, {0x60, 0x0023, 0x0001}, {0x68, 0x0000, 0xdfff}, {0}}, - .device = &cs4297a_device + .pcsr_mask = 0xff, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5e, 0x0000, 0x01b0}, {0, 0x60, 0x0023, 0x0001}, {0, 0x68, 0x0000, 0xdfff}, {0}} }, - [AC97_CODEC_STAC9708] = { - .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08), + { + .device = &stac9708_device, .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, .extid_flags = AC97_SDAC, - .powerdown_mask = 0x2ff, - .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0003}, {0x74, 0x0000, 0x0003}, {0}}, - .device = &stac9708_device + .pcsr_mask = 0xff, + .eascr_mask = 0x02, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0003}, {0, 0x74, 0x0000, 0x0003}, {0}} }, - [AC97_CODEC_STAC9721] = { - .vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09), + { + .device = &stac9721_device, .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, .extid_flags = AC97_AMAP, - .powerdown_mask = 0x0ff, - .vendor_regs = (const ac97_vendor_reg_t []) {{0x6c, 0x0000, 0x0000}, {0x6e, 0x0000, 0x0003}, {0x70, 0x0000, 0xffff}, {0x72, 0x0000, 0x0006}, {0x74, 0x0000, 0x0003}, {0x76, 0x0000, 0xffff}, {0x78, 0x0000, 0x3802}, {0}}, - .device = &stac9721_device + .pcsr_mask = 0xff, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0000}, {0, 0x6e, 0x0000, 0x0003}, {0, 0x70, 0x0000, 0xffff}, {0, 0x72, 0x0000, 0x0006}, {0, 0x74, 0x0000, 0x0003}, {0, 0x76, 0x0000, 0xffff}, {0, 0x78, 0x0000, 0x3802}, {0}} }, - [AC97_CODEC_WM9701A] = { - .vendor_id = AC97_VENDOR_ID('W', 'M', 'L', 0x00), + { + .device = &tr28023_device, + .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = 0, + .extid_flags = 0, + .pcsr_mask = 0x3f + }, + { + .device = &wm9701a_device, .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_DAC_18B | AC97_ADC_18B, .extid_flags = 0, - .powerdown_mask = 0x03f, - .device = &wm9701a_device + .pcsr_mask = 0x3f } // clang-format on }; @@ -163,7 +171,7 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) ac97_codec_log("AC97 Codec %d: writew(%02X, %04X)\n", dev->codec_id, reg, val); reg &= 0x7e; - uint16_t i = 0; + uint16_t i = 0; uint16_t prev = dev->regs[reg >> 1]; int j; @@ -176,7 +184,7 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) val &= 0xbf3f; /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_MASTER_6B)) { + if (!(ac97_codecs[dev->model].misc_flags & AC97_MASTER_6B)) { clamp_5b: if (val & 0x2000) val = (val & ~0x2000) | 0x1f00; @@ -187,41 +195,41 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x04: /* Aux Out Volume */ - if (!(dev->misc_flags & AC97_AUXOUT)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_AUXOUT)) return; val &= 0xbf3f; /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_AUXOUT_6B)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_AUXOUT_6B)) goto clamp_5b; break; case 0x06: /* Mono Out Volume */ - if (!(dev->misc_flags & AC97_MONOOUT)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_MONOOUT)) return; val &= 0x803f; /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_MONOOUT_6B)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_MONOOUT_6B)) goto clamp_5b_r; break; case 0x08: /* Master Tone Control */ - if (!(dev->reset_flags & AC97_TONECTL)) + if (!(ac97_codecs[dev->model].reset_flags & AC97_TONECTL)) return; val &= 0x0f0f; break; case 0x0a: /* PC Beep Volume */ - if (dev->misc_flags & AC97_PCBEEP) + if (ac97_codecs[dev->model].misc_flags & AC97_PCBEEP) i |= 0x801e; - if (dev->misc_flags & AC97_PCBEEP_GEN) + if (ac97_codecs[dev->model].misc_flags & AC97_PCBEEP_GEN) i |= 0x1fe0; val &= i; break; case 0x0c: /* Phone Volume */ - if (!(dev->misc_flags & AC97_PHONE)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_PHONE)) return; val &= 0x801f; break; @@ -238,12 +246,12 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x14: /* Video Volume */ - if (!(dev->misc_flags & AC97_VIDEO)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_VIDEO)) return; goto line_gain; case 0x16: /* Aux In Volume */ - if (!(dev->misc_flags & AC97_AUXIN)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_AUXIN)) return; goto line_gain; @@ -256,26 +264,26 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x1e: /* Record Gain Mic */ - if (!(dev->reset_flags & AC97_MICPCM)) + if (!(ac97_codecs[dev->model].reset_flags & AC97_MICPCM)) return; val &= 0x800f; break; case 0x20: /* General Purpose */ - i = AC97_MIX | (dev->misc_flags & (AC97_POP | AC97_MS | AC97_LPBK)); - if (dev->reset_flags >> AC97_3D_SHIFT) + i = AC97_MIX | (ac97_codecs[dev->model].misc_flags & (AC97_POP | AC97_MS | AC97_LPBK)); + if (ac97_codecs[dev->model].reset_flags >> AC97_3D_SHIFT) i |= AC97_3D; - if (dev->reset_flags & AC97_SIMSTEREO) + if (ac97_codecs[dev->model].reset_flags & AC97_SIMSTEREO) i |= AC97_ST; - if (dev->reset_flags & AC97_LOUDNESS) + if (ac97_codecs[dev->model].reset_flags & AC97_LOUDNESS) i |= AC97_LD; - if (dev->extid_flags & AC97_DRA) + if (ac97_codecs[dev->model].extid_flags & AC97_DRA) i |= AC97_DRSS_MASK; val &= i; break; - case 0x22: /* 3D Control */ - switch (dev->reset_flags >> AC97_3D_SHIFT) { + case 0x22: /* 3D Control */ + switch (ac97_codecs[dev->model].reset_flags >> AC97_3D_SHIFT) { case 1: /* Analog Devices */ case 6: /* Crystal */ val &= 0x000f; @@ -287,7 +295,7 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) case 26: /* SigmaTel */ i = 0x0003; - if (dev->extid_flags & AC97_SDAC) + if (ac97_codecs[dev->model].extid_flags & AC97_SDAC) i |= 0x000c; val &= i; break; @@ -298,13 +306,13 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x24: /* Audio Interrupt and Paging Mechanism */ - if ((dev->extid_flags & AC97_REV_MASK) < AC97_REV_2_3) + if ((ac97_codecs[dev->model].extid_flags & AC97_REV_MASK) < AC97_REV_2_3) return; val &= 0x000f; break; case 0x26: /* Powerdown Control/Status */ - i = dev->powerdown_mask << 8; + i = ac97_codecs[dev->model].pcsr_mask << 8; val = (val & i) | (prev & ~i); /* Update status bits to reflect powerdowns. */ @@ -314,16 +322,16 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x28: /* Extended Audio ID */ - if (dev->misc_flags & AC97_DSA) + if (ac97_codecs[dev->model].misc_flags & AC97_DSA) i |= 0x0030; val = (val & i) | (prev & ~i); break; case 0x2a: /* Extended Audio Status/Control */ - i = dev->extid_flags & (AC97_VRA | AC97_DRA | AC97_SPDIF | AC97_VRM); - if (dev->extid_flags & AC97_SPDIF) + i = ac97_codecs[dev->model].extid_flags & (AC97_VRA | AC97_DRA | AC97_SPDIF | AC97_VRM); + if (ac97_codecs[dev->model].extid_flags & AC97_SPDIF) i |= AC97_SPSA_MASK << AC97_SPSA_SHIFT; - i |= (dev->powerdown_mask << 3) & 0x7800; /* multichannel powerdowns */ + i |= (ac97_codecs[dev->model].eascr_mask << 11) & 0x7800; val = (val & i) | (prev & ~i); /* Reset DAC sample rates to 48 KHz (96 KHz with DRA) if VRA is being cleared. */ @@ -343,57 +351,57 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) case 0x32: /* PCM L/R ADC Rate */ rate: /* Writable only if VRA/VRM is set. */ i = (reg >= 0x32) ? AC97_VRM : AC97_VRA; - if (!(dev->extid_flags & i)) + if (!(ac97_codecs[dev->model].extid_flags & i)) return; /* Limit to supported sample rate range. */ - if (val < dev->min_rate) - val = dev->min_rate; - else if (val > dev->max_rate) - val = dev->max_rate; + if (val < ac97_codecs[dev->model].min_rate) + val = ac97_codecs[dev->model].min_rate; + else if (val > ac97_codecs[dev->model].max_rate) + val = ac97_codecs[dev->model].max_rate; break; case 0x2e: /* PCM Surround DAC Rate */ - if (!(dev->extid_flags & AC97_SDAC)) + if (!(ac97_codecs[dev->model].extid_flags & AC97_SDAC)) return; goto rate; case 0x30: /* PCM LFE DAC Rate */ - if (!(dev->extid_flags & AC97_LDAC)) + if (!(ac97_codecs[dev->model].extid_flags & AC97_LDAC)) return; goto rate; case 0x34: /* Mic ADC Rate */ - if (!(dev->reset_flags & AC97_MICPCM)) + if (!(ac97_codecs[dev->model].reset_flags & AC97_MICPCM)) return; goto rate; case 0x36: /* Center/LFE Volume */ - if (dev->extid_flags & AC97_LDAC) + if (ac97_codecs[dev->model].extid_flags & AC97_LDAC) i |= 0xbf00; - if (dev->extid_flags & AC97_CDAC) + if (ac97_codecs[dev->model].extid_flags & AC97_CDAC) i |= 0x00bf; val &= i; /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_LFE_6B) && (val & 0x2000)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_LFE_6B) && (val & 0x2000)) val = (val & ~0x2000) | 0x1f00; - if (!(dev->misc_flags & AC97_CENTER_6B)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_CENTER_6B)) goto clamp_5b_r; break; case 0x38: /* Surround Volume */ - if (!(dev->extid_flags & AC97_SDAC)) + if (!(ac97_codecs[dev->model].extid_flags & AC97_SDAC)) return; val &= 0xbfbf; /* Convert 1xxxxx to 011111 where unsupported, per specification. */ - if (!(dev->misc_flags & AC97_SURR_6B)) + if (!(ac97_codecs[dev->model].misc_flags & AC97_SURR_6B)) goto clamp_5b; break; case 0x3a: /* S/PDIF Control */ - if (!(dev->extid_flags & AC97_SPDIF)) + if (!(ac97_codecs[dev->model].extid_flags & AC97_SPDIF)) return; break; @@ -410,32 +418,28 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) /* Get actual previous value. */ prev = dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)]; } - - i <<= 8; - /* fall-through */ + fallthrough; case 0x5a ... 0x5e: /* Vendor Reserved */ case 0x70 ... 0x7a: /* Stop if no vendor-specific registers are defined. */ - if (!dev->vendor_regs) + if (!ac97_codecs[dev->model].vendor_regs) return; /* Look for a matching vendor-specific register. */ - i |= reg; - for (j = 0; dev->vendor_regs[j].index; j++) { + for (j = 0; ac97_codecs[dev->model].vendor_regs[j].index; j++) { /* If a match was found, inject written bits. */ - if (dev->vendor_regs[j].index == i) { - val = (val & dev->vendor_regs[j].write_mask) | (prev & ~dev->vendor_regs[j].write_mask); + if ((ac97_codecs[dev->model].vendor_regs[j].page == i) && (ac97_codecs[dev->model].vendor_regs[j].index == reg)) { + val = (val & ac97_codecs[dev->model].vendor_regs[j].write_mask) | (prev & ~ac97_codecs[dev->model].vendor_regs[j].write_mask); break; } } /* No match found. */ - if (!dev->vendor_regs[j].index) + if (!ac97_codecs[dev->model].vendor_regs[j].index) return; /* Redirect a write to page 1+ to the right array, part 2. */ - i >>= 8; if (i > 0) { dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)] = val; return; @@ -445,6 +449,9 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) case 0x7c: /* Vendor ID1 */ case 0x7e: /* Vendor ID2 */ return; + + default: + break; } dev->regs[reg >> 1] = val; @@ -462,52 +469,51 @@ ac97_codec_reset(void *priv) /* Set default level and gain values. */ dev->regs[0x02 >> 1] = AC97_MUTE; - if (dev->misc_flags & AC97_AUXOUT) + if (ac97_codecs[dev->model].misc_flags & AC97_AUXOUT) dev->regs[0x04 >> 1] = AC97_MUTE; - if (dev->misc_flags & AC97_MONOOUT) + if (ac97_codecs[dev->model].misc_flags & AC97_MONOOUT) dev->regs[0x06 >> 1] = AC97_MUTE; - if (dev->misc_flags & AC97_PHONE) + if (ac97_codecs[dev->model].misc_flags & AC97_PHONE) dev->regs[0x0c >> 1] = AC97_MUTE | 0x0008; dev->regs[0x0e >> 1] = AC97_MUTE | 0x0008; /* mic */ dev->regs[0x10 >> 1] = dev->regs[0x12 >> 1] = dev->regs[0x18 >> 1] = AC97_MUTE | 0x0808; /* line in, CD, PCM out */ - if (dev->misc_flags & AC97_VIDEO) + if (ac97_codecs[dev->model].misc_flags & AC97_VIDEO) dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; - if (dev->misc_flags & AC97_AUXIN) + if (ac97_codecs[dev->model].misc_flags & AC97_AUXIN) dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; - dev->regs[0x1c >> 1] = AC97_MUTE; /* record gain */ - if (dev->reset_flags & AC97_MICPCM) + dev->regs[0x1c >> 1] = AC97_MUTE; /* record gain */ + if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) dev->regs[0x1e >> 1] = AC97_MUTE; /* mic record gain */ - if (dev->misc_flags & AC97_LDAC) + if (ac97_codecs[dev->model].misc_flags & AC97_LDAC) dev->regs[0x36 >> 1] = AC97_MUTE_L; - if (dev->misc_flags & AC97_CDAC) + if (ac97_codecs[dev->model].misc_flags & AC97_CDAC) dev->regs[0x36 >> 1] |= AC97_MUTE_R; - if (dev->misc_flags & AC97_SDAC) + if (ac97_codecs[dev->model].misc_flags & AC97_SDAC) dev->regs[0x38 >> 1] = AC97_MUTE_L | AC97_MUTE_R; /* Set flags. */ - dev->regs[0x00 >> 1] = dev->reset_flags; - dev->regs[0x26 >> 1] = 0x000f; /* codec ready */ - dev->regs[0x28 >> 1] = (dev->codec_id << 14) | dev->extid_flags; + dev->regs[0x00 >> 1] = ac97_codecs[dev->model].reset_flags; + dev->regs[0x26 >> 1] = 0x000f; /* codec ready */ + dev->regs[0x28 >> 1] = (dev->codec_id << 14) | ac97_codecs[dev->model].extid_flags; ac97_codec_writew(dev, 0x2a, 0x0000); /* reset variable DAC/ADC sample rates */ - i = dev->extid_flags & (AC97_CDAC | AC97_SDAC | AC97_LDAC); + i = ac97_codecs[dev->model].extid_flags & (AC97_CDAC | AC97_SDAC | AC97_LDAC); dev->regs[0x2a >> 1] |= i | (i << 5); /* any additional DACs are ready but powered down */ - if (dev->extid_flags & AC97_SPDIF) + if (ac97_codecs[dev->model].extid_flags & AC97_SPDIF) dev->regs[0x2a >> 1] |= AC97_SPCV; - if (dev->reset_flags & AC97_MICPCM) + if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) dev->regs[0x2a >> 1] |= AC97_MADC | AC97_PRL; /* Set vendor ID. */ - dev->regs[0x7c >> 1] = dev->vendor_id >> 16; - dev->regs[0x7e >> 1] = dev->vendor_id; + dev->regs[0x7c >> 1] = ac97_codecs[dev->model].device->local >> 16; + dev->regs[0x7e >> 1] = ac97_codecs[dev->model].device->local; /* Set vendor-specific registers. */ - if (dev->vendor_regs) { - for (uint16_t j = 0; dev->vendor_regs[j].index; j++) { - i = (dev->vendor_regs[j].index >> 8) & 0x000f; - if (i > 0) - dev->vendor_reg_pages[(i << 3) | (dev->vendor_regs[j].index >> 1)] = dev->vendor_regs[j].value; + if (ac97_codecs[dev->model].vendor_regs) { + for (i = 0; ac97_codecs[dev->model].vendor_regs[i].index; i++) { + if (ac97_codecs[dev->model].vendor_regs[i].page > 0) + dev->vendor_reg_pages[(ac97_codecs[dev->model].vendor_regs[i].page << 3) | (ac97_codecs[dev->model].vendor_regs[i].index >> 1)] = ac97_codecs[dev->model].vendor_regs[i].value; else - dev->regs[dev->vendor_regs[j].index >> 1] = dev->vendor_regs[j].value; + dev->regs[ac97_codecs[dev->model].vendor_regs[i].index >> 1] = ac97_codecs[dev->model].vendor_regs[i].value; } } } @@ -515,8 +521,8 @@ ac97_codec_reset(void *priv) void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r) { - ac97_codec_t *dev = (ac97_codec_t *) priv; - uint16_t val = dev->regs[reg >> 1]; + const ac97_codec_t *dev = (ac97_codec_t *) priv; + uint16_t val = dev->regs[reg >> 1]; /* Apply full mute and powerdowns. */ int full_mute = (reg < 0x36); @@ -554,7 +560,7 @@ ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r) uint32_t ac97_codec_getrate(void *priv, uint8_t reg) { - ac97_codec_t *dev = (ac97_codec_t *) priv; + const ac97_codec_t *dev = (ac97_codec_t *) priv; /* Get configured sample rate, which is always 48000 if VRA/VRM is not set. */ uint32_t ret = dev->regs[reg >> 1]; @@ -574,15 +580,18 @@ ac97_codec_init(const device_t *info) ac97_codec_t *dev = malloc(sizeof(ac97_codec_t)); memset(dev, 0, sizeof(ac97_codec_t)); - dev->vendor_id = ac97_codecs[info->local].vendor_id; - dev->min_rate = ac97_codecs[info->local].min_rate; - dev->max_rate = ac97_codecs[info->local].max_rate; - dev->reset_flags = ac97_codecs[info->local].reset_flags; - dev->extid_flags = ac97_codecs[info->local].extid_flags; - dev->misc_flags = ac97_codecs[info->local].misc_flags; - dev->powerdown_mask = ac97_codecs[info->local].powerdown_mask; - dev->vendor_regs = ac97_codecs[info->local].vendor_regs; - ac97_codec_log("AC97 Codec %d: init(%c%c%c%02X)\n", ac97_codec_id, (dev->vendor_id >> 24) & 0xff, (dev->vendor_id >> 16) & 0xff, (dev->vendor_id >> 8) & 0xff, dev->vendor_id & 0xff); + for (; dev->model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])); dev->model++) { + if (ac97_codecs[dev->model].device->local == info->local) + break; + } + if (dev->model >= (sizeof(ac97_codecs) / sizeof(ac97_codecs[0]))) { + fatal("AC97 Codec %d: Unknown ID %c%c%c%02X\n", ac97_codec_id, (uint32_t) ((info->local >> 24) & 0xff), (uint32_t) ((info->local >> 16) & 0xff), (uint32_t) ((info->local >> 8) & 0xff), (uint32_t) (info->local & 0xff)); + free(dev); + return NULL; + } + ac97_codec_log("AC97 Codec %d: init(%c%c%c%02X)\n", ac97_codec_id, + (ac97_codecs[dev->model].device->local >> 24) & 0xff, (ac97_codecs[dev->model].device->local >> 16) & 0xff, + (ac97_codecs[dev->model].device->local >> 8) & 0xff, ac97_codecs[dev->model].device->local & 0xff); /* Associate this codec to the current controller. */ if (!ac97_codec || (ac97_codec_count <= 0)) { @@ -598,20 +607,17 @@ ac97_codec_init(const device_t *info) dev->codec_id = ac97_codec_id++; /* Allocate vendor-specific register pages if required. */ - if (dev->vendor_regs) { + if (ac97_codecs[dev->model].vendor_regs) { /* Get the highest vendor-specific register page number. */ - int i; - dev->vendor_reg_page_max = 0; - for (uint16_t j = 0; dev->vendor_regs[j].index; j++) { - i = (dev->vendor_regs[j].index >> 8) & 0x000f; - if (i > dev->vendor_reg_page_max) - dev->vendor_reg_page_max = i; + for (uint16_t i = 0; ac97_codecs[dev->model].vendor_regs[i].index; i++) { + if (ac97_codecs[dev->model].vendor_regs[i].page > dev->vendor_reg_page_max) + dev->vendor_reg_page_max = ac97_codecs[dev->model].vendor_regs[i].page; } /* Allocate pages 1+. */ if (dev->vendor_reg_page_max > 0) { ac97_codec_log("AC97 Codec %d: Allocating %d vendor-specific register pages\n", dev->codec_id, dev->vendor_reg_page_max); - i = 16 * dev->vendor_reg_page_max; + int i = 16 * dev->vendor_reg_page_max; dev->vendor_reg_pages = (uint16_t *) malloc(i); memset(dev->vendor_reg_pages, 0, i); } @@ -638,12 +644,13 @@ ac97_codec_close(void *priv) } const device_t * -ac97_codec_get(int model) +ac97_codec_get(uint32_t id) { - if ((model >= 0) && (model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])))) - return ac97_codecs[model].device; - else - return &cs4297a_device; /* fallback */ + for (int i = 0; i < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])); i++) { + if (ac97_codecs[i].device->local == id) + return ac97_codecs[i].device; + } + return &tr28023_device; /* fallback */ } const device_t ad1881_device = { @@ -744,6 +751,20 @@ const device_t stac9721_device = { .config = NULL }; +const device_t tr28023_device = { + .name = "TriTech TR28023 / Creative CT1297", + .internal_name = "tr28023", + .flags = DEVICE_AC97, + .local = AC97_CODEC_TR28023, + .init = ac97_codec_init, + .close = ac97_codec_close, + .reset = ac97_codec_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t wm9701a_device = { .name = "Wolfson WM9701A", .internal_name = "wm9701a", diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index 81babc78ba..ceac42387d 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -30,38 +30,60 @@ #include <86box/snd_ac97.h> #include <86box/sound.h> #include <86box/timer.h> +#include <86box/plat_unused.h> -typedef struct { - uint8_t id, always_run; +typedef struct ac97_via_sgd_t { + uint8_t id; + uint8_t always_run; struct _ac97_via_ *dev; - uint32_t entry_ptr, sample_ptr, fifo_pos, fifo_end; + uint32_t entry_ptr; + uint32_t sample_ptr; + uint32_t fifo_pos; + uint32_t fifo_end; int32_t sample_count; - uint8_t entry_flags, fifo[32], restart; - - int16_t out_l, out_r; - int vol_l, vol_r, pos; + uint8_t entry_flags; + uint8_t fifo[32]; + uint8_t restart; + + int16_t out_l; + int16_t out_r; + int vol_l; + int vol_r; + int pos; int32_t buffer[SOUNDBUFLEN * 2]; uint64_t timer_latch; - pc_timer_t dma_timer, poll_timer; + pc_timer_t dma_timer; + pc_timer_t poll_timer; } ac97_via_sgd_t; typedef struct _ac97_via_ { - uint16_t audio_sgd_base, audio_codec_base, modem_sgd_base, modem_codec_base; - uint8_t sgd_regs[256], pcm_enabled : 1, fm_enabled : 1, vsr_enabled : 1; + uint16_t audio_sgd_base; + uint16_t audio_codec_base; + uint16_t modem_sgd_base; + uint16_t modem_codec_base; + uint8_t sgd_regs[256]; + uint8_t pcm_enabled : 1; + uint8_t fm_enabled : 1; + uint8_t vsr_enabled : 1; struct { union { uint8_t regs_codec[2][128]; uint8_t regs_linear[256]; }; } codec_shadow[2]; - int slot, irq_pin; + uint8_t pci_slot; + uint8_t irq_state; + int irq_pin; ac97_codec_t *codec[2][2]; ac97_via_sgd_t sgd[6]; - int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r; + int master_vol_l; + int master_vol_r; + int cd_vol_l; + int cd_vol_r; } ac97_via_t; #ifdef ENABLE_AC97_VIA_LOG @@ -94,15 +116,15 @@ ac97_via_set_slot(void *priv, int slot, int irq_pin) ac97_via_log("AC97 VIA: set_slot(%d, %d)\n", slot, irq_pin); - dev->slot = slot; - dev->irq_pin = irq_pin; + dev->pci_slot = slot; + dev->irq_pin = irq_pin; } uint8_t ac97_via_read_status(void *priv, uint8_t modem) { - ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t ret = 0x00; + const ac97_via_t *dev = (ac97_via_t *) priv; + uint8_t ret = 0x00; /* Flag each codec as ready if present. */ for (uint8_t i = 0; i <= 1; i++) { @@ -161,12 +183,12 @@ ac97_via_update_irqs(ac97_via_t *dev) /* Stop immediately if any flag is set. Doing it this way optimizes rising edges for the playback SGD (0 - first to be checked). */ if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) { - pci_set_irq(dev->slot, dev->irq_pin); + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); return; } } - pci_clear_irq(dev->slot, dev->irq_pin); + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); } static void @@ -188,7 +210,7 @@ ac97_via_update_codec(ac97_via_t *dev) uint8_t ac97_via_sgd_read(uint16_t addr, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; + const ac97_via_t *dev = (ac97_via_t *) priv; #ifdef ENABLE_AC97_VIA_LOG uint8_t modem = (addr & 0xff00) == dev->modem_sgd_base; #endif @@ -350,6 +372,9 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) case 0x8 ... 0xf: /* Read-only registers. */ return; + + default: + break; } } else { /* Process regular registers. */ @@ -404,6 +429,9 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) val = dev->sgd_regs[addr] | (val & 0xc0); #endif break; + + default: + break; } } @@ -441,10 +469,11 @@ ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable) uint8_t ac97_via_codec_read(uint16_t addr, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; + const ac97_via_t *dev = (ac97_via_t *) priv; + uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; + uint8_t ret = 0xff; + addr &= 0xff; - uint8_t ret = 0xff; ret = dev->codec_shadow[modem].regs_linear[addr]; @@ -676,6 +705,9 @@ ac97_via_poll_stereo(void *priv) return; } break; + + default: + break; } /* Feed silence if the FIFO is empty. */ @@ -728,9 +760,9 @@ ac97_via_get_buffer(int32_t *buffer, int len, void *priv) static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - double c; - double volume = channel ? dev->cd_vol_r : dev->cd_vol_l; + const ac97_via_t *dev = (ac97_via_t *) priv; + double c; + double volume = channel ? dev->cd_vol_r : dev->cd_vol_l; c = ((*buffer) * volume) / 65536.0; *buffer = c; @@ -753,7 +785,7 @@ ac97_via_speed_changed(void *priv) } static void * -ac97_via_init(const device_t *info) +ac97_via_init(UNUSED(const device_t *info)) { ac97_via_t *dev = malloc(sizeof(ac97_via_t)); memset(dev, 0, sizeof(ac97_via_t)); diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 2848367047..d2a05fd6f6 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -30,6 +30,7 @@ #include <86box/timer.h> #include <86box/sound.h> #include <86box/snd_ad1848.h> +#include <86box/plat_fallthrough.h> #define CS4231 0x80 #define CS4236 0x03 @@ -65,8 +66,8 @@ ad1848_updatevolmask(ad1848_t *ad1848) static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq; - uint8_t set = 0; + double freq = 0.0; + uint8_t set = 0; if (ad1848->type >= AD1848_TYPE_CS4235) { if (ad1848->xregs[11] & 0x20) { @@ -111,6 +112,9 @@ ad1848_updatefreq(ad1848_t *ad1848) case 0x20: freq /= 256 * set; break; + + default: + break; } set = 1; } @@ -143,6 +147,9 @@ ad1848_updatefreq(ad1848_t *ad1848) case 7: freq /= 2560; break; + + default: + break; } } @@ -194,12 +201,18 @@ ad1848_read(uint16_t addr, void *priv) ret = ad1848->xregs[ad1848->xindex]; } break; + + default: + break; } break; case 2: ret = ad1848->status; break; + + default: + break; } return ret; @@ -229,7 +242,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 10: if (ad1848->type < AD1848_TYPE_CS4235) break; - /* fall-through */ + fallthrough; case 8: updatefreq = 1; @@ -359,6 +372,9 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 25: return; + + default: + break; } ad1848->xregs[ad1848->xindex] = val; @@ -383,6 +399,9 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) if (ad1848->type != AD1848_TYPE_DEFAULT) return; break; + + default: + break; } ad1848->regs[ad1848->index] = val; @@ -406,6 +425,9 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848->status &= 0xfe; ad1848->regs[24] &= 0x0f; break; + + default: + break; } } @@ -561,6 +583,9 @@ ad1848_poll(void *priv) break; /* 0xe0 and 0xf0 reserved */ + + default: + break; } if (ad1848->regs[6] & 0x80) @@ -595,9 +620,9 @@ ad1848_poll(void *priv) void ad1848_filter_cd_audio(int channel, double *buffer, void *priv) { - ad1848_t *ad1848 = (ad1848_t *) priv; - double c; - double volume = channel ? ad1848->cd_vol_r : ad1848->cd_vol_l; + const ad1848_t *ad1848 = (ad1848_t *) priv; + double c; + double volume = channel ? ad1848->cd_vol_r : ad1848->cd_vol_l; c = ((*buffer) * volume) / 65536.0; *buffer = c; @@ -606,7 +631,7 @@ ad1848_filter_cd_audio(int channel, double *buffer, void *priv) void ad1848_filter_aux2(void *priv, double *out_l, double *out_r) { - ad1848_t *ad1848 = (ad1848_t *) priv; + const ad1848_t *ad1848 = (ad1848_t *) priv; if (ad1848->regs[4] & 0x80) { *out_l = 0.0; diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index d9498d5673..5d0d7c7aac 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -13,6 +13,7 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/snd_opl.h> +#include <86box/plat_unused.h> #ifdef ENABLE_ADLIB_LOG int adlib_do_log = ENABLE_ADLIB_LOG; @@ -39,22 +40,22 @@ typedef struct adlib_t { } adlib_t; static void -adlib_get_buffer(int32_t *buffer, int len, void *p) +adlib_get_buffer(int32_t *buffer, int len, void *priv) { - adlib_t *adlib = (adlib_t *) p; + adlib_t *adlib = (adlib_t *) priv; - int32_t *opl_buf = adlib->opl.update(adlib->opl.priv); + const int32_t *opl_buf = adlib->opl.update(adlib->opl.priv); for (int c = 0; c < len * 2; c++) - buffer[c] += (int32_t) opl_buf[c]; + buffer[c] += opl_buf[c]; adlib->opl.reset_buffer(adlib->opl.priv); } uint8_t -adlib_mca_read(int port, void *p) +adlib_mca_read(int port, void *priv) { - adlib_t *adlib = (adlib_t *) p; + const adlib_t *adlib = (adlib_t *) priv; adlib_log("adlib_mca_read: port=%04x\n", port); @@ -62,9 +63,9 @@ adlib_mca_read(int port, void *p) } void -adlib_mca_write(int port, uint8_t val, void *p) +adlib_mca_write(int port, uint8_t val, void *priv) { - adlib_t *adlib = (adlib_t *) p; + adlib_t *adlib = (adlib_t *) priv; if (port < 0x102) return; @@ -84,20 +85,23 @@ adlib_mca_write(int port, uint8_t val, void *p) adlib->opl.write, NULL, NULL, adlib->opl.priv); break; + + default: + break; } adlib->pos_regs[port & 7] = val; } uint8_t -adlib_mca_feedb(void *p) +adlib_mca_feedb(void *priv) { - adlib_t *adlib = (adlib_t *) p; + const adlib_t *adlib = (adlib_t *) priv; return (adlib->pos_regs[2] & 1); } void * -adlib_init(const device_t *info) +adlib_init(UNUSED(const device_t *info)) { adlib_t *adlib = malloc(sizeof(adlib_t)); memset(adlib, 0, sizeof(adlib_t)); @@ -133,9 +137,9 @@ adlib_mca_init(const device_t *info) } void -adlib_close(void *p) +adlib_close(void *priv) { - adlib_t *adlib = (adlib_t *) p; + adlib_t *adlib = (adlib_t *) priv; free(adlib); } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index c1b2c3867b..71cbbcaa6b 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -17,15 +17,18 @@ #include <86box/sound.h> #include <86box/snd_opl.h> #include <86box/snd_ym7128.h> +#include <86box/plat_unused.h> typedef struct adgold_t { int adgold_irq_status; - int irq, dma, hdma; + int irq; + int dma; uint8_t adgold_eeprom[0x1a]; uint8_t adgold_status; - int adgold_38x_state, adgold_38x_addr; + int adgold_38x_state; + int adgold_38x_addr; uint8_t adgold_38x_regs[0x1a]; int adgold_mma_addr; @@ -33,7 +36,8 @@ typedef struct adgold_t { int adgold_mma_enable[2]; uint8_t adgold_mma_fifo[2][256]; - int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2]; + int adgold_mma_fifo_start[2]; + int adgold_mma_fifo_end[2]; uint8_t adgold_mma_status; int16_t adgold_mma_out[2]; @@ -41,28 +45,42 @@ typedef struct adgold_t { pc_timer_t adgold_mma_timer_count; - uint8_t adgold_midi_ctrl, midi_queue[16]; - int midi_r, midi_w; - int uart_in, uart_out, sysex; - - struct - { - int timer0_latch, timer0_count; - int timerbase_latch, timerbase_count; - int timer1_latch, timer1_count; - int timer2_latch, timer2_count, timer2_read; - - int voice_count[2], voice_latch[2]; + uint8_t adgold_midi_ctrl; + uint8_t midi_queue[16]; + int midi_r; + int midi_w; + int uart_in; + int uart_out; + int sysex; + + struct { + int timer0_latch; + int timer0_count; + int timerbase_latch; + int timerbase_count; + int timer1_latch; + int timer1_count; + int timer2_latch; + int timer2_count; + int timer2_read; + + int voice_count[2]; + int voice_latch[2]; } adgold_mma; fm_drv_t opl; ym7128_t ym7128; - int fm_vol_l, fm_vol_r; - int samp_vol_l, samp_vol_r; - int aux_vol_l, aux_vol_r; - int vol_l, vol_r; - int treble, bass; + int fm_vol_l; + int fm_vol_r; + int samp_vol_l; + int samp_vol_r; + int aux_vol_l; + int aux_vol_r; + int vol_l; + int vol_r; + int treble; + int bass; int16_t opl_buffer[SOUNDBUFLEN * 2]; int16_t mma_buffer[2][SOUNDBUFLEN]; @@ -131,7 +149,7 @@ static int treble_cut[6] = { (int) (0.354 * 16384) /*-3 dB - filter output is at +6 dB*/ }; -void adgold_timer_poll(void *p); +void adgold_timer_poll(void *priv); void adgold_update(adgold_t *adgold); void @@ -164,18 +182,18 @@ adgold_update_irq_status(adgold_t *adgold) adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; } -void +int adgold_getsamp_dma(adgold_t *adgold, int channel) { int temp; dma_set_drq(adgold->dma, 1); if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) - return; + return 2; temp = dma_channel_read(adgold->dma); if (temp == DMA_NODATA) { - return; + return 1; } adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; @@ -189,12 +207,14 @@ adgold_getsamp_dma(adgold_t *adgold, int channel) adgold_update_irq_status(adgold); dma_set_drq(adgold->dma, 0); } + + return 0; } void -adgold_write(uint16_t addr, uint8_t val, void *p) +adgold_write(uint16_t addr, uint8_t val, void *priv) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; switch (addr & 7) { case 0: case 1: @@ -337,6 +357,9 @@ adgold_write(uint16_t addr, uint8_t val, void *p) case 0x18: adgold->adgold_mma.voice_latch[0] = 72; break; /* 7350 Hz*/ + + default: + break; } if (val & 0x80) { adgold->adgold_mma_enable[0] = 0; @@ -356,8 +379,16 @@ adgold_write(uint16_t addr, uint8_t val, void *p) adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -371,7 +402,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p) } } else { while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -438,6 +473,9 @@ adgold_write(uint16_t addr, uint8_t val, void *p) adgold_update_irq_status(adgold); } break; + + default: + break; } adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val; break; @@ -460,6 +498,9 @@ adgold_write(uint16_t addr, uint8_t val, void *p) case 0x18: adgold->adgold_mma.voice_latch[1] = 72; break; /* 7350 Hz*/ + + default: + break; } if (val & 0x80) { adgold->adgold_mma_enable[1] = 0; @@ -475,7 +516,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p) if (adgold->adgold_mma_regs[1][0xc] & 1) { while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } } } @@ -497,16 +542,22 @@ adgold_write(uint16_t addr, uint8_t val, void *p) case 0xc: adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8; break; + + default: + break; } adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val; break; + + default: + break; } } uint8_t -adgold_read(uint16_t addr, void *p) +adgold_read(uint16_t addr, void *priv) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; uint8_t temp = 0; switch (addr & 7) { @@ -547,6 +598,7 @@ adgold_read(uint16_t addr, void *p) temp = adgold->adgold_mma_status; adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/ adgold_update_irq_status(adgold); + picintc(1 << adgold->irq); break; case 5: if (adgold->adgold_mma_addr >= 0xf) @@ -585,6 +637,9 @@ adgold_read(uint16_t addr, void *p) else temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; break; + + default: + break; } return temp; } @@ -632,13 +687,20 @@ adgold_mma_poll(adgold_t *adgold, int channel) adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; adgold->adgold_mma_out[channel] = dat; break; + + default: + break; } if (adgold->adgold_mma_regs[channel][0xc] & 1) { - adgold_getsamp_dma(adgold, channel); + if (adgold_getsamp_dma(adgold, channel)) { + adgold->adgold_mma_fifo_end[channel] = 0; + adgold->adgold_mma_fifo_start[channel] = 0; + return; + } } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) { - adgold->adgold_mma_status |= 1 << channel; + adgold->adgold_mma_status |= (1 << channel); adgold_update_irq_status(adgold); } } @@ -648,10 +710,11 @@ adgold_mma_poll(adgold_t *adgold, int channel) } void -adgold_timer_poll(void *p) +adgold_timer_poll(void *priv) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; + /*A small timer period will result in hangs.*/ timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t) ((double) TIMER_USEC * 1.88964)); if (adgold->adgold_midi_ctrl & 0x3f) { @@ -716,16 +779,16 @@ adgold_timer_poll(void *p) } static void -adgold_get_buffer(int32_t *buffer, int len, void *p) +adgold_get_buffer(int32_t *buffer, int len, void *priv) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2); if (adgold_buffer == NULL) fatal("adgold_buffer = NULL"); int c; - int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); + const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { @@ -753,6 +816,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *p) break; case 6: /*Left and right channels*/ break; + + default: + break; } switch (adgold->adgold_38x_regs[0x8] & 0x18) { @@ -779,6 +845,9 @@ adgold_get_buffer(int32_t *buffer, int len, void *p) adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3); } break; + + default: + break; } for (c = 0; c < len * 2; c += 2) { @@ -829,21 +898,21 @@ adgold_get_buffer(int32_t *buffer, int len, void *p) } static void -adgold_filter_cd_audio(int channel, double *buffer, void *p) +adgold_filter_cd_audio(int channel, double *buffer, void *priv) { - adgold_t *adgold = (adgold_t *) p; - double c; - int aux = channel ? adgold->aux_vol_r : adgold->aux_vol_l; - int vol = channel ? adgold->vol_r : adgold->vol_l; + const adgold_t *adgold = (adgold_t *) priv; + double c; + int aux = channel ? adgold->aux_vol_r : adgold->aux_vol_l; + int vol = channel ? adgold->vol_r : adgold->vol_l; c = ((((*buffer) * aux) / 4096.0) * vol) / 4096.0; *buffer = c; } static void -adgold_input_msg(void *p, uint8_t *msg, uint32_t len) +adgold_input_msg(void *priv, uint8_t *msg, uint32_t len) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; if (adgold->sysex) return; @@ -861,9 +930,9 @@ adgold_input_msg(void *p, uint8_t *msg, uint32_t len) } static int -adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +adgold_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - adgold_t *adgold = (adgold_t *) p; + adgold_t *adgold = (adgold_t *) priv; if (abort) { adgold->sysex = 0; @@ -881,9 +950,9 @@ adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) } void * -adgold_init(const device_t *info) +adgold_init(UNUSED(const device_t *info)) { - FILE *f; + FILE *fp; int c; double out; adgold_t *adgold = malloc(sizeof(adgold_t)); @@ -925,7 +994,7 @@ adgold_init(const device_t *info) adgold->adgold_eeprom[0x10] = 0xff; adgold->adgold_eeprom[0x11] = 0x20; adgold->adgold_eeprom[0x12] = 0x00; - adgold->adgold_eeprom[0x13] = 0xa0; + adgold->adgold_eeprom[0x13] = 0x00; adgold->adgold_eeprom[0x14] = 0x00; adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ adgold->adgold_eeprom[0x16] = 0x00; @@ -933,11 +1002,11 @@ adgold_init(const device_t *info) adgold->adgold_eeprom[0x18] = 0x00; /* Surround */ adgold->adgold_eeprom[0x19] = 0x00; - f = nvr_fopen("adgold.bin", "rb"); - if (f) { - if (fread(adgold->adgold_eeprom, 1, 0x1a, f) != 0x1a) + fp = nvr_fopen("adgold.bin", "rb"); + if (fp) { + if (fread(adgold->adgold_eeprom, 1, 0x1a, fp) != 0x1a) fatal("adgold_init(): Error reading data\n"); - fclose(f); + fclose(fp); } adgold->adgold_status = 0xf; @@ -955,8 +1024,12 @@ adgold_init(const device_t *info) case 7: adgold->adgold_eeprom[0x13] |= 0x03; break; + + default: + break; } adgold->adgold_eeprom[0x13] |= (adgold->dma << 3); + adgold->adgold_eeprom[0x14] |= (adgold->dma << 4); memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; @@ -990,15 +1063,15 @@ adgold_init(const device_t *info) } void -adgold_close(void *p) +adgold_close(void *priv) { - FILE *f; - adgold_t *adgold = (adgold_t *) p; + FILE *fp; + adgold_t *adgold = (adgold_t *) priv; - f = nvr_fopen("adgold.bin", "wb"); - if (f) { - fwrite(adgold->adgold_eeprom, 0x1a, 1, f); - fclose(f); + fp = nvr_fopen("adgold.bin", "wb"); + if (fp) { + fwrite(adgold->adgold_eeprom, 0x1a, 1, fp); + fclose(fp); } free(adgold); diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 6b9d8d7926..1405d8769a 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -38,6 +38,7 @@ #include <86box/snd_ac97.h> #include <86box/sound.h> #include <86box/timer.h> +#include <86box/plat_unused.h> #define N 16 @@ -45,18 +46,21 @@ static float low_fir_es1371_coef[ES1371_NCoef]; -typedef struct { - uint8_t pci_command, pci_serr; +typedef struct es1371_t { + uint8_t pci_command; + uint8_t pci_serr; uint32_t base_addr; uint8_t int_line; + uint8_t irq_state; uint16_t pmcsr; - uint32_t int_ctrl, int_status, - legacy_ctrl; - void *gameport; + uint32_t int_ctrl; + uint32_t int_status; + uint32_t legacy_ctrl; + void *gameport; int mem_page; @@ -65,17 +69,22 @@ typedef struct { uint32_t sr_cir; uint16_t sr_ram[128]; - uint8_t uart_data, uart_ctrl, - uart_status, uart_res; + uint8_t uart_data; + uint8_t uart_ctrl; + uint8_t uart_status; + uint8_t uart_res; uint32_t uart_fifo[8]; - uint8_t read_fifo_pos, write_fifo_pos; + uint8_t read_fifo_pos; + uint8_t write_fifo_pos; ac97_codec_t *codec; uint32_t codec_ctrl; struct { - uint32_t addr, addr_latch; - uint16_t count, size; + uint32_t addr; + uint32_t addr_latch; + uint16_t count; + uint16_t size; uint16_t samp_ct; int curr_samp_ct; @@ -83,26 +92,36 @@ typedef struct { pc_timer_t timer; uint64_t latch; - uint32_t vf, ac; + uint32_t vf; + uint32_t ac; - int16_t buffer_l[64], buffer_r[64]; - int buffer_pos, buffer_pos_end; + int16_t buffer_l[64]; + int16_t buffer_r[64]; + int buffer_pos; + int buffer_pos_end; - int filtered_l[32], filtered_r[32]; + int filtered_l[32]; + int filtered_r[32]; int f_pos; - int16_t out_l, out_r; + int16_t out_l; + int16_t out_r; - int32_t vol_l, vol_r; + int32_t vol_l; + int32_t vol_r; } dac[2], adc; - int64_t dac_latch, dac_time; + int64_t dac_latch; + int64_t dac_time; - int master_vol_l, master_vol_r, - pcm_vol_l, pcm_vol_r, - cd_vol_l, cd_vol_r; + int master_vol_l; + int master_vol_r; + int pcm_vol_l; + int pcm_vol_r; + int cd_vol_l; + int cd_vol_r; - int card; + uint8_t pci_slot; int pos; int16_t buffer[SOUNDBUFLEN * 2]; @@ -217,9 +236,9 @@ es1371_update_irqs(es1371_t *dev) irq = 1; if (irq) - pci_set_irq(dev->card, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else - pci_clear_irq(dev->card, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } static void @@ -299,15 +318,15 @@ es1371_reset_fifo(es1371_t *dev) } static void -es1371_reset(void *p) +es1371_reset(void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; nmi = 0; /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ - dev->int_ctrl = 0xfc0f0000; + dev->int_ctrl = 0xfcff0000; /* Interrupt/Chip Select Control Register, Address 00H Addressable as longword only */ @@ -315,7 +334,7 @@ es1371_reset(void *p) /* UART Status Register, Address 09H Addressable as byte only */ - dev->uart_status = 0x00; + dev->uart_status = 0xff; /* UART Control Register, Address 09H Addressable as byte only */ @@ -323,15 +342,15 @@ es1371_reset(void *p) /* UART Reserved Register, Address 0AH Addressable as byte only */ - dev->uart_res = 0x00; + dev->uart_res = 0xff; /* Memory Page Register, Address 0CH Addressable as byte, word, longword */ - dev->mem_page = 0x00; + dev->mem_page = 0xf0; /* FIXME: hardware reads 0xfffffff0 */ /* Sample Rate Converter Interface Register, Address 10H Addressable as longword only */ - dev->sr_cir = 0x00000000; + dev->sr_cir = 0x00470000; /* CODEC Write Register, Address 14H Addressable as longword only */ @@ -339,7 +358,7 @@ es1371_reset(void *p) /* Legacy Control/Status Register, Address 18H Addressable as byte, word, longword */ - dev->legacy_ctrl = 0x0000f800; + dev->legacy_ctrl = 0x0000f801; /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ @@ -347,17 +366,17 @@ es1371_reset(void *p) /* DAC1 Channel Sample Count Register, Address 24H Addressable as word, longword */ - dev->dac[0].samp_ct = 0x00000000; + dev->dac[0].samp_ct = 0x00000000; /* FIXME: hardware reads 0x00010000 */ dev->dac[0].curr_samp_ct = 0x00000000; /* DAC2 Channel Sample Count Register, Address 28H Addressable as word, longword */ - dev->dac[1].samp_ct = 0x00000000; + dev->dac[1].samp_ct = 0x00000000; /* FIXME: hardware reads 0x00010000 */ dev->dac[1].curr_samp_ct = 0x00000000; /* ADC Channel Sample Count Register, Address 2CH Addressable as word, longword */ - dev->adc.samp_ct = 0x00000000; + dev->adc.samp_ct = 0x00000000; /* FIXME: hardware reads 0x00010000 */ dev->adc.curr_samp_ct = 0x00000000; /* DAC1 Frame Register 1, Address 30H, Memory Page 1100b @@ -429,6 +448,9 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; + + default: + break; } break; case 0x34: @@ -452,6 +474,9 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; + + default: + break; } break; case 0x38: @@ -470,6 +495,9 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; + + default: + break; } break; case 0x3c: @@ -488,8 +516,14 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; + + default: + break; } break; + + default: + break; } return ret; @@ -519,6 +553,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; + + default: + break; } break; case 0x34: @@ -543,6 +580,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; + + default: + break; } break; case 0x38: @@ -560,6 +600,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; + + default: + break; } break; case 0x3c: @@ -578,8 +621,14 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; + + default: + break; } break; + + default: + break; } if (page == 0x0e || page == 0x0f) { @@ -588,9 +637,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) } static uint8_t -es1371_inb(uint16_t port, void *p) +es1371_inb(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint8_t ret = 0xff; switch (port & 0x3f) { @@ -621,11 +670,11 @@ es1371_inb(uint16_t port, void *p) audiopci_log("[R] STATUS 8-15 = %02X\n", ret); break; case 0x06: - ret = (dev->int_status >> 16) & 0x0f; + ret = (dev->int_status >> 16) & 0xff; audiopci_log("[R] STATUS 16-23 = %02X\n", ret); break; case 0x07: - ret = ((dev->int_status >> 24) & 0x03) | 0xfc; + ret = (dev->int_status >> 24) & 0xff; audiopci_log("[R] STATUS 24-31 = %02X\n", ret); break; @@ -699,9 +748,9 @@ es1371_inb(uint16_t port, void *p) } static uint16_t -es1371_inw(uint16_t port, void *p) +es1371_inw(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint16_t ret = 0xffff; switch (port & 0x3e) { @@ -780,6 +829,9 @@ es1371_inw(uint16_t port, void *p) case 0x3e: ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; break; + + default: + break; } audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); @@ -788,9 +840,9 @@ es1371_inw(uint16_t port, void *p) } static uint32_t -es1371_inl(uint16_t port, void *p) +es1371_inl(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint32_t ret = 0xffffffff; switch (port & 0x3c) { @@ -862,6 +914,9 @@ es1371_inl(uint16_t port, void *p) case 0x3c: ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); break; + + default: + break; } audiopci_log("es1371_inl: port=%04x ret=%08x\n", port, ret); @@ -869,9 +924,9 @@ es1371_inl(uint16_t port, void *p) } static void -es1371_outb(uint16_t port, uint8_t val, void *p) +es1371_outb(uint16_t port, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint32_t old_legacy_ctrl; audiopci_log("es1371_outb: port=%04x val=%02x\n", port, val); @@ -989,9 +1044,9 @@ es1371_outb(uint16_t port, uint8_t val, void *p) } static void -es1371_outw(uint16_t port, uint16_t val, void *p) +es1371_outw(uint16_t port, uint16_t val, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint32_t old_legacy_ctrl; switch (port & 0x3f) { @@ -1068,13 +1123,16 @@ es1371_outw(uint16_t port, uint16_t val, void *p) case 0x2c: dev->adc.samp_ct = val; break; + + default: + break; } } static void -es1371_outl(uint16_t port, uint32_t val, void *p) +es1371_outl(uint16_t port, uint32_t val, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint32_t old_legacy_ctrl; audiopci_log("es1371_outl: port=%04x val=%08x\n", port, val); @@ -1154,6 +1212,9 @@ es1371_outl(uint16_t port, uint32_t val, void *p) case 0x7f: dev->dac[1].vol_r = (int32_t) (int16_t) (val & 0xffff); break; + + default: + break; } } break; @@ -1219,6 +1280,9 @@ es1371_outl(uint16_t port, uint32_t val, void *p) case 0x3c: es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); break; + + default: + break; } } @@ -1237,106 +1301,106 @@ capture_event(es1371_t *dev, int type, int rw, uint16_t port) } static void -capture_write_sscape(uint16_t port, uint8_t val, void *p) +capture_write_sscape(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_SSCAPE, 1, port); + capture_event(priv, LEGACY_EVENT_SSCAPE, 1, port); } static void -capture_write_codec(uint16_t port, uint8_t val, void *p) +capture_write_codec(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_CODEC, 1, port); + capture_event(priv, LEGACY_EVENT_CODEC, 1, port); } static void -capture_write_sb(uint16_t port, uint8_t val, void *p) +capture_write_sb(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_SB, 1, port); + capture_event(priv, LEGACY_EVENT_SB, 1, port); } static void -capture_write_adlib(uint16_t port, uint8_t val, void *p) +capture_write_adlib(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_ADLIB, 1, port); + capture_event(priv, LEGACY_EVENT_ADLIB, 1, port); } static void -capture_write_master_pic(uint16_t port, uint8_t val, void *p) +capture_write_master_pic(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_MASTER_PIC, 1, port); + capture_event(priv, LEGACY_EVENT_MASTER_PIC, 1, port); } static void -capture_write_master_dma(uint16_t port, uint8_t val, void *p) +capture_write_master_dma(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_MASTER_DMA, 1, port); + capture_event(priv, LEGACY_EVENT_MASTER_DMA, 1, port); } static void -capture_write_slave_pic(uint16_t port, uint8_t val, void *p) +capture_write_slave_pic(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_SLAVE_PIC, 1, port); + capture_event(priv, LEGACY_EVENT_SLAVE_PIC, 1, port); } static void -capture_write_slave_dma(uint16_t port, uint8_t val, void *p) +capture_write_slave_dma(uint16_t port, UNUSED(uint8_t val), void *priv) { - capture_event(p, LEGACY_EVENT_SLAVE_DMA, 1, port); + capture_event(priv, LEGACY_EVENT_SLAVE_DMA, 1, port); } static uint8_t -capture_read_sscape(uint16_t port, void *p) +capture_read_sscape(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_SSCAPE, 0, port); + capture_event(priv, LEGACY_EVENT_SSCAPE, 0, port); return 0xff; } static uint8_t -capture_read_codec(uint16_t port, void *p) +capture_read_codec(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_CODEC, 0, port); + capture_event(priv, LEGACY_EVENT_CODEC, 0, port); return 0xff; } static uint8_t -capture_read_sb(uint16_t port, void *p) +capture_read_sb(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_SB, 0, port); + capture_event(priv, LEGACY_EVENT_SB, 0, port); return 0xff; } static uint8_t -capture_read_adlib(uint16_t port, void *p) +capture_read_adlib(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_ADLIB, 0, port); + capture_event(priv, LEGACY_EVENT_ADLIB, 0, port); return 0xff; } static uint8_t -capture_read_master_pic(uint16_t port, void *p) +capture_read_master_pic(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_MASTER_PIC, 0, port); + capture_event(priv, LEGACY_EVENT_MASTER_PIC, 0, port); return 0xff; } static uint8_t -capture_read_master_dma(uint16_t port, void *p) +capture_read_master_dma(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_MASTER_DMA, 0, port); + capture_event(priv, LEGACY_EVENT_MASTER_DMA, 0, port); return 0xff; } static uint8_t -capture_read_slave_pic(uint16_t port, void *p) +capture_read_slave_pic(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_SLAVE_PIC, 0, port); + capture_event(priv, LEGACY_EVENT_SLAVE_PIC, 0, port); return 0xff; } static uint8_t -capture_read_slave_dma(uint16_t port, void *p) +capture_read_slave_dma(uint16_t port, void *priv) { - capture_event(p, LEGACY_EVENT_SLAVE_DMA, 0, port); + capture_event(priv, LEGACY_EVENT_SLAVE_DMA, 0, port); return 0xff; } @@ -1365,6 +1429,9 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, dev); break; + + default: + break; } } @@ -1385,6 +1452,9 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, dev); break; + + default: + break; } } @@ -1452,6 +1522,9 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, dev); break; + + default: + break; } } @@ -1472,6 +1545,9 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, dev); break; + + default: + break; } } @@ -1519,9 +1595,9 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) } static uint8_t -es1371_pci_read(int func, int addr, void *p) +es1371_pci_read(int func, int addr, void *priv) { - es1371_t *dev = (es1371_t *) p; + const es1371_t *dev = (es1371_t *) priv; if (func > 0) return 0xff; @@ -1551,7 +1627,7 @@ es1371_pci_read(int func, int addr, void *p) return 0x00; case 0x08: - return 0x08; /* Revision ID - 0x02 (datasheet, VMware) has issues with the 2001 Creative WDM driver */ + return 0x02; /* Revision ID - 0x02 is actual Ensoniq-branded ES1371 */ case 0x09: return 0x00; /* Multimedia audio device */ case 0x0a: @@ -1603,6 +1679,9 @@ es1371_pci_read(int func, int addr, void *p) return dev->pmcsr & 0xff; case 0xe1: return dev->pmcsr >> 8; + + default: + break; } return 0x00; @@ -1619,9 +1698,9 @@ es1371_io_set(es1371_t *dev, int set) } static void -es1371_pci_write(int func, int addr, uint8_t val, void *p) +es1371_pci_write(int func, int addr, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; if (func) return; @@ -1663,6 +1742,9 @@ es1371_pci_write(int func, int addr, uint8_t val, void *p) case 0xe1: dev->pmcsr = (dev->pmcsr & 0x00ff) | ((val & 0x01) << 8); break; + + default: + break; } } @@ -1748,6 +1830,9 @@ es1371_fetch(es1371_t *dev, int dac_nr) } } break; + + default: + break; } } @@ -1839,9 +1924,9 @@ es1371_update(es1371_t *dev) } static void -es1371_poll(void *p) +es1371_poll(void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; int frac; int idx; int samp1_l; @@ -1907,9 +1992,9 @@ es1371_poll(void *p) } static void -es1371_get_buffer(int32_t *buffer, int len, void *p) +es1371_get_buffer(int32_t *buffer, int len, void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; es1371_update(dev); @@ -1920,12 +2005,12 @@ es1371_get_buffer(int32_t *buffer, int len, void *p) } static void -es1371_filter_cd_audio(int channel, double *buffer, void *p) +es1371_filter_cd_audio(int channel, double *buffer, void *priv) { - es1371_t *dev = (es1371_t *) p; - double c; - int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; - int master = channel ? dev->master_vol_r : dev->master_vol_l; + const es1371_t *dev = (es1371_t *) priv; + double c; + int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; + int master = channel ? dev->master_vol_r : dev->master_vol_l; c = ((((*buffer) * cd) / 65536.0) * master) / 65536.0; *buffer = c; @@ -1969,18 +2054,18 @@ generate_es1371_filter(void) } static void -es1371_input_msg(void *p, uint8_t *msg, uint32_t len) +es1371_input_msg(void *priv, uint8_t *msg, uint32_t len) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; for (uint32_t i = 0; i < len; i++) es1371_write_fifo(dev, msg[i]); } static int -es1371_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; uint32_t i = -1; audiopci_log("Abort = %i\n", abort); @@ -2016,7 +2101,7 @@ es1371_init(const device_t *info) dev->gameport = gameport_add(&gameport_pnp_device); gameport_remap(dev->gameport, 0x200); - dev->card = pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev); + pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); @@ -2035,17 +2120,17 @@ es1371_init(const device_t *info) } static void -es1371_close(void *p) +es1371_close(void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; free(dev); } static void -es1371_speed_changed(void *p) +es1371_speed_changed(void *priv) { - es1371_t *dev = (es1371_t *) p; + es1371_t *dev = (es1371_t *) priv; dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); } @@ -2054,7 +2139,7 @@ static const device_config_t es1371_config[] = { // clang-format off { .name = "codec", - .description = "CODEC", + .description = "Codec", .type = CONFIG_SELECTION, .selection = { { @@ -2062,23 +2147,12 @@ static const device_config_t es1371_config[] = { .value = AC97_CODEC_AK4540 }, { - .description = "Crystal CS4297", - .value = AC97_CODEC_CS4297 - }, - { - .description = "Crystal CS4297A", - .value = AC97_CODEC_CS4297A + .description = "TriTech TR28023 / Creative CT1297", + .value = AC97_CODEC_TR28023 }, - { - .description = "SigmaTel STAC9708", - .value = AC97_CODEC_STAC9708 - }, - { - .description = "SigmaTel STAC9721", - .value = AC97_CODEC_STAC9721 - } + { .description = "" } }, - .default_int = AC97_CODEC_CS4297A + .default_int = AC97_CODEC_TR28023 }, { .name = "receive_input", diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index ee5c982f49..80d6685997 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -150,6 +150,7 @@ #include <86box/snd_ad1848.h> #include <86box/snd_azt2316a.h> #include <86box/snd_sb.h> +#include <86box/plat_unused.h> /*530, 11, 3 - 530=23*/ /*530, 11, 1 - 530=22*/ @@ -164,7 +165,9 @@ static int azt2316a_wss_dma[4] = { 0, 0, 1, 3 }; static int azt2316a_wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; /* W95 only uses 7-10, others may be wrong */ -// static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; +#if 0 +static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; +#endif typedef struct azt2316a_t { int type; @@ -172,10 +175,14 @@ typedef struct azt2316a_t { uint8_t wss_config; - uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + uint16_t cur_addr; + uint16_t cur_wss_addr; + uint16_t cur_mpu401_addr; int cur_irq, cur_dma; - int cur_wss_enabled, cur_wss_irq, cur_wss_dma; + int cur_wss_enabled; + int cur_wss_irq; + int cur_wss_dma; int cur_mpu401_irq; int cur_mpu401_enabled; @@ -191,10 +198,10 @@ typedef struct azt2316a_t { } azt2316a_t; static uint8_t -azt2316a_wss_read(uint16_t addr, void *p) +azt2316a_wss_read(uint16_t addr, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; - uint8_t temp; + const azt2316a_t *azt2316a = (azt2316a_t *) priv; + uint8_t temp; /* TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to 0x530 makes reading from 0x533 return 0x44, but writing 0x50 @@ -208,9 +215,9 @@ azt2316a_wss_read(uint16_t addr, void *p) } static void -azt2316a_wss_write(uint16_t addr, uint8_t val, void *p) +azt2316a_wss_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; int interrupt = 0; if (azt2316a->wss_interrupt_after_config) { @@ -231,9 +238,9 @@ azt2316a_wss_write(uint16_t addr, uint8_t val, void *p) /* generate a config word based on current settings */ static void -azt1605_create_config_word(void *p) +azt1605_create_config_word(void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; uint32_t temp = 0; /* not implemented / hardcoded */ @@ -244,8 +251,10 @@ azt1605_create_config_word(void *p) switch (azt2316a->cur_addr) { case 0x220: - /* do nothing - temp += 0 << 0; */ + // do nothing +#if 0 + temp += 0 << 0; +#endif break; case 0x240: temp += 1 << 0; @@ -258,6 +267,8 @@ azt1605_create_config_word(void *p) temp += 3 << 0; break; #endif + default: + break; } switch (azt2316a->cur_irq) { @@ -273,12 +284,17 @@ azt1605_create_config_word(void *p) case 7: temp += 1 << 11; break; + + default: + break; } switch (azt2316a->cur_wss_addr) { case 0x530: - /* do nothing - temp += 0 << 16; */ + // do nothing +#if 0 + temp += 0 << 16; +#endif break; case 0x604: temp += 1 << 16; @@ -289,6 +305,9 @@ azt1605_create_config_word(void *p) case 0xF40: temp += 3 << 16; break; + + default: + break; } if (azt2316a->cur_wss_enabled) @@ -299,12 +318,17 @@ azt1605_create_config_word(void *p) switch (azt2316a->cur_mpu401_addr) { case 0x300: - /* do nothing - temp += 0 << 2; */ + // do nothing +#if 0 + temp += 0 << 2; +#endif break; case 0x330: temp += 1 << 2; break; + + default: + break; } if (azt2316a->cur_mpu401_enabled) @@ -336,6 +360,9 @@ azt1605_create_config_word(void *p) case 7: // unused temp += 7 << 5; break; + + default: + break; } switch (cd_dma8) { @@ -352,6 +379,9 @@ azt1605_create_config_word(void *p) case 3: temp += 3 << 22; break; + + default: + break; } switch (azt2316a->cur_mpu401_irq) { @@ -367,6 +397,9 @@ azt1605_create_config_word(void *p) case 7: temp += 1 << 15; break; + + default: + break; } switch (cd_irq) { @@ -382,15 +415,18 @@ azt1605_create_config_word(void *p) case 15: temp += 1 << 21; break; + + default: + break; } azt2316a->config_word = temp; } static void -azt2316a_create_config_word(void *p) +azt2316a_create_config_word(void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; uint32_t temp = 0; /* not implemented / hardcoded */ @@ -402,14 +438,16 @@ azt2316a_create_config_word(void *p) uint8_t cd_irq = 15; if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt1605_create_config_word(p); + azt1605_create_config_word(priv); return; } switch (azt2316a->cur_addr) { case 0x220: - /* do nothing - temp += 0 << 0; */ + // do nothing +#if 0 + temp += 0 << 0; +#endif break; case 0x240: temp += 1 << 0; @@ -422,6 +460,8 @@ azt2316a_create_config_word(void *p) temp += 3 << 0; break; #endif + default: + break; } switch (azt2316a->cur_irq) { @@ -437,6 +477,9 @@ azt2316a_create_config_word(void *p) case 10: temp += 1 << 5; break; + + default: + break; } switch (azt2316a->cur_dma) { @@ -456,12 +499,17 @@ azt2316a_create_config_word(void *p) case 3: temp += 3 << 6; break; + + default: + break; } switch (azt2316a->cur_wss_addr) { case 0x530: // do nothing - // temp += 0 << 8; +#if 0 + temp += 0 << 8; +#endif break; case 0x604: temp += 1 << 8; @@ -472,6 +520,9 @@ azt2316a_create_config_word(void *p) case 0xF40: temp += 3 << 8; break; + + default: + break; } if (azt2316a->cur_wss_enabled) temp += 1 << 10; @@ -480,11 +531,16 @@ azt2316a_create_config_word(void *p) switch (azt2316a->cur_mpu401_addr) { case 0x300: // do nothing - // temp += 0 << 12; +#if 0 + temp += 0 << 12; +#endif break; case 0x330: temp += 1 << 12; break; + + default: + break; } if (azt2316a->cur_mpu401_enabled) @@ -493,7 +549,9 @@ azt2316a_create_config_word(void *p) switch (cd_addr) { case 0x310: // do nothing - // temp += 0 << 14; +#if 0 + temp += 0 << 14; +#endif break; case 0x320: temp += 1 << 14; @@ -504,11 +562,16 @@ azt2316a_create_config_word(void *p) case 0x350: temp += 3 << 14; break; + + default: + break; } switch (cd_type) { - case 0: /* disabled - do nothing + case 0: /* disabled */ + // do nothing +#if 0 temp += 0 << 16; */ +#endif break; case 1: /* panasonic */ temp += 1 << 16; @@ -531,6 +594,9 @@ azt2316a_create_config_word(void *p) case 7: /* unused */ temp += 7 << 16; break; + + default: + break; } switch (cd_dma8) { @@ -549,6 +615,9 @@ azt2316a_create_config_word(void *p) case 3: temp += 3 << 20; break; + + default: + break; } switch (cd_dma16) { @@ -565,6 +634,9 @@ azt2316a_create_config_word(void *p) case 7: temp += 3 << 22; break; + + default: + break; } switch (azt2316a->cur_mpu401_irq) { @@ -580,6 +652,9 @@ azt2316a_create_config_word(void *p) case 10: temp += 1 << 27; break; + + default: + break; } switch (cd_irq) { @@ -595,16 +670,19 @@ azt2316a_create_config_word(void *p) case 15: temp += 1 << 31; break; + + default: + break; } azt2316a->config_word = temp; } static uint8_t -azt2316a_config_read(uint16_t addr, void *p) +azt2316a_config_read(uint16_t addr, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; - uint8_t temp = 0; + const azt2316a_t *azt2316a = (azt2316a_t *) priv; + uint8_t temp = 0; /* Some WSS config here + config change enable bit (setting bit 7 and writing back) */ @@ -635,6 +713,9 @@ azt2316a_config_read(uint16_t addr, void *p) case 3: temp = (azt2316a->config_word >> 24); break; + + default: + break; } } @@ -642,9 +723,9 @@ azt2316a_config_read(uint16_t addr, void *p) } static void -azt1605_config_write(uint16_t addr, uint8_t val, void *p) +azt1605_config_write(uint16_t addr, uint8_t val, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; uint8_t temp; if (addr == (azt2316a->cur_addr + 0x404)) { @@ -731,6 +812,9 @@ azt1605_config_write(uint16_t addr, uint8_t val, void *p) break; case 3: break; + + default: + break; } /* update sbprov2 configs */ sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); @@ -743,9 +827,9 @@ azt1605_config_write(uint16_t addr, uint8_t val, void *p) } static void -azt2316a_config_write(uint16_t addr, uint8_t val, void *p) +azt2316a_config_write(uint16_t addr, uint8_t val, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; uint8_t temp; if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { @@ -839,6 +923,9 @@ azt2316a_config_write(uint16_t addr, uint8_t val, void *p) azt2316a->cur_mpu401_irq = 10; /* else undefined? */ break; + + default: + break; } /* update sbprov2 configs */ sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); @@ -852,9 +939,9 @@ azt2316a_config_write(uint16_t addr, uint8_t val, void *p) /* How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system resources!) */ void -azt2316a_enable_wss(uint8_t enable, void *p) +azt2316a_enable_wss(uint8_t enable, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; if (enable) azt2316a->cur_mode = 1; @@ -863,9 +950,9 @@ azt2316a_enable_wss(uint8_t enable, void *p) } static void -azt2316a_get_buffer(int32_t *buffer, int len, void *p) +azt2316a_get_buffer(int32_t *buffer, int len, void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; /* wss part */ ad1848_update(&azt2316a->ad1848); @@ -881,7 +968,7 @@ azt2316a_get_buffer(int32_t *buffer, int len, void *p) static void * azt_init(const device_t *info) { - FILE *f; + FILE *fp; char *fn = NULL; int i; int loaded_from_eeprom = 0; @@ -899,20 +986,20 @@ azt_init(const device_t *info) } /* config */ - f = nvr_fopen(fn, "rb"); - if (f) { + fp = nvr_fopen(fn, "rb"); + if (fp) { uint8_t checksum = 0x7f; uint8_t saved_checksum; size_t res; - res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); + res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, fp); for (i = 0; i < AZTECH_EEPROM_SIZE; i++) checksum += read_eeprom[i]; - res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); + res = fread(&saved_checksum, sizeof(saved_checksum), 1, fp); (void) res; - fclose(f); + fclose(fp); if (checksum == saved_checksum) loaded_from_eeprom = 1; @@ -1182,11 +1269,11 @@ azt_init(const device_t *info) } static void -azt_close(void *p) +azt_close(void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; char *fn = NULL; - FILE *f; + FILE *fp; uint8_t checksum = 0x7f; if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { @@ -1196,18 +1283,18 @@ azt_close(void *p) } /* always save to eeprom (recover from bad values) */ - f = nvr_fopen(fn, "wb"); - if (f) { + fp = nvr_fopen(fn, "wb"); + if (fp) { for (uint8_t i = 0; i < AZTECH_EEPROM_SIZE; i++) checksum += azt2316a->sb->dsp.azt_eeprom[i]; - fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); + fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, fp); // TODO: confirm any models saving mixer settings to EEPROM and implement reading back // TODO: should remember to save wss duplex setting if 86Box has voice recording implemented in the future? Also, default azt2316a->wss_config // TODO: azt2316a->cur_mode is not saved to EEPROM? - fwrite(&checksum, sizeof(checksum), 1, f); + fwrite(&checksum, sizeof(checksum), 1, fp); - fclose(f); + fclose(fp); } sb_close(azt2316a->sb); @@ -1217,9 +1304,9 @@ azt_close(void *p) } static void -azt_speed_changed(void *p) +azt_speed_changed(void *priv) { - azt2316a_t *azt2316a = (azt2316a_t *) p; + azt2316a_t *azt2316a = (azt2316a_t *) priv; ad1848_speed_changed(&azt2316a->ad1848); sb_speed_changed(azt2316a->sb); diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index ee37d7f26c..359563b991 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -34,6 +34,8 @@ #include <86box/gameport.h> #include <86box/nmi.h> #include <86box/ui.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> enum { /* [23:16] = reg 0F [7:0] (reg 0C [31:24]) @@ -53,37 +55,68 @@ enum { TRAP_MAX }; -typedef struct { - uint8_t id, reg, always_run, playback_enabled, channels; +typedef struct cmi8x38_dma_t { + uint8_t id; + uint8_t reg; + uint8_t always_run; + uint8_t playback_enabled; + uint8_t channels; struct _cmi8x38_ *dev; - uint32_t sample_ptr, fifo_pos, fifo_end; - int32_t frame_count_dma, frame_count_fragment, sample_count_out; - uint8_t fifo[256], restart; - - int16_t out_fl, out_fr, out_rl, out_rr, out_c, out_lfe; - int vol_l, vol_r, pos; + uint32_t sample_ptr; + uint32_t fifo_pos; + uint32_t fifo_end; + int32_t frame_count_dma; + int32_t frame_count_fragment; + int32_t sample_count_out; + uint8_t fifo[256]; + uint8_t restart; + + int16_t out_fl; + int16_t out_fr; + int16_t out_rl; + int16_t out_rr; + int16_t out_c; + int16_t out_lfe; + int vol_l; + int vol_r; + int pos; int32_t buffer[SOUNDBUFLEN * 2]; uint64_t timer_latch; double dma_latch; - pc_timer_t dma_timer, poll_timer; + pc_timer_t dma_timer; + pc_timer_t poll_timer; } cmi8x38_dma_t; typedef struct _cmi8x38_ { uint32_t type; - uint16_t io_base, sb_base, opl_base, mpu_base; - uint8_t pci_regs[256], io_regs[256]; - int slot; + uint16_t io_base; + uint16_t sb_base; + uint16_t opl_base; + uint16_t mpu_base; + uint8_t pci_regs[256]; + uint8_t io_regs[256]; + uint8_t pci_slot; + uint8_t irq_state; sb_t *sb; - void *gameport, *io_traps[TRAP_MAX]; + void *gameport; + void *io_traps[TRAP_MAX]; cmi8x38_dma_t dma[2]; - uint16_t tdma_base_addr, tdma_base_count; - int tdma_8, tdma_16, tdma_mask, prev_mask, tdma_irq_mask; - - int master_vol_l, master_vol_r, cd_vol_l, cd_vol_r; + uint16_t tdma_base_addr; + uint16_t tdma_base_count; + int tdma_8; + int tdma_16; + int tdma_mask; + int prev_mask; + int tdma_irq_mask; + + int master_vol_l; + int master_vol_r; + int cd_vol_l; + int cd_vol_r; } cmi8x38_t; #ifdef ENABLE_CMI8X38_LOG @@ -116,11 +149,11 @@ cmi8x38_update_irqs(cmi8x38_t *dev) /* Calculate and use the INTR flag. */ if (*((uint32_t *) &dev->io_regs[0x10]) & 0x0401c003) { dev->io_regs[0x13] |= 0x80; - pci_set_irq(dev->slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); cmi8x38_log("CMI8x38: Raising IRQ\n"); } else { dev->io_regs[0x13] &= ~0x80; - pci_clear_irq(dev->slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } } @@ -138,7 +171,8 @@ cmi8x38_mpu_irq_update(void *priv, int set) static int cmi8x38_mpu_irq_pending(void *priv) { - cmi8x38_t *dev = (cmi8x38_t *) priv; + const cmi8x38_t *dev = (cmi8x38_t *) priv; + return dev->io_regs[0x12] & 0x01; } @@ -307,7 +341,7 @@ cmi8x38_sb_dma_writew(void *priv, uint16_t val) } static void -cmi8x38_dma_write(uint16_t addr, uint8_t val, void *priv) +cmi8x38_dma_write(uint16_t addr, UNUSED(uint8_t val), void *priv) { cmi8x38_t *dev = (cmi8x38_t *) priv; @@ -348,7 +382,7 @@ cmi8x38_dma_write(uint16_t addr, uint8_t val, void *priv) } static void -cmi8x38_dma_mask_write(uint16_t addr, uint8_t val, void *priv) +cmi8x38_dma_mask_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv) { cmi8x38_t *dev = (cmi8x38_t *) priv; @@ -365,7 +399,7 @@ cmi8x38_dma_mask_write(uint16_t addr, uint8_t val, void *priv) } static void -cmi8338_io_trap(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +cmi8338_io_trap(UNUSED(int size), uint16_t addr, uint8_t write, uint8_t val, void *priv) { cmi8x38_t *dev = (cmi8x38_t *) priv; @@ -390,9 +424,9 @@ cmi8338_io_trap(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) static uint8_t cmi8x38_sb_mixer_read(uint16_t addr, void *priv) { - cmi8x38_t *dev = (cmi8x38_t *) priv; - sb_ct1745_mixer_t *mixer = &dev->sb->mixer_sb16; - uint8_t ret = sb_ct1745_mixer_read(addr, dev->sb); + cmi8x38_t *dev = (cmi8x38_t *) priv; + const sb_ct1745_mixer_t *mixer = &dev->sb->mixer_sb16; + uint8_t ret = sb_ct1745_mixer_read(addr, dev->sb); if (addr & 1) { if ((mixer->index == 0x0e) || (mixer->index >= 0xf0)) @@ -435,10 +469,13 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0xf8 ... 0xff: if (dev->type == CMEDIA_CMI8338) mixer->regs[mixer->index] = val; - /* fall-through */ + fallthrough; case 0xf1 ... 0xf7: return; + + default: + break; } sb_ct1745_mixer_write(addr, val, dev->sb); @@ -446,8 +483,8 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) /* No [3F:47] controls. */ mixer->input_gain_L = 0; mixer->input_gain_R = 0; - mixer->output_gain_L = (double) 1.0; - mixer->output_gain_R = (double) 1.0; + mixer->output_gain_L = 1.0; + mixer->output_gain_R = 1.0; mixer->bass_l = 8; mixer->bass_r = 8; mixer->treble_l = 8; @@ -785,9 +822,9 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) /* Force IRQ if requested. Clearing this bit is undefined. */ if (val & 0x10) - pci_set_irq(dev->slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else if ((dev->io_regs[0x17] & 0x10) && !(val & 0x10)) - pci_clear_irq(dev->slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); /* Enable or disable I/O traps. */ dev->io_regs[addr] = val; @@ -920,8 +957,8 @@ cmi8x38_remap(cmi8x38_t *dev) static uint8_t cmi8x38_pci_read(int func, int addr, void *priv) { - cmi8x38_t *dev = (cmi8x38_t *) priv; - uint8_t ret = 0xff; + const cmi8x38_t *dev = (cmi8x38_t *) priv; + uint8_t ret = 0xff; if (!func) { ret = dev->pci_regs[addr]; @@ -990,9 +1027,9 @@ cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv) static void cmi8x38_update(cmi8x38_t *dev, cmi8x38_dma_t *dma) { - sb_ct1745_mixer_t *mixer = &dev->sb->mixer_sb16; - int32_t l = (dma->out_fl * mixer->voice_l) * mixer->master_l; - int32_t r = (dma->out_fr * mixer->voice_r) * mixer->master_r; + const sb_ct1745_mixer_t *mixer = &dev->sb->mixer_sb16; + int32_t l = (dma->out_fl * mixer->voice_l) * mixer->master_l; + int32_t r = (dma->out_fr * mixer->voice_r) * mixer->master_r; for (; dma->pos < sound_pos_global; dma->pos++) { dma->buffer[dma->pos * 2] = l; @@ -1201,8 +1238,14 @@ cmi8x38_poll(void *priv) return; } break; + + default: + break; } break; + + default: + break; } /* Feed silence if the FIFO is empty. */ @@ -1429,7 +1472,7 @@ cmi8x38_init(const device_t *info) } /* Add PCI card. */ - dev->slot = pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev); + pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev, &dev->pci_slot); /* Perform initial reset. */ cmi8x38_reset(dev); diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index b451dea301..d33eba83a2 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -10,17 +10,16 @@ #include <86box/io.h> #include <86box/snd_cms.h> #include <86box/sound.h> +#include <86box/plat_unused.h> void cms_update(cms_t *cms) { for (; cms->pos < sound_pos_global; cms->pos++) { - int c; - int d; int16_t out_l = 0; int16_t out_r = 0; - for (c = 0; c < 4; c++) { + for (uint8_t c = 0; c < 4; c++) { switch (cms->noisetype[c >> 1][c & 1]) { case 0: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 256; @@ -34,11 +33,14 @@ cms_update(cms_t *cms) case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; + + default: + break; } } - for (c = 0; c < 2; c++) { + for (uint8_t c = 0; c < 2; c++) { if (cms->regs[c][0x1C] & 1) { - for (d = 0; d < 6; d++) { + for (uint8_t d = 0; d < 6; d++) { if (cms->regs[c][0x14] & (1 << d)) { if (cms->stat[c][d]) out_l += (cms->vol[c][d][0] * 90); @@ -56,7 +58,7 @@ cms_update(cms_t *cms) out_r += (cms->vol[c][d][0] * 90); } } - for (d = 0; d < 2; d++) { + for (uint8_t d = 0; d < 2; d++) { cms->noisecount[c][d] += cms->noisefreq[c][d]; while (cms->noisecount[c][d] >= 24000) { cms->noisecount[c][d] -= 24000; @@ -73,9 +75,9 @@ cms_update(cms_t *cms) } void -cms_get_buffer(int32_t *buffer, int len, void *p) +cms_get_buffer(int32_t *buffer, int len, void *priv) { - cms_t *cms = (cms_t *) p; + cms_t *cms = (cms_t *) priv; cms_update(cms); @@ -86,9 +88,9 @@ cms_get_buffer(int32_t *buffer, int len, void *p) } void -cms_write(uint16_t addr, uint8_t val, void *p) +cms_write(uint16_t addr, uint8_t val, void *priv) { - cms_t *cms = (cms_t *) p; + cms_t *cms = (cms_t *) priv; int voice; int chip = (addr & 2) >> 1; @@ -138,19 +140,25 @@ cms_write(uint16_t addr, uint8_t val, void *p) cms->noisetype[chip][0] = val & 3; cms->noisetype[chip][1] = (val >> 4) & 3; break; + + default: + break; } break; case 0x6: case 0x7: cms->latched_data = val; break; + + default: + break; } } uint8_t -cms_read(uint16_t addr, void *p) +cms_read(uint16_t addr, void *priv) { - cms_t *cms = (cms_t *) p; + const cms_t *cms = (cms_t *) priv; switch (addr & 0xf) { case 0x1: @@ -162,12 +170,15 @@ cms_read(uint16_t addr, void *p) case 0xa: case 0xb: return cms->latched_data; + + default: + break; } return 0xff; } void * -cms_init(const device_t *info) +cms_init(UNUSED(const device_t *info)) { cms_t *cms = malloc(sizeof(cms_t)); memset(cms, 0, sizeof(cms_t)); @@ -179,9 +190,9 @@ cms_init(const device_t *info) } void -cms_close(void *p) +cms_close(void *priv) { - cms_t *cms = (cms_t *) p; + cms_t *cms = (cms_t *) priv; free(cms); } diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 58b217fbd3..fad1d76b93 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -36,6 +36,8 @@ #include <86box/snd_ad1848.h> #include <86box/snd_opl.h> #include <86box/snd_sb.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define CRYSTAL_NOEEPROM 0x100 @@ -133,14 +135,32 @@ typedef struct cs423x_t { ad1848_t ad1848; sb_t *sb; void *gameport; - void *i2c, *eeprom; - - uint16_t wss_base, opl_base, sb_base, ctrl_base, ram_addr, eeprom_size : 11, pnp_offset; - uint8_t type, ad1848_type, regs[8], indirect_regs[16], - eeprom_data[2048], ram_data[65536], ram_dl : 2, opl_wss : 1; - char *nvr_path; - - uint8_t pnp_enable : 1, key_pos : 5, slam_enable : 1, slam_state : 2, slam_ld, slam_reg; + void *i2c; + void *eeprom; + + uint16_t wss_base; + uint16_t opl_base; + uint16_t sb_base; + uint16_t ctrl_base; + uint16_t ram_addr; + uint16_t eeprom_size : 11; + uint16_t pnp_offset; + uint8_t type; + uint8_t ad1848_type; + uint8_t regs[8]; + uint8_t indirect_regs[16]; + uint8_t eeprom_data[2048]; + uint8_t ram_data[65536]; + uint8_t ram_dl : 2; + uint8_t opl_wss : 1; + char *nvr_path; + + uint8_t pnp_enable : 1; + uint8_t key_pos : 5; + uint8_t slam_enable : 1; + uint8_t slam_state : 2; + uint8_t slam_ld; + uint8_t slam_reg; isapnp_device_config_t *slam_config; } cs423x_t; @@ -151,13 +171,13 @@ static void cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config static void cs423x_nvram(cs423x_t *dev, uint8_t save) { - FILE *f = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); - if (f) { + FILE *fp = nvr_fopen(dev->nvr_path, save ? "wb" : "rb"); + if (fp) { if (save) - fwrite(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); + fwrite(dev->eeprom_data, sizeof(dev->eeprom_data), 1, fp); else - (void) !fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f); - fclose(f); + (void) !fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, fp); + fclose(fp); } } @@ -198,6 +218,9 @@ cs423x_read(uint16_t addr, void *priv) ret |= 0x20; break; + + default: + break; } return ret; @@ -264,6 +287,9 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) dev->ad1848.wten = !!(val & 0x08); ad1848_updatevolmask(&dev->ad1848); break; + + default: + break; } dev->indirect_regs[dev->regs[3]] = val; break; @@ -274,7 +300,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) switch (val) { case 0x55: /* Disable PnP Key */ dev->pnp_enable = 0; - /* fall-through */ + fallthrough; case 0x5a: /* Update Hardware Configuration Data */ cs423x_pnp_enable(dev, 0, 1); @@ -290,6 +316,9 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 0xaa: /* Download RAM */ dev->ram_dl = 1; break; + + default: + break; } break; @@ -306,6 +335,9 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 3: /* data */ dev->ram_data[dev->ram_addr++] = val; break; + + default: + break; } break; @@ -321,13 +353,16 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 7: /* Global Status */ return; + + default: + break; } dev->regs[reg] = val; } static void -cs423x_slam_write(uint16_t addr, uint8_t val, void *priv) +cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { cs423x_t *dev = (cs423x_t *) priv; uint8_t idx; @@ -441,11 +476,17 @@ cs423x_slam_write(uint16_t addr, uint8_t val, void *priv) /* Activate or deactivate the device. */ dev->slam_config->activate = val & 0x01; break; + + default: + break; } /* Prepare for the next register, unless a two-byte read returns above. */ dev->slam_state = CRYSTAL_SLAM_INDEX; break; + + default: + break; } } @@ -467,7 +508,7 @@ cs423x_slam_enable(cs423x_t *dev, uint8_t enable) } static void -cs423x_ctxswitch_write(uint16_t addr, uint8_t val, void *priv) +cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv) { cs423x_t *dev = (cs423x_t *) priv; uint8_t ctx = (dev->regs[7] & 0x80); @@ -503,9 +544,9 @@ cs423x_ctxswitch_write(uint16_t addr, uint8_t val, void *priv) static void cs423x_get_buffer(int32_t *buffer, int len, void *priv) { - cs423x_t *dev = (cs423x_t *) priv; - int opl_wss = dev->opl_wss; - int32_t *opl_buf = NULL; + cs423x_t *dev = (cs423x_t *) priv; + int opl_wss = dev->opl_wss; + const int32_t *opl_buf = NULL; /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ ad1848_update(&dev->ad1848); @@ -542,7 +583,9 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) /* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't line up with real hardware (still listed in the POST summary and seen by software). Disable the PnP key disabling mechanism until someone figures something out. */ - // isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); +#if 0 + isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); +#endif if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) pclog("CS423x: Attempted to disable PnP key\n"); } @@ -674,6 +717,9 @@ cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv } break; + + default: + break; } } @@ -764,6 +810,9 @@ cs423x_init(const device_t *info) dev->eeprom_data[26] = 0x38; dev->nvr_path = "cs4238b.nvr"; break; + + default: + break; } /* Load EEPROM contents from file if present. */ @@ -775,6 +824,9 @@ cs423x_init(const device_t *info) dev->gameport = gameport_add(((dev->type == CRYSTAL_CS4235) || (dev->type == CRYSTAL_CS4236B)) ? &gameport_pnp_device : &gameport_pnp_6io_device); break; + + default: + break; } /* Initialize I2C bus for the EEPROM. */ diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 99a703d143..22435c0650 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -17,81 +17,90 @@ #include <86box/sound.h> #include <86box/snd_emu8k.h> #include <86box/timer.h> +#include <86box/plat_unused.h> #if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT -// #define FILTER_INITIAL +#if 0 +#define FILTER_INITIAL +#endif # define FILTER_MOOG -// #define FILTER_CONSTANT +#if 0 +#define FILTER_CONSTANT +#endif #endif #if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC -// #define RESAMPLER_LINEAR +#if 0 +#define RESAMPLER_LINEAR +#endif # define RESAMPLER_CUBIC #endif -// #define EMU8K_DEBUG_REGISTERS +#if 0 +#define EMU8K_DEBUG_REGISTERS +#endif char *PORT_NAMES[][8] = { - /* Data 0 ( 0x620/0x622) */ + /* Data 0 ( 0x620/0x622) */ { - "AWE_CPF", - "AWE_PTRX", - "AWE_CVCF", - "AWE_VTFT", - "Unk-620-4", - "Unk-620-5", - "AWE_PSST", - "AWE_CSL", - }, - /* Data 1 0xA20 */ + "AWE_CPF", + "AWE_PTRX", + "AWE_CVCF", + "AWE_VTFT", + "Unk-620-4", + "Unk-620-5", + "AWE_PSST", + "AWE_CSL", + }, + /* Data 1 0xA20 */ { - "AWE_CCCA", - 0, - /* - "AWE_HWCF4" - "AWE_HWCF5" - "AWE_HWCF6" - "AWE_HWCF7" - "AWE_SMALR" - "AWE_SMARR" - "AWE_SMALW" - "AWE_SMARW" - "AWE_SMLD" - "AWE_SMRD" - "AWE_WC" - "AWE_HWCF1" - "AWE_HWCF2" - "AWE_HWCF3" - */ - 0, //"AWE_INIT1", - 0, //"AWE_INIT3", + "AWE_CCCA", + 0, + /* + "AWE_HWCF4" + "AWE_HWCF5" + "AWE_HWCF6" + "AWE_HWCF7" + "AWE_SMALR" + "AWE_SMARR" + "AWE_SMALW" + "AWE_SMARW" + "AWE_SMLD" + "AWE_SMRD" + "AWE_WC" + "AWE_HWCF1" + "AWE_HWCF2" + "AWE_HWCF3" + */ + 0, //"AWE_INIT1", + 0, //"AWE_INIT3", "AWE_ENVVOL", - "AWE_DCYSUSV", - "AWE_ENVVAL", - "AWE_DCYSUS", - }, - /* Data 2 0xA22 */ + "AWE_DCYSUSV", + "AWE_ENVVAL", + "AWE_DCYSUS", + }, + /* Data 2 0xA22 */ { - "AWE_CCCA", - 0, - 0, //"AWE_INIT2", - 0, //"AWE_INIT4", + "AWE_CCCA", + 0, + 0, //"AWE_INIT2", + 0, //"AWE_INIT4", "AWE_ATKHLDV", - "AWE_LFO1VAL", - "AWE_ATKHLD", - "AWE_LFO2VAL", - }, - /* Data 3 0xE20 */ + "AWE_LFO1VAL", + "AWE_ATKHLD", + "AWE_LFO2VAL", + }, + /* Data 3 0xE20 */ { - "AWE_IP", - "AWE_IFATN", - "AWE_PEFE", - "AWE_FMMOD", - "AWE_TREMFRQ", - "AWE_FM2FRQ2", - 0, - 0, - }, + "AWE_IP", + "AWE_IFATN", + "AWE_PEFE", + "AWE_FMMOD", + "AWE_TREMFRQ", + "AWE_FM2FRQ2", + 0, + 0, + }, }; enum { @@ -143,13 +152,13 @@ static int32_t env_attack_to_samples[128]; * In other words, the unit of the table is the 1/21845th of a dB per sample frame, to be added or * substracted to the accumulating value_db of the envelope. */ static int32_t env_decay_to_dbs_or_oct[128] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 32, - 33, 34, 36, 38, 39, 41, 43, 45, 49, 51, 53, 55, 58, 60, 63, 66, - 69, 72, 75, 78, 82, 85, 89, 93, 97, 102, 106, 111, 116, 121, 126, 132, - 138, 144, 150, 157, 164, 171, 179, 186, 195, 203, 212, 222, 232, 243, 253, 264, - 276, 288, 301, 315, 328, 342, 358, 374, 390, 406, 425, 444, 466, 485, 506, 528, - 553, 580, 602, 634, 660, 689, 721, 755, 780, 820, 849, 897, 932, 970, 1012, 1057, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 32, + 33, 34, 36, 38, 39, 41, 43, 45, 49, 51, 53, 55, 58, 60, 63, 66, + 69, 72, 75, 78, 82, 85, 89, 93, 97, 102, 106, 111, 116, 121, 126, 132, + 138, 144, 150, 157, 164, 171, 179, 186, 195, 203, 212, 222, 232, 243, 253, 264, + 276, 288, 301, 315, 328, 342, 358, 374, 390, 406, 425, 444, 466, 485, 506, 528, + 553, 580, 602, 634, 660, 689, 721, 755, 780, 820, 849, 897, 932, 970, 1012, 1057, 1106, 1160, 1219, 1285, 1321, 1399, 1441, 1534, 1585, 1640, 1698, 1829, 1902, 1981, 2068, 2162 }; @@ -158,17 +167,19 @@ static int32_t env_decay_to_dbs_or_oct[128] = { * I tried calculating it using the instructions in awe32p10 from Judge Dredd, but the formula there * is wrong. * + */ +#if 0 static int32_t env_decay_to_millis[128] = { -0, 45120, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082, -2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507, -1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722, -691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, -345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, -172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, -86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, -43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, + 0, 45120, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082, + 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507, + 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722, + 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, + 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, + 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, + 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, + 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, }; -*/ +#endif /* Table represeting the LFO waveform (signed 16bits with 32768 max int. >> 15 to move back to +/-1 range). */ static int32_t lfotable[65536]; @@ -348,7 +359,9 @@ EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) * the card could use two oscillators (usually 31 and 32) where it would * be writing the OPL3 output, and to which, chorus and reverb could be applied to get * those effects for OPL3 sounds.*/ - // if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} +#if 0 + if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} +#endif /* This is cubic interpolation. * Not the same than 3-point interpolation, but a better approximation than linear @@ -383,9 +396,9 @@ EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) } uint16_t -emu8k_inw(uint16_t addr, void *p) +emu8k_inw(uint16_t addr, void *priv) { - emu8k_t *emu8k = (emu8k_t *) p; + emu8k_t *emu8k = (emu8k_t *) priv; uint16_t ret = 0xffff; #ifdef EMU8K_DEBUG_REGISTERS @@ -557,6 +570,9 @@ emu8k_inw(uint16_t addr, void *p) case 7: READ16(addr, emu8k->voice[emu8k->cur_voice].csl); return ret; + + default: + break; } break; @@ -611,6 +627,9 @@ emu8k_inw(uint16_t addr, void *p) | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); case 31: /*Configuration Word 3*/ return emu8k->hwcf2 & 0x1f; + + default: + break; } break; @@ -631,6 +650,9 @@ emu8k_inw(uint16_t addr, void *p) case 7: return emu8k->voice[emu8k->cur_voice].dcysus; + + default: + break; } break; @@ -690,6 +712,9 @@ emu8k_inw(uint16_t addr, void *p) the amount of calls and wait time */ case 27: /*Sample Counter ( 44Khz clock) */ return emu8k->wc; + + default: + break; } break; @@ -710,6 +735,9 @@ emu8k_inw(uint16_t addr, void *p) case 7: return emu8k->voice[emu8k->cur_voice].lfo2val; + + default: + break; } break; @@ -738,6 +766,9 @@ emu8k_inw(uint16_t addr, void *p) case 7: /*ID?*/ return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); + + default: + break; } break; @@ -749,15 +780,18 @@ emu8k_inw(uint16_t addr, void *p) * cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero.*/ random_helper = (random_helper + 1) & 0x1F; return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; + + default: + break; } emu8k_log("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); return 0xffff; } void -emu8k_outw(uint16_t addr, uint16_t val, void *p) +emu8k_outw(uint16_t addr, uint16_t val, void *priv) { - emu8k_t *emu8k = (emu8k_t *) p; + emu8k_t *emu8k = (emu8k_t *) priv; /*TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). * Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread.*/ @@ -879,6 +913,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ emu8k->voice[emu8k->cur_voice].loop_end.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; return; + + default: + break; } break; @@ -933,6 +970,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 31: emu8k->hwcf3 = val; return; + + default: + break; } break; @@ -966,17 +1006,29 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val & 0xF) / 15.0; break; - case 0xB: // emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; + case 0xB: +#if 0 + emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; +#endif break; case 0x11: emu8k->reverb_engine.reflections[1].feedback = (val & 0xF) / 15.0; break; - case 0x13: // emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; + case 0x13: +#if 0 + emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; +#endif break; case 0x19: emu8k->reverb_engine.reflections[2].feedback = (val & 0xF) / 15.0; break; - case 0x1B: // emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; + case 0x1B: +#if 0 + emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; +#endif + break; + + default: break; } } @@ -998,7 +1050,13 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 1: emu8k->reverb_engine.refl_in_amp = val & 0xFF; break; - case 3: // emu8k->reverb_engine.refl_in_amp_r = val&0xFF; + case 3: +#if 0 + emu8k->reverb_engine.refl_in_amp_r = val&0xFF; +#endif + break; + + default: break; } } @@ -1105,6 +1163,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) } } return; + + default: + break; } break; @@ -1180,6 +1241,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) EMU8K_WRITE(emu8k, emu8k->smarw, val); emu8k->smarw++; return; + + default: + break; } break; @@ -1230,17 +1294,29 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 0x1: emu8k->reverb_engine.reflections[3].feedback = (val & 0xF) / 15.0; break; - case 0x3: // emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; + case 0x3: +#if 0 + emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; +#endif break; case 0x9: emu8k->reverb_engine.reflections[4].feedback = (val & 0xF) / 15.0; break; - case 0xb: // emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; + case 0xb: +#if 0 + emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; +#endif break; case 0x11: emu8k->reverb_engine.reflections[5].feedback = (val & 0xF) / 15.0; break; - case 0x13: // emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; + case 0x13: +#if 0 + emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; +#endif + break; + + default: break; } } @@ -1261,6 +1337,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 0x1F: emu8k->reverb_engine.link_return_amp = val & 0xFF; break; + + default: + break; } } return; @@ -1346,6 +1425,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); return; + + default: + break; } break; @@ -1429,6 +1511,9 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) case 7: /*ID? I believe that this allows applications to know if the emu is in use by another application */ emu8k->id = val; return; + + default: + break; } break; @@ -1436,30 +1521,33 @@ emu8k_outw(uint16_t addr, uint16_t val, void *p) emu8k->cur_voice = (val & 31); emu8k->cur_reg = ((val >> 5) & 7); return; + + default: + break; } emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice, val); } uint8_t -emu8k_inb(uint16_t addr, void *p) +emu8k_inb(uint16_t addr, void *priv) { /* Reading a single byte is a feature that at least Impulse tracker uses, * but only on detection code and not for odd addresses.*/ if (addr & 1) - return emu8k_inw(addr & ~1, p) >> 1; - return emu8k_inw(addr, p) & 0xff; + return emu8k_inw(addr & ~1, priv) >> 1; + return emu8k_inw(addr, priv) & 0xff; } void -emu8k_outb(uint16_t addr, uint8_t val, void *p) +emu8k_outb(uint16_t addr, uint8_t val, void *priv) { /* TODO: AWE32 docs says that you cannot write in bytes, but if * an app were to use this implementation, the content of the LS Byte would be lost.*/ if (addr & 1) - emu8k_outw(addr & ~1, val << 8, p); + emu8k_outw(addr & ~1, val << 8, priv); else - emu8k_outw(addr, val, p); + emu8k_outw(addr, val, priv); } /* TODO: This is not a correct emulation, just a workalike implementation. */ @@ -1468,7 +1556,9 @@ emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, i { for (int pos = 0; pos < count; pos++) { double lfo_inter1 = chortable[engine->lfo_pos.int_address]; - // double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; +#if 0 + double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; +#endif double offset_lfo = lfo_inter1; //= lfo_inter1 + ((lfo_inter2-lfo_inter1)*engine->lfo_pos.fract_address/65536.0); offset_lfo *= engine->lfodepth_multip; @@ -1567,10 +1657,14 @@ emu8k_reverb_tail_work(emu8k_reverb_combfilter_t *comb, emu8k_reverb_combfilter_ /* store new value in delayed buffer */ comb->reflection[comb->read_pos] = in; - // output = emu8k_reverb_allpass_work(&allpasses[0],output); +#if 0 + output = emu8k_reverb_allpass_work(&allpasses[0],output); +#endif output = emu8k_reverb_diffuser_work(&allpasses[1], output); output = emu8k_reverb_diffuser_work(&allpasses[2], output); - // output = emu8k_reverb_allpass_work(&allpasses[3],output); +#if 0 + output = emu8k_reverb_allpass_work(&allpasses[3],output); +#endif if (++comb->read_pos >= comb->bufsize) comb->read_pos = 0; @@ -1636,7 +1730,7 @@ emu8k_work_reverb(int32_t *inbuf, int32_t *outbuf, emu8k_reverb_eng_t *engine, i } } void -emu8k_work_eq(int32_t *inoutbuf, int count) +emu8k_work_eq(UNUSED(int32_t *inoutbuf), UNUSED(int count)) { // TODO: Work EQ over buf } @@ -1656,9 +1750,11 @@ emu8k_vol_slide(emu8k_slide_t *slide, int32_t target) return slide->last; } -// int32_t old_pitch[32]={0}; -// int32_t old_cut[32]={0}; -// int32_t old_vol[32]={0}; +#if 0 +int32_t old_pitch[32] = { 0 }; +int32_t old_cut[32] = { 0 }; +int32_t old_vol[32] = { 0 }; +#endif void emu8k_update(emu8k_t *emu8k) { @@ -1861,6 +1957,9 @@ emu8k_update(emu8k_t *emu8k) case ENV_STOPPED: attenuation = 0x1FFFFF; break; + + default: + break; } emu8k_envelope_t *modenv = &emu_voice->mod_envelope; @@ -1912,6 +2011,9 @@ emu8k_update(emu8k_t *emu8k) modenv->state = ENV_SUSTAIN; } break; + + default: + break; } /* run lfos */ @@ -2009,11 +2111,13 @@ emu8k_update(emu8k_t *emu8k) emu_voice->ccca = (((uint32_t) emu_voice->ccca_qcontrol) << 24) | emu_voice->addr.int_address; emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; - // if ( emu_voice->cvcf_curr_volume != old_vol[c]) { - // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); - // old_vol[c]=emu_voice->cvcf_curr_volume; - // } - // pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); +#if 0 + if (emu_voice->cvcf_curr_volume != old_vol[c]) { + pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); + old_vol[c]=emu_voice->cvcf_curr_volume; + } + pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); +#endif } buf = &emu8k->buffer[emu8k->pos * 2]; @@ -2064,18 +2168,18 @@ void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) { uint32_t const BLOCK_SIZE_WORDS = 0x10000; - FILE *f; + FILE *fp; int c; double out; - f = rom_fopen("roms/sound/awe32.raw", "rb"); - if (!f) + fp = rom_fopen("roms/sound/creative/awe32.raw", "rb"); + if (!fp) fatal("AWE32.RAW not found\n"); emu8k->rom = malloc(1024 * 1024); - if (fread(emu8k->rom, 1, 1048576, f) != 1048576) + if (fread(emu8k->rom, 1, 1048576, fp) != 1048576) fatal("emu8k_init(): Error reading data\n"); - fclose(f); + fclose(fp); /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this then correct it*/ if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) { @@ -2142,8 +2246,10 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) * Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ out = 65535.0; for (c = 0; c < 0x10000; c++) { - // double db = -(c*6.0205999/65535.0)*16.0; - // out = powf(10.f,db/20.f) * 65536.0; +#if 0 + double db = -(c*6.0205999/65535.0)*16.0; + out = powf(10.f,db/20.f) * 65536.0; +#endif env_vol_db_to_vol_target[c] = (int32_t) out; /* calculated from the 65536th root of 65536 */ out /= 1.00016923970; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 9dfd7269b3..d0af5c5644 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -16,7 +16,11 @@ #include <86box/pic.h> #include <86box/sound.h> #include <86box/timer.h> -#include <86box/snd_ad1848.h> +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +# include <86box/snd_ad1848.h> +#endif +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> enum { MIDI_INT_RECEIVE = 0x01, @@ -48,28 +52,42 @@ typedef struct gus_t { int reset; int global; - uint32_t addr, dmaaddr; + uint32_t addr; + uint32_t dmaaddr; int voice; - uint32_t start[32], end[32], cur[32]; - uint32_t startx[32], endx[32], curx[32]; - int rstart[32], rend[32]; + uint32_t start[32]; + uint32_t end[32]; + uint32_t cur[32]; + uint32_t startx[32]; + uint32_t endx[32]; + uint32_t curx[32]; + int rstart[32]; + int rend[32]; int rcur[32]; uint16_t freq[32]; uint16_t rfreq[32]; uint8_t ctrl[32]; uint8_t rctrl[32]; int curvol[32]; - int pan_l[32], pan_r[32]; - int t1on, t2on; + int pan_l[32]; + int pan_r[32]; + int t1on; + int t2on; uint8_t tctrl; - uint16_t t1, t2, t1l, t2l; - uint8_t irqstatus, irqstatus2; + uint16_t t1; + uint16_t t2; + uint16_t t1l; + uint16_t t2l; + uint8_t irqstatus; + uint8_t irqstatus2; uint8_t adcommand; - int waveirqs[32], rampirqs[32]; + int waveirqs[32]; + int rampirqs[32]; int voices; uint8_t dmactrl; - int32_t out_l, out_r; + int32_t out_l; + int32_t out_r; int16_t buffer[2][SOUNDBUFLEN]; int pos; @@ -82,33 +100,53 @@ typedef struct gus_t { int irqnext; - pc_timer_t timer_1, timer_2; + uint8_t irq_state; + uint8_t midi_irq_state; + + pc_timer_t timer_1; + pc_timer_t timer_2; - int irq, dma, irq_midi; + uint8_t type; + + int irq; + int dma; + int irq_midi; + int dma2; uint16_t base; int latch_enable; - uint8_t sb_2xa, sb_2xc, sb_2xe; + uint8_t sb_2xa; + uint8_t sb_2xc; + uint8_t sb_2xe; uint8_t sb_ctrl; int sb_nmi; uint8_t reg_ctrl; - uint8_t ad_status, ad_data; + uint8_t ad_status; + uint8_t ad_data; uint8_t ad_timer_ctrl; - uint8_t midi_ctrl, midi_status, midi_queue[64], midi_data; - int midi_r, midi_w; - int uart_in, uart_out, sysex; - - uint8_t gp1, gp2; - uint16_t gp1_addr, gp2_addr; + uint8_t midi_ctrl; + uint8_t midi_status; + uint8_t midi_queue[64]; + uint8_t midi_data; + int midi_r; + int midi_w; + int uart_in; + int uart_out; + int sysex; + + uint8_t gp1; + uint8_t gp2; + uint16_t gp1_addr; + uint16_t gp2_addr; uint8_t usrr; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) uint8_t max_ctrl; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) ad1848_t ad1848; #endif } gus_t; @@ -127,13 +165,14 @@ double vol16bit[4096]; void gus_update_int_status(gus_t *gus) { - int c; - int irq_pending = 0; - int midi_irq_pending = 0; + int irq_pending = 0; + int midi_irq_pending = 0; + int intr_pending = 0; + int midi_intr_pending = 0; gus->irqstatus &= ~0x60; gus->irqstatus2 = 0xE0; - for (c = 0; c < 32; c++) { + for (uint8_t c = 0; c < 32; c++) { if (gus->waveirqs[c]) { gus->irqstatus2 = 0x60 | c; if (gus->rampirqs[c]) @@ -158,24 +197,35 @@ gus_update_int_status(gus_t *gus) midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; - if (gus->irq == gus->irq_midi && gus->irq != -1) { + if (gus->irq == gus->irq_midi) { if (irq_pending || midi_irq_pending) - picintlevel(1 << gus->irq); + intr_pending = 1; else - picintc(1 << gus->irq); + intr_pending = 0; } else { - if (gus->irq != -1) { - if (irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); - } - if (gus->irq_midi != -1) { - if (midi_irq_pending) - picintlevel(1 << gus->irq_midi); - else - picintc(1 << gus->irq_midi); - } + if (irq_pending) + intr_pending = 1; + else + intr_pending = 0; + + if (midi_irq_pending) + midi_intr_pending = 1; + else + midi_intr_pending = 0; + } + + if (gus->irq != -1) { + if (intr_pending) + picint(1 << gus->irq); + else + picintc(1 << gus->irq); + } + + if ((gus->irq_midi != -1) && (gus->irq_midi != gus->irq)) { + if (midi_intr_pending) + picint(1 << gus->irq_midi); + else + picintc(1 << gus->irq_midi); } } @@ -199,9 +249,9 @@ gus_midi_update_int_status(gus_t *gus) } void -writegus(uint16_t addr, uint8_t val, void *p) +writegus(uint16_t addr, uint8_t val, void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; int c; int d; int old; @@ -299,6 +349,9 @@ writegus(uint16_t addr, uint8_t val, void *p) gus->tctrl = val; gus_update_int_status(gus); break; + + default: + break; } break; case 0x305: /*Global high*/ @@ -374,7 +427,8 @@ writegus(uint16_t addr, uint8_t val, void *p) if (gus->voices < 14) gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); else - gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus->samp_latch = (uint64_t) (TIMER_USEC * + (1000000.0 / gusfreqs[gus->voices - 14])); break; case 0x41: /*DMA*/ @@ -384,15 +438,28 @@ writegus(uint16_t addr, uint8_t val, void *p) while (c < 65536) { int dma_result; if (val & 0x04) { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | + ((gus->dmaaddr & 0x1ffff) << 1); + + if (gus_addr < gus->gus_end_ram) + d = gus->ram[gus_addr]; + else + d = 0x00; + + if ((gus_addr + 1) < gus->gus_end_ram) + d |= (gus->ram[gus_addr + 1] << 8); + if (val & 0x80) d ^= 0x8080; dma_result = dma_channel_write(gus->dma, d); if (dma_result == DMA_NODATA) break; } else { - d = gus->ram[gus->dmaaddr]; + if (gus->dmaaddr < gus->gus_end_ram) + d = gus->ram[gus->dmaaddr]; + else + d = 0x00; + if (val & 0x80) d ^= 0x80; dma_result = dma_channel_write(gus->dma, d); @@ -400,7 +467,7 @@ writegus(uint16_t addr, uint8_t val, void *p) break; } gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; + gus->dmaaddr &= 0xfffff; c++; if (dma_result & DMA_OVER) break; @@ -414,18 +481,25 @@ writegus(uint16_t addr, uint8_t val, void *p) if (d == DMA_NODATA) break; if (val & 0x04) { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | + ((gus->dmaaddr & 0x1ffff) << 1); if (val & 0x80) d ^= 0x8080; - gus->ram[gus_addr] = d & 0xff; - gus->ram[gus_addr + 1] = (d >> 8) & 0xff; + + if (gus_addr < gus->gus_end_ram) + gus->ram[gus_addr] = d & 0xff; + + if ((gus_addr + 1) < gus->gus_end_ram) + gus->ram[gus_addr + 1] = (d >> 8) & 0xff; } else { if (val & 0x80) d ^= 0x80; - gus->ram[gus->dmaaddr] = d; + + if (gus->dmaaddr < gus->gus_end_ram) + gus->ram[gus->dmaaddr] = d; } gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; + gus->dmaaddr &= 0xfffff; c++; if (d & DMA_OVER) break; @@ -441,28 +515,20 @@ writegus(uint16_t addr, uint8_t val, void *p) break; case 0x43: /*Address low*/ - gus->addr = (gus->addr & 0xF00FF) | (val << 8); + gus->addr = (gus->addr & 0xf00ff) | (val << 8); break; case 0x44: /*Address high*/ - gus->addr = (gus->addr & 0xFFFF) | ((val << 16) & 0xF0000); + gus->addr = (gus->addr & 0x0ffff) | ((val << 16) & 0xf0000); break; case 0x45: /*Timer control*/ if (!(val & 4)) gus->irqstatus &= ~4; if (!(val & 8)) gus->irqstatus &= ~8; - if (!(val & 0x20)) { + if (!(val & 0x20)) gus->ad_status &= ~0x18; -#ifdef OLD_NMI_BEHAVIOR - nmi = 0; -#endif - } - if (!(val & 0x02)) { + if (!(val & 0x02)) gus->ad_status &= ~0x01; -#ifdef OLD_NMI_BEHAVIOR - nmi = 0; -#endif - } gus->tctrl = val; gus->sb_ctrl = val; gus_update_int_status(gus); @@ -479,12 +545,15 @@ writegus(uint16_t addr, uint8_t val, void *p) case 0x4c: /*Reset*/ gus->reset = val; break; + + default: + break; } break; case 0x307: /*DRAM access*/ if (gus->addr < gus->gus_end_ram) gus->ram[gus->addr] = val; - gus->addr &= 0xFFFFF; + gus->addr &= 0xfffff; break; case 0x208: case 0x388: @@ -538,14 +607,24 @@ writegus(uint16_t addr, uint8_t val, void *p) } else gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_setirq(&gus->ad1848, gus->irq); + if (gus->type == GUS_MAX) + ad1848_setirq(&gus->ad1848, gus->irq); #endif gus->sb_nmi = val & 0x80; } else { gus->dma = gus_dmas[val & 7]; + + if (val & 0x40) { + if (gus->dma == -1) + gus->dma = gus->dma2 = gus_dmas[(val >> 3) & 7]; + else + gus->dma2 = gus->dma; + } else + gus->dma2 = gus_dmas[(val >> 3) & 7]; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_setdma(&gus->ad1848, gus->dma); + if (gus->type == GUS_MAX) + ad1848_setdma(&gus->ad1848, gus->dma2); #endif } break; @@ -566,6 +645,9 @@ writegus(uint16_t addr, uint8_t val, void *p) break; case 6: break; + + default: + break; } break; @@ -589,7 +671,7 @@ writegus(uint16_t addr, uint8_t val, void *p) else if (gus->irq != -1) picint(1 << gus->irq); } - /*FALLTHROUGH*/ + fallthrough; case 0x20d: gus->sb_2xc = val; break; @@ -601,31 +683,38 @@ writegus(uint16_t addr, uint8_t val, void *p) break; case 0x306: case 0x706: - if (gus->dma >= 4) - val |= 0x30; - gus->max_ctrl = (val >> 6) & 1; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (val & 0x40) { - if ((val & 0xF) != ((addr >> 4) & 0xF)) { - csioport = 0x30c | ((addr >> 4) & 0xf); - io_removehandler(csioport, 4, - ad1848_read, NULL, NULL, - ad1848_write, NULL, NULL, &gus->ad1848); - csioport = 0x30c | ((val & 0xf) << 4); - io_sethandler(csioport, 4, - ad1848_read, NULL, NULL, - ad1848_write, NULL, NULL, &gus->ad1848); + if (gus->type == GUS_MAX) { + if (gus->dma >= 4) + val |= 0x10; + if (gus->dma2 >= 4) + val |= 0x20; + gus->max_ctrl = (val >> 6) & 1; + if (val & 0x40) { + if ((val & 0xF) != ((addr >> 4) & 0xF)) { + csioport = 0x30c | ((addr >> 4) & 0xf); + io_removehandler(csioport, 4, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, &gus->ad1848); + csioport = 0x30c | ((val & 0xf) << 4); + io_sethandler(csioport, 4, + ad1848_read, NULL, NULL, + ad1848_write, NULL, NULL, &gus->ad1848); + } } } #endif break; + + default: + break; } } uint8_t -readgus(uint16_t addr, void *p) +readgus(uint16_t addr, void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; uint8_t val = 0xff; uint16_t port; @@ -666,9 +755,11 @@ readgus(uint16_t addr, void *p) return val; case 0x20F: - if (gus->max_ctrl) +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + if (gus->type == GUS_MAX) val = 0x02; else +#endif val = 0x00; break; @@ -717,6 +808,9 @@ readgus(uint16_t addr, void *p) case 0x0f: val = 0xff; break; + + default: + break; } break; case 0x305: /*Global high*/ @@ -777,20 +871,23 @@ readgus(uint16_t addr, void *p) case 0x0f: val = 0xff; break; + + default: + break; } break; case 0x306: case 0x706: - if (gus->max_ctrl) +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ else +#endif val = 0xff; /*Pre 3.7 - no mixer*/ break; - break; case 0x307: /*DRAM access*/ - val = gus->ram[gus->addr]; - gus->addr &= 0xFFFFF; + gus->addr &= 0xfffff; if (gus->addr < gus->gus_end_ram) val = gus->ram[gus->addr]; else @@ -813,6 +910,9 @@ readgus(uint16_t addr, void *p) case 4: val = gus->gp2_addr; break; + + default: + break; } break; @@ -840,7 +940,7 @@ readgus(uint16_t addr, void *p) #ifdef OLD_NMI_BEHAVIOR nmi = 0; #endif - /*FALLTHROUGH*/ + fallthrough; case 0x389: val = gus->ad_data; break; @@ -848,14 +948,17 @@ readgus(uint16_t addr, void *p) case 0x20A: val = gus->adcommand; break; + + default: + break; } return val; } void -gus_poll_timer_1(void *p) +gus_poll_timer_1(void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; timer_advance_u64(&gus->timer_1, (uint64_t) (TIMER_USEC * 80)); if (gus->t1on) { @@ -879,9 +982,9 @@ gus_poll_timer_1(void *p) } void -gus_poll_timer_2(void *p) +gus_poll_timer_2(void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; timer_advance_u64(&gus->timer_2, (uint64_t) (TIMER_USEC * 320)); if (gus->t2on) { @@ -922,9 +1025,9 @@ gus_update(gus_t *gus) } void -gus_poll_wave(void *p) +gus_poll_wave(void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; uint32_t addr; int16_t v; int32_t vl; @@ -943,21 +1046,41 @@ gus_poll_wave(void *p) if (gus->ctrl[d] & 4) { addr = gus->cur[d] >> 9; addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); - vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); + if (!(gus->freq[d] >> 10)) { + /* Interpolate */ + if (((addr + 1) & 0xfffff) < gus->gus_end_ram) + vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80) * + (511 - (gus->cur[d] & 511)); + else + vl = 0; + + if (((addr + 3) & 0xfffff) < gus->gus_end_ram) + vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xfffff] ^ 0x80) - 0x80) * + (gus->cur[d] & 511); + v = vl >> 9; - } else - v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); + } else if (((addr + 1) & 0xfffff) < gus->gus_end_ram) + v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80); + else + v = 0x0000; } else { - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); - vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); + if (!(gus->freq[d] >> 10)) { + /* Interpolate */ + if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram) + vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80)) * + (511 - (gus->cur[d] & 511)); + else + vl = 0; + + if ((((gus->cur[d] >> 9) + 1) & 0xfffff) < gus->gus_end_ram) + vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xfffff] ^ 0x80) - 0x80)) * + (gus->cur[d] & 511); + v = vl >> 9; - } else - v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); + } else if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram) + v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80); + else + v = 0x0000; } if ((gus->rcur[d] >> 14) > 4095) @@ -1055,35 +1178,35 @@ gus_poll_wave(void *p) } static void -gus_get_buffer(int32_t *buffer, int len, void *p) +gus_get_buffer(int32_t *buffer, int len, void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) + if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_update(&gus->ad1848); #endif gus_update(gus); for (int c = 0; c < len * 2; c++) { #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) + if ((gus->type == GUS_MAX) && (gus->max_ctrl)) buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); #endif buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; } #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) + if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; #endif gus->pos = 0; } static void -gus_input_msg(void *p, uint8_t *msg, uint32_t len) +gus_input_msg(void *priv, uint8_t *msg, uint32_t len) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; if (gus->sysex) return; @@ -1101,9 +1224,9 @@ gus_input_msg(void *p, uint8_t *msg, uint32_t len) } static int -gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +gus_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; if (abort) { gus->sysex = 0; @@ -1120,14 +1243,113 @@ gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) return 0; } +static void +gus_reset(void *priv) +{ + gus_t *gus = (gus_t *) priv; + int c; + double out = 1.0; + + if (gus == NULL) + return; + + memset(gus->ram, 0x00, (gus->gus_end_ram)); + + for (c = 0; c < 32; c++) { + gus->ctrl[c] = 1; + gus->rctrl[c] = 1; + gus->rfreq[c] = 63 * 512; + } + + for (c = 4095; c >= 0; c--) { + vol16bit[c] = out; + out /= 1.002709201; /* 0.0235 dB Steps */ + } + + gus->voices = 14; + + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); + + gus->t1l = gus->t2l = 0xff; + + gus->global = 0; + gus->addr = 0; + gus->dmaaddr = 0; + gus->voice = 0; + memset(gus->start, 0x00, 32 * sizeof(uint32_t)); + memset(gus->end, 0x00, 32 * sizeof(uint32_t)); + memset(gus->cur, 0x00, 32 * sizeof(uint32_t)); + memset(gus->startx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->endx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->curx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->rstart, 0x00, 32 * sizeof(int)); + memset(gus->rend, 0x00, 32 * sizeof(int)); + memset(gus->rcur, 0x00, 32 * sizeof(int)); + memset(gus->freq, 0x00, 32 * sizeof(uint16_t)); + memset(gus->curvol, 0x00, 32 * sizeof(int)); + memset(gus->pan_l, 0x00, 32 * sizeof(int)); + memset(gus->pan_r, 0x00, 32 * sizeof(int)); + gus->t1on = 0; + gus->t2on = 0; + gus->tctrl = 0; + gus->t1 = 0; + gus->t2 = 0; + gus->irqstatus = 0; + gus->irqstatus2 = 0; + gus->adcommand = 0; + memset(gus->waveirqs, 0x00, 32 * sizeof(int)); + memset(gus->rampirqs, 0x00, 32 * sizeof(int)); + gus->dmactrl = 0; + + gus->uart_out = 1; + + gus->sb_2xa = 0; + gus->sb_2xc = 0; + gus->sb_2xe = 0; + gus->sb_ctrl = 0; + gus->sb_nmi = 0; + + gus->reg_ctrl = 0; + + gus->ad_status = 0; + gus->ad_data = 0; + gus->ad_timer_ctrl = 0; + + gus->midi_ctrl = 0; + gus->midi_status = 0; + memset(gus->midi_queue, 0x00, 64 * sizeof(uint8_t)); + gus->midi_data = 0; + gus->midi_r = 0; + gus->midi_w = 0; + gus->uart_in = 0; + gus->uart_out = 0; + gus->sysex = 0; + + gus->gp1 = 0; + gus->gp2 = 0; + gus->gp1_addr = 0; + gus->gp2_addr = 0; + + gus->usrr = 0; + +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) + gus->max_ctrl = 0; +#endif + + gus->irq_state = 0; + gus->midi_irq_state = 0; + + gus_update_int_status(gus); +} + void * -gus_init(const device_t *info) +gus_init(UNUSED(const device_t *info)) { int c; double out = 1.0; uint8_t gus_ram = device_get_config_int("gus_ram"); gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0, sizeof(gus_t)); + memset(gus, 0x00, sizeof(gus_t)); gus->gus_end_ram = 1 << (18 + gus_ram); gus->ram = (uint8_t *) malloc(gus->gus_end_ram); @@ -1152,6 +1374,8 @@ gus_init(const device_t *info) gus->uart_out = 1; + gus->type = device_get_config_int("type"); + gus->base = device_get_config_hex16("base"); io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); @@ -1160,11 +1384,13 @@ gus_init(const device_t *info) io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); - ad1848_setirq(&gus->ad1848, 5); - ad1848_setdma(&gus->ad1848, 3); - io_sethandler(0x10C + gus->base, 4, - ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); + if (gus->type == GUS_MAX) { + ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); + ad1848_setirq(&gus->ad1848, 5); + ad1848_setdma(&gus->ad1848, 3); + io_sethandler(0x10C + gus->base, 4, + ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); + } #endif timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); @@ -1180,18 +1406,18 @@ gus_init(const device_t *info) } void -gus_close(void *p) +gus_close(void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; free(gus->ram); free(gus); } void -gus_speed_changed(void *p) +gus_speed_changed(void *priv) { - gus_t *gus = (gus_t *) p; + gus_t *gus = (gus_t *) priv; if (gus->voices < 14) gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); @@ -1199,7 +1425,7 @@ gus_speed_changed(void *p) gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (gus->max_ctrl) + if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_speed_changed(&gus->ad1848); #endif } @@ -1305,7 +1531,7 @@ const device_t gus_device = { .local = 0, .init = gus_init, .close = gus_close, - .reset = NULL, + .reset = gus_reset, { .available = NULL }, .speed_changed = gus_speed_changed, .force_redraw = NULL, diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index c0712d8bec..8fb526f143 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -11,11 +11,13 @@ #include <86box/machine.h> #include <86box/sound.h> #include <86box/timer.h> +#include <86box/plat_unused.h> typedef struct lpt_dac_t { void *lpt; - uint8_t dac_val_l, dac_val_r; + uint8_t dac_val_l; + uint8_t dac_val_r; int is_stereo; int channel; @@ -34,9 +36,9 @@ dac_update(lpt_dac_t *lpt_dac) } static void -dac_write_data(uint8_t val, void *p) +dac_write_data(uint8_t val, void *priv) { - lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; if (lpt_dac->is_stereo) { if (lpt_dac->channel) @@ -49,24 +51,24 @@ dac_write_data(uint8_t val, void *p) } static void -dac_write_ctrl(uint8_t val, void *p) +dac_write_ctrl(uint8_t val, void *priv) { - lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; if (lpt_dac->is_stereo) lpt_dac->channel = val & 0x01; } static uint8_t -dac_read_status(void *p) +dac_read_status(UNUSED(void *priv)) { return 0x0f; } static void -dac_get_buffer(int32_t *buffer, int len, void *p) +dac_get_buffer(int32_t *buffer, int len, void *priv) { - lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; dac_update(lpt_dac); @@ -100,9 +102,9 @@ dac_stereo_init(void *lpt) return lpt_dac; } static void -dac_close(void *p) +dac_close(void *priv) { - lpt_dac_t *lpt_dac = (lpt_dac_t *) p; + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; free(lpt_dac); } diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 9ae2ffdbe5..bd794fffb8 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -11,15 +11,17 @@ #include <86box/machine.h> #include <86box/sound.h> #include <86box/timer.h> +#include <86box/plat_unused.h> typedef struct dss_t { void *lpt; uint8_t fifo[16]; - int read_idx, write_idx; + int read_idx; + int write_idx; - uint8_t dac_val, - status; + uint8_t dac_val; + uint8_t status; pc_timer_t timer; @@ -49,9 +51,9 @@ dss_update_status(dss_t *dss) } static void -dss_write_data(uint8_t val, void *p) +dss_write_data(uint8_t val, void *priv) { - dss_t *dss = (dss_t *) p; + dss_t *dss = (dss_t *) priv; if ((dss->write_idx - dss->read_idx) < 16) { dss->fifo[dss->write_idx & 15] = val; @@ -61,22 +63,23 @@ dss_write_data(uint8_t val, void *p) } static void -dss_write_ctrl(uint8_t val, void *p) +dss_write_ctrl(UNUSED(uint8_t val), UNUSED(void *priv)) { + // } static uint8_t -dss_read_status(void *p) +dss_read_status(void *priv) { - dss_t *dss = (dss_t *) p; + const dss_t *dss = (dss_t *) priv; return dss->status | 0x0f; } static void -dss_get_buffer(int32_t *buffer, int len, void *p) +dss_get_buffer(int32_t *buffer, int len, void *priv) { - dss_t *dss = (dss_t *) p; + dss_t *dss = (dss_t *) priv; int16_t val; float fval; @@ -84,7 +87,7 @@ dss_get_buffer(int32_t *buffer, int len, void *p) for (int c = 0; c < len * 2; c += 2) { fval = dss_iir((float) dss->buffer[c >> 1]); - val = (float) fval; + val = fval; buffer[c] += val; buffer[c + 1] += val; @@ -94,9 +97,9 @@ dss_get_buffer(int32_t *buffer, int len, void *p) } static void -dss_callback(void *p) +dss_callback(void *priv) { - dss_t *dss = (dss_t *) p; + dss_t *dss = (dss_t *) priv; dss_update(dss); @@ -123,9 +126,9 @@ dss_init(void *lpt) return dss; } static void -dss_close(void *p) +dss_close(void *priv) { - dss_t *dss = (dss_t *) p; + dss_t *dss = (dss_t *) priv; free(dss); } diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 0758393ccb..a8c9d3e3ce 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -10,15 +10,15 @@ * * * - * Authors: Sarah Walker, - * DOSBox Team, + * Authors: DOSBox Team, * Miran Grca, * TheCollector1995, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2008-2020 DOSBox Team. * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 TheCollector1995. */ +#include #include #include #include @@ -38,6 +38,7 @@ #include <86box/timer.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> +#include <86box/plat_unused.h> static uint32_t MPUClockBase[8] = { 48, 72, 96, 120, 144, 168, 192 }; static uint8_t cth_data[16] = { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }; @@ -52,7 +53,7 @@ int mpu401_standalone_enable = 0; static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t track); static void MPU401_EOIHandler(void *priv); -static void MPU401_EOIHandlerDispatch(void *p); +static void MPU401_EOIHandlerDispatch(void *priv); static void MPU401_NotesOff(mpu_t *mpu, int i); #ifdef ENABLE_MPU401_LOG @@ -104,12 +105,23 @@ MPU401_ReCalcClock(mpu_t *mpu) } } +static void +MPU401_ReStartClock(mpu_t *mpu) +{ + if (mpu->clock.active) { + timer_disable(&mpu->mpu401_event_callback); + timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); + } +} + static void MPU401_StartClock(mpu_t *mpu) { + mpu401_log("MPU401_StartClock(): %i, %i, %i, %i\n", mpu->clock.active, mpu->state.clock_to_host, + mpu->state.playing, (mpu->state.rec == M_RECON)); if (mpu->clock.active) return; - if (!(mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON))) + if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)) return; mpu->clock.active = 1; @@ -119,7 +131,7 @@ MPU401_StartClock(mpu_t *mpu) static void MPU401_StopClock(mpu_t *mpu) { - if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)) + if (!mpu->state.clock_to_host && !mpu->state.playing && (mpu->state.rec == M_RECOFF)) return; mpu->clock.active = 0; timer_disable(&mpu->mpu401_event_callback); @@ -132,12 +144,14 @@ MPU401_RunClock(mpu_t *mpu) timer_disable(&mpu->mpu401_event_callback); return; } - timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); - mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); + timer_advance_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); +#if 0 + mpu401_log("Next event after %" PRIu64 " us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); +#endif } static void -MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, int irq) +MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, UNUSED(int irq)) { if (mpu->state.block_ack) { mpu->state.block_ack = 0; @@ -186,7 +200,7 @@ MPU401_IRQPending(mpu_t *mpu) } static void -MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, int block) +MPU401_RecQueueBuffer(mpu_t *mpu, uint8_t *buf, uint32_t len, UNUSED(int block)) { uint32_t cnt = 0; int pos; @@ -405,32 +419,39 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) mpu->clock.measure_counter = mpu->clock.meas_old; mpu->clock.cth_counter = mpu->clock.cth_old; break; + + default: + break; } switch (val & 0xc) { /* Playing */ case 0x4: /* Stop */ - mpu->state.playing = 0; MPU401_StopClock(mpu); + mpu->state.playing = 0; for (i = 0; i < 16; i++) MPU401_NotesOff(mpu, i); mpu->filter.prchg_mask = 0; break; case 0x8: /* Start */ - mpu->state.playing = 1; MPU401_StartClock(mpu); + mpu->state.playing = 1; + MPU401_ClrQueue(mpu); + break; + + default: break; } switch (val & 0x30) { /* Recording */ case 0: /* check if it waited for MIDI RT command */ if (((val & 3) < 2) || !mpu->filter.rt_affection || (mpu->state.rec != M_RECSTB)) break; - mpu->state.rec = M_RECON; MPU401_StartClock(mpu); + mpu->state.rec = M_RECON; if (mpu->filter.prchg_mask) send_prchg = 1; break; case 0x10: /* Stop */ - mpu->state.rec = M_RECOFF; MPU401_StopClock(mpu); + mpu->state.rec = M_RECOFF; MPU401_QueueByte(mpu, MSG_MPU_ACK); MPU401_QueueByte(mpu, mpu->clock.rec_counter); MPU401_QueueByte(mpu, MSG_MPU_END); @@ -450,6 +471,9 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) MPU401_StartClock(mpu); } break; + + default: + break; } } MPU401_QueueByte(mpu, MSG_MPU_ACK); @@ -570,12 +594,12 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) mpu->filter.rt_affection = !!(val & 1); break; case 0x94: /* Clock to host */ - mpu->state.clock_to_host = 0; MPU401_StopClock(mpu); + mpu->state.clock_to_host = 0; break; case 0x95: - mpu->state.clock_to_host = 1; MPU401_StartClock(mpu); + mpu->state.clock_to_host = 1; break; case 0x96: case 0x97: /* Sysex input allow */ @@ -650,6 +674,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) case 0xc8: mpu->clock.timebase = MPUClockBase[val - 0xc2]; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); break; case 0xdf: /* Send system message */ mpu->state.wsd = 0; @@ -679,8 +704,11 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) return; break; - /* default: - mpu401_log("MPU-401:Unhandled command %X",val); */ + default: +#if 0 + mpu401_log("MPU-401:Unhandled command %X",val); +#endif + break; } MPU401_QueueByte(mpu, MSG_MPU_ACK); @@ -721,16 +749,19 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) else mpu->clock.tempo = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe1: /* Set relative tempo */ mpu->state.command_byte = 0; mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; mpu->clock.tempo_rel = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe2: /* Set gradation for relative tempo */ mpu->clock.tempo_grad = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe4: /* Set MIDI clocks for metronome ticks */ mpu->state.command_byte = 0; @@ -793,7 +824,9 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) break; case 0xf0: - /* mpu401_log("MPU-401:Illegal WSD byte\n"); */ +#if 0 + mpu401_log("MPU-401:Illegal WSD byte\n"); +#endif mpu->state.wsd = 0; mpu->state.track = mpu->state.old_track; return; @@ -900,6 +933,9 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) mpu->state.data_onoff = -1; mpu->state.cond_req = 0; break; + + default: + break; } return; } @@ -944,7 +980,9 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) if (val == 0xf9) mpu->clock.measure_counter = 0; } else { - /* mpu401_log("MPU-401:Illegal message"); */ +#if 0 + mpu401_log("MPU-401:Illegal message"); +#endif mpu->playbuf[mpu->state.track].type = T_OVERFLOW; } mpu->state.data_onoff = -1; @@ -969,6 +1007,9 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) MPU401_EOIHandler(mpu); } break; + + default: + break; } return; @@ -1022,6 +1063,9 @@ MPU401_IntelligentOut(mpu_t *mpu, uint8_t track) return; } break; + + default: + break; } if (retrigger) { midi_raw_out_byte(0x80 | chan); @@ -1054,25 +1098,6 @@ UpdateTrack(mpu_t *mpu, uint8_t track) } } -#if 0 -static void -UpdateConductor(mpu_t *mpu) -{ - if (mpu->condbuf.value[0] == 0xfc) { - mpu->condbuf.value[0] = 0; - mpu->state.conductor = 0; - mpu->state.req_mask &= ~(1 << 9); - if (mpu->state.amask == 0) - mpu->state.req_mask |= (1 << 12); - return; - } - - mpu->condbuf.vlength = 0; - mpu->condbuf.counter = 0xf0; - mpu->state.req_mask |= (1 << 9); -} -#endif - /* Updates counters and requests new data on "End of Input" */ static void MPU401_EOIHandler(void *priv) @@ -1096,16 +1121,15 @@ MPU401_EOIHandler(void *priv) if (mpu->state.rec_copy || !mpu->state.sysex_in_finished) return; + if (!mpu->state.req_mask || !mpu->clock.active) + return; + if (mpu->ext_irq_update) mpu->ext_irq_update(mpu->priv, 0); else { mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); } - if (!(mpu->state.req_mask && mpu->clock.active)) - return; - i = 0; do { if (mpu->state.req_mask & (1 << i)) { @@ -1130,7 +1154,7 @@ MPU401_EOIHandlerDispatch(void *priv) } static void -imf_write(uint16_t addr, uint8_t val, void *priv) +imf_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), UNUSED(void *priv)) { mpu401_log("IMF:Wr %4X,%X\n", addr, val); } @@ -1245,6 +1269,9 @@ mpu401_write(uint16_t addr, uint8_t val, void *priv) MPU401_WriteCommand(mpu, val); mpu401_log("Write Command (0x331) %x\n", val); break; + + default: + break; } } @@ -1269,6 +1296,9 @@ mpu401_read(uint16_t addr, void *priv) mpu401_log("Read Status (0x331) %x\n", ret); break; + + default: + break; } /* mpu401_log("MPU401 Read Port %04X, ret %x\n", addr, ret); */ @@ -1350,7 +1380,7 @@ MPU401_Event(void *priv) } } - if (MPU401_IRQPending(mpu) && mpu->state.req_mask) + if (!MPU401_IRQPending(mpu) && mpu->state.req_mask) MPU401_EOIHandler(mpu); next_event: @@ -1382,9 +1412,9 @@ MPU401_NotesOff(mpu_t *mpu, int i) /*Input handler for SysEx */ int -MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort) +MPU401_InputSysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - mpu_t *mpu = (mpu_t *) p; + mpu_t *mpu = (mpu_t *) priv; int i; uint8_t val_ff = 0xff; @@ -1437,9 +1467,9 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort) /*Input handler for MIDI*/ void -MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) +MPU401_InputMsg(void *priv, uint8_t *msg, uint32_t len) { - mpu_t *mpu = (mpu_t *) p; + mpu_t *mpu = (mpu_t *) priv; int i; int tick; static uint8_t old_msg = 0; @@ -1520,8 +1550,11 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) } } } - break; } + break; + + default: + break; } } if ((msg[0] >= 0xf0) || (mpu->state.midi_mask & (1 << chan))) { @@ -1565,6 +1598,7 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick); } MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); } mpu->clock.ticks_in = 0; } @@ -1617,9 +1651,16 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) if (mpu->filter.rt_out) midi_raw_out_rt_byte(msg[0]); break; + + default: + break; } return; } + break; + + default: + break; } } if (send_thru && mpu->midi_thru) { @@ -1728,17 +1769,17 @@ mpu401_device_add(void) } static uint8_t -mpu401_mca_read(int port, void *p) +mpu401_mca_read(int port, void *priv) { - mpu_t *mpu = (mpu_t *) p; + const mpu_t *mpu = (mpu_t *) priv; return mpu->pos_regs[port & 7]; } static void -mpu401_mca_write(int port, uint8_t val, void *p) +mpu401_mca_write(int port, uint8_t val, void *priv) { - mpu_t *mpu = (mpu_t *) p; + mpu_t *mpu = (mpu_t *) priv; uint16_t addr; if (port < 0x102) @@ -1762,7 +1803,7 @@ mpu401_mca_write(int port, uint8_t val, void *p) } static uint8_t -mpu401_mca_feedb(void *p) +mpu401_mca_feedb(UNUSED(void *priv)) { return 1; } diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 20b956b1d1..d8281ba1dd 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -125,9 +125,9 @@ typedef struct chan { uint8_t con; uint8_t alg; uint8_t ksv; - uint16_t cha, - chb; - uint8_t ch_num; + uint16_t cha; + uint16_t chb; + uint8_t ch_num; } chan_t; typedef struct wrbuf { @@ -177,12 +177,14 @@ typedef struct chip { typedef struct { nuked_t opl; - int8_t flags, pad; + int8_t flags; + int8_t pad; uint16_t port; - uint8_t status, timer_ctrl; - uint16_t timer_count[2], - timer_cur_count[2]; + uint8_t status; + uint8_t timer_ctrl; + uint16_t timer_count[2]; + uint16_t timer_cur_count[2]; pc_timer_t timers[2]; @@ -543,6 +545,9 @@ env_calc(slot_t *slot) case envelope_gen_num_release: reg_rate = slot->reg_rr; break; + + default: + break; } slot->pg_reset = reset; @@ -619,6 +624,9 @@ env_calc(slot_t *slot) if (!eg_off && !reset && shift > 0) eg_inc = 1 << (shift - 1); break; + + default: + break; } slot->eg_rout = (eg_rout + eg_inc) & 0x1ff; @@ -810,6 +818,9 @@ channel_setup_alg(chan_t *ch) ch->slots[0]->mod = &ch->slots[0]->fbmod; ch->slots[1]->mod = &ch->dev->zeromod; break; + + default: + break; } return; } @@ -867,6 +878,9 @@ channel_setup_alg(chan_t *ch) ch->out[2] = &ch->slots[1]->out; ch->out[3] = &ch->dev->zeromod; break; + + default: + break; } } else switch (ch->alg & 0x01) { @@ -887,6 +901,9 @@ channel_setup_alg(chan_t *ch) ch->out[2] = &ch->dev->zeromod; ch->out[3] = &ch->dev->zeromod; break; + + default: + break; } } @@ -1100,7 +1117,7 @@ channel_set_4op(nuked_t *dev, uint8_t data) uint16_t nuked_write_addr(void *priv, uint16_t port, uint8_t val) { - nuked_t *dev = (nuked_t *) priv; + const nuked_t *dev = (nuked_t *) priv; uint16_t addr; addr = val; @@ -1128,12 +1145,18 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val) case 0x05: dev->newm = val & 0x01; break; + + default: + break; } else switch (regm & 0x0f) { case 0x08: dev->nts = (val >> 6) & 0x01; break; + + default: + break; } break; @@ -1191,6 +1214,9 @@ nuked_write_reg(void *priv, uint16_t reg, uint8_t val) if (ad_slot[regm & 0x1f] >= 0) slot_write_e0(&dev->slot[18 * high + ad_slot[regm & 0x1f]], val); break; + + default: + break; } } @@ -1555,17 +1581,17 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv) nuked_write_reg_buffered(&dev->opl, dev->port, val); switch (dev->port) { - case 0x02: /* Timer 1 */ + case 0x002: /* Timer 1 */ dev->timer_count[0] = val; nuked_log("Timer 0 count now: %i\n", dev->timer_count[0]); break; - case 0x03: /* Timer 2 */ + case 0x003: /* Timer 2 */ dev->timer_count[1] = val; nuked_log("Timer 1 count now: %i\n", dev->timer_count[1]); break; - case 0x04: /* Timer control */ + case 0x004: /* Timer control */ if (val & CTRL_RESET) { nuked_log("Resetting timer status...\n"); dev->status &= ~STAT_TMR_OVER; @@ -1576,6 +1602,13 @@ nuked_drv_write(uint16_t port, uint8_t val, void *priv) nuked_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val); } break; + + case 0x105: + dev->opl.newm = val & 0x01; + break; + + default: + break; } } else { dev->port = nuked_write_addr(&dev->opl, port, val) & 0x01ff; @@ -1628,4 +1661,5 @@ const fm_drv_t nuked_opl_drv = { &nuked_drv_reset_buffer, &nuked_drv_set_do_cycles, NULL, + NULL, }; \ No newline at end of file diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 8390bc1ed2..0f996f6bc9 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -29,6 +29,7 @@ extern "C" { #include <86box/snd_opl.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/plat_unused.h> // Disable c99-designator to avoid the warnings in *_ymfm_device #ifdef __clang__ @@ -50,7 +51,7 @@ enum { class YMFMChipBase { public: - YMFMChipBase(uint32_t clock, fm_type type, uint32_t samplerate) + YMFMChipBase(UNUSED(uint32_t clock), fm_type type, UNUSED(uint32_t samplerate)) : m_buf_pos(0) , m_flags(0) , m_type(type) @@ -97,7 +98,7 @@ class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface { memset(m_samples, 0, sizeof(m_samples)); memset(m_oldsamples, 0, sizeof(m_oldsamples)); m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); - m_clock_us = 1000000 / (double) m_clock; + m_clock_us = 1000000.0 / (double) m_clock; m_subtract[0] = 80.0; m_subtract[1] = 320.0; m_type = type; @@ -138,7 +139,7 @@ class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface { virtual void set_clock(uint32_t clock) override { m_clock = clock; - m_clock_us = 1000000 / (double) m_clock; + m_clock_us = 1000000.0 / (double) m_clock; m_rateratio = (m_samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); ymfm_set_timer(0, m_duration_in_clocks[0]); @@ -149,12 +150,20 @@ class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface { { for (uint32_t i = 0; i < num_samples; i++) { m_chip.generate(&m_output); - if (ChipType::OUTPUTS == 1) { - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + if ((m_type == FM_YMF278B) && (sizeof(m_output.data) > (4 * sizeof(int32_t)))) { + if (ChipType::OUTPUTS == 1) { + *data++ = m_output.data[4]; + *data++ = m_output.data[4]; + } else { + *data++ = m_output.data[4]; + *data++ = m_output.data[5]; + } + } else if (ChipType::OUTPUTS == 1) { + *data++ = m_output.data[0]; + *data++ = m_output.data[0]; } else { - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - *data++ = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; + *data++ = m_output.data[0]; + *data++ = m_output.data[1 % ChipType::OUTPUTS]; } } } @@ -166,12 +175,20 @@ class YMFMChip : public YMFMChipBase, public ymfm::ymfm_interface { m_oldsamples[0] = m_samples[0]; m_oldsamples[1] = m_samples[1]; m_chip.generate(&m_output); - if (ChipType::OUTPUTS == 1) { - m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + if ((m_type == FM_YMF278B) && (sizeof(m_output.data) > (4 * sizeof(int32_t)))) { + if (ChipType::OUTPUTS == 1) { + m_samples[0] = m_output.data[4]; + m_samples[1] = m_output.data[4]; + } else { + m_samples[0] = m_output.data[4]; + m_samples[1] = m_output.data[5]; + } + } else if (ChipType::OUTPUTS == 1) { + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[0]; } else { - m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[1 % ChipType::OUTPUTS]; } m_samplecnt -= m_rateratio; } @@ -295,8 +312,8 @@ ymfm_drv_init(const device_t *info) YMFMChipBase *fm; switch (info->local) { - case FM_YM3812: default: + case FM_YM3812: fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, OPL_FREQ); break; @@ -305,11 +322,13 @@ ymfm_drv_init(const device_t *info) break; case FM_YMF289B: - fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF289B, OPL_FREQ); + /* According to the datasheet, we should be using 33868800, but YMFM appears + to cheat and does it using the same values as the YMF262. */ + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, OPL_FREQ); break; case FM_YMF278B: - fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, 48000); + fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, OPL_FREQ); break; } @@ -380,6 +399,13 @@ ymfm_drv_set_do_cycles(void *priv, int8_t do_cycles) drv->set_do_cycles(do_cycles); } +static void +ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) +{ + YMFMChipBase *drv = (YMFMChipBase *) priv; + drv->generate_resampled(data, num_samples); +} + const device_t ym3812_ymfm_device = { .name = "Yamaha YM3812 OPL2 (YMFM)", .internal_name = "ym3812_ymfm", @@ -424,7 +450,7 @@ const device_t ymf289b_ymfm_device = { const device_t ymf278b_ymfm_device = { .name = "Yamaha YMF278B OPL4 (YMFM)", - .internal_name = "ymf289b_ymfm", + .internal_name = "ymf278b_ymfm", .flags = 0, .local = FM_YMF278B, .init = ymfm_drv_init, @@ -443,6 +469,7 @@ const fm_drv_t ymfm_drv { &ymfm_drv_reset_buffer, &ymfm_drv_set_do_cycles, NULL, + ymfm_drv_generate, }; #ifdef __clang__ diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 11aea6896f..d7afca3822 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -38,6 +38,7 @@ #include <86box/snd_sb.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/plat_unused.h> static int optimc_wss_dma[4] = { 0, 0, 1, 3 }; static int optimc_wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; @@ -48,14 +49,21 @@ enum optimc_local_flags { }; typedef struct optimc_t { - uint8_t type, fm_type; + uint8_t type; + uint8_t fm_type; - uint8_t wss_config, reg_enabled; + uint8_t wss_config; + uint8_t reg_enabled; - uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + uint16_t cur_addr; + uint16_t cur_wss_addr; + uint16_t cur_mpu401_addr; - int cur_irq, cur_dma; - int cur_wss_enabled, cur_wss_irq, cur_wss_dma; + int cur_irq; + int cur_dma; + int cur_wss_enabled; + int cur_wss_irq; + int cur_wss_dma; int cur_mpu401_irq; int cur_mpu401_enabled; void *gameport; @@ -82,9 +90,9 @@ optimc_filter_opl(void *priv, double *out_l, double *out_r) } static uint8_t -optimc_wss_read(uint16_t addr, void *priv) +optimc_wss_read(UNUSED(uint16_t addr), void *priv) { - optimc_t *optimc = (optimc_t *) priv; + const optimc_t *optimc = (optimc_t *) priv; if (!(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) return 0xFF; @@ -93,7 +101,7 @@ optimc_wss_read(uint16_t addr, void *priv) } static void -optimc_wss_write(uint16_t addr, uint8_t val, void *priv) +optimc_wss_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { optimc_t *optimc = (optimc_t *) priv; @@ -105,9 +113,9 @@ optimc_wss_write(uint16_t addr, uint8_t val, void *priv) } static void -optimc_get_buffer(int32_t *buffer, int len, void *p) +optimc_get_buffer(int32_t *buffer, int len, void *priv) { - optimc_t *optimc = (optimc_t *) p; + optimc_t *optimc = (optimc_t *) priv; if (optimc->regs[3] & 0x4) return; @@ -141,9 +149,9 @@ optimc_add_opl(optimc_t *optimc) } static void -optimc_reg_write(uint16_t addr, uint8_t val, void *p) +optimc_reg_write(uint16_t addr, uint8_t val, void *priv) { - optimc_t *optimc = (optimc_t *) p; + optimc_t *optimc = (optimc_t *) priv; uint16_t idx = addr - 0xF8D; uint8_t old = optimc->regs[idx]; static uint8_t reg_enable_phase = 0; @@ -176,6 +184,9 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *p) case 3: /* WSBase = 0x604 */ optimc->cur_wss_addr = 0x604; break; + + default: + break; } io_sethandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); io_sethandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); @@ -247,6 +258,9 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *p) case 3: optimc->cur_mpu401_irq = 7; break; + + default: + break; } switch ((val >> 5) & 0x3) { case 0: @@ -261,11 +275,17 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *p) case 3: optimc->cur_mpu401_addr = 0x300; break; + + default: + break; } mpu401_change_addr(optimc->mpu, optimc->cur_mpu401_addr); mpu401_setirq(optimc->mpu, optimc->cur_mpu401_irq); } break; + + default: + break; } } if (optimc->reg_enabled) @@ -291,6 +311,9 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *p) reg_enable_phase = 1; } break; + + default: + break; } } else reg_enable_phase = 1; @@ -299,9 +322,9 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *p) } static uint8_t -optimc_reg_read(uint16_t addr, void *p) +optimc_reg_read(uint16_t addr, void *priv) { - optimc_t *optimc = (optimc_t *) p; + optimc_t *optimc = (optimc_t *) priv; uint8_t temp = 0xFF; if (optimc->reg_enabled) { @@ -316,6 +339,9 @@ optimc_reg_read(uint16_t addr, void *p) case 2: /* MC3 */ temp = (optimc->regs[2] & ~0x3) | 0x2; break; + + default: + break; } optimc->reg_enabled = 0; } @@ -398,19 +424,19 @@ optimc_init(const device_t *info) } static void -optimc_close(void *p) +optimc_close(void *priv) { - optimc_t *optimc = (optimc_t *) p; + optimc_t *optimc = (optimc_t *) priv; sb_close(optimc->sb); free(optimc->mpu); - free(p); + free(priv); } static void -optimc_speed_changed(void *p) +optimc_speed_changed(void *priv) { - optimc_t *optimc = (optimc_t *) p; + optimc_t *optimc = (optimc_t *) priv; ad1848_speed_changed(&optimc->ad1848); sb_speed_changed(optimc->sb); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 10e6bd1c49..674acfcbbe 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -20,6 +20,7 @@ #include <86box/snd_opl.h> #include <86box/snd_sb.h> #include <86box/snd_sb_dsp.h> +#include <86box/plat_unused.h> /* Original PAS uses 2 x OPL2 @@ -97,39 +98,51 @@ typedef struct pas16_t { uint16_t base; - int irq, dma; + int irq; + int dma; uint8_t audiofilt; uint8_t audio_mixer; - uint8_t compat, compat_base; + uint8_t compat; + uint8_t compat_base; uint8_t enhancedscsi; - uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; + uint8_t io_conf_1; + uint8_t io_conf_2; + uint8_t io_conf_3; + uint8_t io_conf_4; - uint8_t irq_stat, irq_ena; + uint8_t irq_stat; + uint8_t irq_ena; uint8_t pcm_ctrl; uint16_t pcm_dat; - uint16_t pcm_dat_l, pcm_dat_r; + uint16_t pcm_dat_l; + uint16_t pcm_dat_r; uint8_t sb_irqdma; int stereo_lr; - uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; + uint8_t sys_conf_1; + uint8_t sys_conf_2; + uint8_t sys_conf_3; + uint8_t sys_conf_4; - struct - { + struct { uint32_t l[3]; int64_t c[3]; pc_timer_t timer[3]; uint8_t m[3]; - uint8_t ctrl, ctrls[2]; - int wp, rm[3], wm[3]; + uint8_t ctrl; + uint8_t ctrls[2]; + int wp; + int rm[3]; + int wm[3]; uint16_t rl[3]; int thit[3]; int delay[3]; @@ -192,9 +205,9 @@ pas16_log(const char *fmt, ...) #endif static uint8_t -pas16_in(uint16_t port, void *p) +pas16_in(uint16_t port, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; uint8_t temp = 0xff; switch ((port - pas16->base) + 0x388) { case 0x388: @@ -286,15 +299,18 @@ pas16_in(uint16_t port, void *p) case 0xff8b: /*Master mode read*/ temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ break; + + default: + break; } pas16_log("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS, cpu_state.pc); return temp; } static void -pas16_out(uint16_t port, uint8_t val, void *p) +pas16_out(uint16_t port, uint8_t val, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; pas16_log("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); switch ((port - pas16->base) + 0x388) { case 0x388: @@ -409,9 +425,9 @@ pas16_out(uint16_t port, uint8_t val, void *p) } static void -pas16_pit_out(uint16_t port, uint8_t val, void *p) +pas16_pit_out(uint16_t port, uint8_t val, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; int t; switch (port & 3) { case 3: /*CTRL*/ @@ -496,6 +512,9 @@ pas16_pit_out(uint16_t port, uint8_t val, void *p) pas16->pit.l[t] |= val; pas16->pit.wm[t] = 0; break; + + default: + break; } if (!pas16->pit.l[t]) { pas16->pit.l[t] |= 0x10000; @@ -504,13 +523,16 @@ pas16_pit_out(uint16_t port, uint8_t val, void *p) timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); } break; + + default: + break; } } static uint8_t -pas16_pit_in(uint16_t port, void *p) +pas16_pit_in(uint16_t port, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; uint8_t temp = 0xff; int t = port & 3; switch (port & 3) { @@ -550,11 +572,17 @@ pas16_pit_in(uint16_t port, void *p) else pas16->pit.rm[t] = 0; break; + + default: + break; } break; case 3: /*Control*/ temp = pas16->pit.ctrl; break; + + default: + break; } return temp; } @@ -566,9 +594,9 @@ pas16_readdma(pas16_t *pas16) } static void -pas16_pcm_poll(void *p) +pas16_pcm_poll(void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; pas16_update(pas16); if (pas16->pit.m[0] & 2) { @@ -633,9 +661,9 @@ pas16_pcm_poll(void *p) } static void -pas16_out_base(uint16_t port, uint8_t val, void *p) +pas16_out_base(UNUSED(uint16_t port), uint8_t val, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); @@ -696,11 +724,11 @@ pas16_update(pas16_t *pas16) } void -pas16_get_buffer(int32_t *buffer, int len, void *p) +pas16_get_buffer(int32_t *buffer, int len, void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; - int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); + const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv); sb_dsp_update(&pas16->dsp); pas16_update(pas16); for (int c = 0; c < len * 2; c++) { @@ -715,7 +743,7 @@ pas16_get_buffer(int32_t *buffer, int len, void *p) } static void * -pas16_init(const device_t *info) +pas16_init(UNUSED(const device_t *info)) { pas16_t *pas16 = malloc(sizeof(pas16_t)); memset(pas16, 0, sizeof(pas16_t)); @@ -733,9 +761,9 @@ pas16_init(const device_t *info) } static void -pas16_close(void *p) +pas16_close(void *priv) { - pas16_t *pas16 = (pas16_t *) p; + pas16_t *pas16 = (pas16_t *) priv; free(pas16); } diff --git a/src/sound/snd_ps1.c b/src/sound/snd_ps1.c index d440af9d07..60b4515f82 100644 --- a/src/sound/snd_ps1.c +++ b/src/sound/snd_ps1.c @@ -13,15 +13,18 @@ #include <86box/sound.h> #include <86box/snd_sn76489.h> #include <86box/timer.h> +#include <86box/plat_unused.h> -typedef struct { +typedef struct ps1snd_t { sn76489_t sn76489; - uint8_t status, ctrl; + uint8_t status; + uint8_t ctrl; uint64_t timer_latch; pc_timer_t timer_count; int timer_enable; uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; + int fifo_read_idx; + int fifo_write_idx; int fifo_threshold; uint8_t dac_val; int16_t buffer[SOUNDBUFLEN]; @@ -73,6 +76,10 @@ ps1snd_read(uint16_t port, void *priv) case 6: case 7: ret = 0; + break; + + default: + break; } return ret; @@ -109,6 +116,9 @@ ps1snd_write(uint16_t port, uint8_t val, void *priv) case 4: /* almost empty */ ps1snd->fifo_threshold = val * 4; break; + + default: + break; } } @@ -154,7 +164,7 @@ ps1snd_get_buffer(int32_t *buffer, int len, void *priv) } static void * -ps1snd_init(const device_t *info) +ps1snd_init(UNUSED(const device_t *info)) { ps1snd_t *ps1snd = malloc(sizeof(ps1snd_t)); memset(ps1snd, 0x00, sizeof(ps1snd_t)); diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 705a83517b..1e6f48ae3b 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -12,6 +12,7 @@ #include <86box/sound.h> #include <86box/snd_sn76489.h> #include <86box/timer.h> +#include <86box/plat_unused.h> typedef struct pssj_t { sn76489_t sn76489; @@ -41,9 +42,9 @@ pssj_update_irq(pssj_t *pssj) } static void -pssj_write(uint16_t port, uint8_t val, void *p) +pssj_write(uint16_t port, uint8_t val, void *priv) { - pssj_t *pssj = (pssj_t *) p; + pssj_t *pssj = (pssj_t *) priv; switch (port & 3) { case 0: @@ -67,6 +68,9 @@ pssj_write(uint16_t port, uint8_t val, void *p) case 3: /*Direct DAC*/ pssj->dac_val = val; break; + + default: + break; } break; case 2: @@ -76,12 +80,15 @@ pssj_write(uint16_t port, uint8_t val, void *p) pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); pssj->amplitude = val >> 4; break; + + default: + break; } } static uint8_t -pssj_read(uint16_t port, void *p) +pssj_read(uint16_t port, void *priv) { - pssj_t *pssj = (pssj_t *) p; + const pssj_t *pssj = (pssj_t *) priv; switch (port & 3) { case 0: @@ -96,6 +103,9 @@ pssj_read(uint16_t port, void *p) return 0x80; case 3: /*Direct DAC*/ return pssj->dac_val; + + default: + break; } break; case 2: @@ -117,9 +127,9 @@ pssj_update(pssj_t *pssj) } static void -pssj_callback(void *p) +pssj_callback(void *priv) { - pssj_t *pssj = (pssj_t *) p; + pssj_t *pssj = (pssj_t *) priv; int data; pssj_update(pssj); @@ -157,6 +167,9 @@ pssj_callback(void *p) case 0xc0: pssj->dac_val = 0x80; break; + + default: + break; } pssj->wave_pos = (pssj->wave_pos + 1) & 31; } @@ -165,9 +178,9 @@ pssj_callback(void *p) } static void -pssj_get_buffer(int32_t *buffer, int len, void *p) +pssj_get_buffer(int32_t *buffer, int len, void *priv) { - pssj_t *pssj = (pssj_t *) p; + pssj_t *pssj = (pssj_t *) priv; pssj_update(pssj); @@ -178,7 +191,7 @@ pssj_get_buffer(int32_t *buffer, int len, void *p) } void * -pssj_init(const device_t *info) +pssj_init(UNUSED(const device_t *info)) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -193,7 +206,7 @@ pssj_init(const device_t *info) } void * -pssj_1e0_init(const device_t *info) +pssj_1e0_init(UNUSED(const device_t *info)) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -208,7 +221,7 @@ pssj_1e0_init(const device_t *info) } void * -pssj_isa_init(const device_t *info) +pssj_isa_init(UNUSED(const device_t *info)) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -225,9 +238,9 @@ pssj_isa_init(const device_t *info) } void -pssj_close(void *p) +pssj_close(void *priv) { - pssj_t *pssj = (pssj_t *) p; + pssj_t *pssj = (pssj_t *) priv; free(pssj); } diff --git a/src/sound/snd_resid.cc b/src/sound/snd_resid.cc index 68d9fa71ca..94bbcd5913 100644 --- a/src/sound/snd_resid.cc +++ b/src/sound/snd_resid.cc @@ -20,12 +20,16 @@ psid_t *psid; void * sid_init(void) { - // psid_t *psid; +#if 0 + psid_t *psid; +#endif sampling_method method = SAMPLE_INTERPOLATE; float cycles_per_sec = 14318180.0 / 16.0; psid = new psid_t; - // psid = (psid_t *)malloc(sizeof(sound_t)); +#if 0 + psid = (psid_t *)malloc(sizeof(sound_t)); +#endif psid->sid = new SIDFP; psid->sid->set_chip_model(MOS8580FP); @@ -42,9 +46,11 @@ sid_init(void) for (uint8_t c = 0; c < 32; c++) psid->sid->write(c, 0); - if (!psid->sid->set_sampling_parameters((float) cycles_per_sec, method, + if (!psid->sid->set_sampling_parameters(cycles_per_sec, method, (float) RESID_FREQ, 0.9 * (float) RESID_FREQ / 2.0)) { - // printf("reSID failed!\n"); +#if 0 + printf("reSID failed!\n"); +#endif } psid->sid->set_chip_model(MOS6581FP); @@ -58,17 +64,23 @@ sid_init(void) } void -sid_close(UNUSED(void *p)) +sid_close(UNUSED(void *priv)) { - // psid_t *psid = (psid_t *)p; +#if 0 + psid_t *psid = (psid_t *) priv; +#endif delete psid->sid; - // free(psid); +#if 0 + free(psid); +#endif } void -sid_reset(UNUSED(void *p)) +sid_reset(UNUSED(void *priv)) { - // psid_t *psid = (psid_t *)p; +#if 0 + psid_t *psid = (psid_t *) priv; +#endif psid->sid->reset(); @@ -77,18 +89,24 @@ sid_reset(UNUSED(void *p)) } uint8_t -sid_read(uint16_t addr, UNUSED(void *p)) +sid_read(uint16_t addr, UNUSED(void *priv)) { - // psid_t *psid = (psid_t *)p; +#if 0 + psid_t *psid = (psid_t *) priv; +#endif return psid->sid->read(addr & 0x1f); - // return 0xFF; +#if 0 + return 0xFF; +#endif } void -sid_write(uint16_t addr, uint8_t val, UNUSED(void *p)) +sid_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { - // psid_t *psid = (psid_t *)p; +#if 0 + psid_t *psid = (psid_t *) priv; +#endif psid->sid->write(addr & 0x1f, val); } @@ -105,9 +123,11 @@ fillbuf2(int &count, int16_t *buf, int len) psid->last_sample = *buf; } void -sid_fillbuf(int16_t *buf, int len, UNUSED(void *p)) +sid_fillbuf(int16_t *buf, int len, UNUSED(void *priv)) { - // psid_t *psid = (psid_t *)p; +#if 0 + psid_t *psid = (psid_t *) priv; +#endif int x = CLOCK_DELTA(len); fillbuf2(x, buf, len); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 84f31f5008..3aa152b8f9 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -41,6 +41,7 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/snd_sb.h> +#include <86box/plat_unused.h> /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ @@ -177,14 +178,14 @@ sb_log(const char *fmt, ...) /* SB 1, 1.5, MCV, and 2 do not have a mixer, so signal is hardwired. */ static void -sb_get_buffer_sb2(int32_t *buffer, int len, void *p) +sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double out_mono = 0.0; - double out_l = 0.0; - double out_r = 0.0; - int32_t *opl_buf = NULL; + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double out_mono = 0.0; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); @@ -245,30 +246,30 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *p) } static void -sb2_filter_cd_audio(int channel, double *buffer, void *p) +sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - double c; + const sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + double c; if (sb->mixer_enabled) { c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0; *buffer = c * mixer->master; } else { - c = (((sb_iir(1, 0, ((double) *buffer)) / 1.3) * 65536) / 3.0) / 65536.0; + c = (((sb_iir(1, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0; *buffer = c; } } void -sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) +sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double out_l = 0.0; - double out_r = 0.0; - int32_t *opl_buf = NULL; - int32_t *opl2_buf = NULL; + sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double out_l = 0.0; + double out_r = 0.0; + const int32_t *opl_buf = NULL; + const int32_t *opl2_buf = NULL; if (sb->opl_enabled) { if (sb->dsp.sb_type == SBPRO) { @@ -281,7 +282,8 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) sb_dsp_update(&sb->dsp); for (int c = 0; c < len * 2; c += 2) { - out_l = 0.0, out_r = 0.0; + out_l = 0.0; + out_r = 0.0; if (sb->opl_enabled) { if (sb->dsp.sb_type == SBPRO) { @@ -327,13 +329,13 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) } void -sbpro_filter_cd_audio(int channel, double *buffer, void *p) +sbpro_filter_cd_audio(int channel, double *buffer, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l; - double master = channel ? mixer->master_r : mixer->master_l; + const sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l; + double master = channel ? mixer->master_r : mixer->master_l; if (mixer->output_filter) c = (sb_iir(1, channel, *buffer) * cd) / 3.9; @@ -343,19 +345,19 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *p) } static void -sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p) +sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k; - int c_record; - int32_t in_l; - int32_t in_r; - double out_l = 0.0; - double out_r = 0.0; - double bass_treble; - int32_t *opl_buf = NULL; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + int dsp_rec_pos = sb->dsp.record_pos_write; + int c_emu8k = 0; + int c_record; + int32_t in_l; + int32_t in_r; + double out_l = 0.0; + double out_r = 0.0; + double bass_treble; + const int32_t *opl_buf = NULL; if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); @@ -477,17 +479,17 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p) } void -sb16_awe32_filter_cd_audio(int channel, double *buffer, void *p) +sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - double c; - double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; - double master = channel ? mixer->master_r : mixer->master_l; - int32_t bass = channel ? mixer->bass_r : mixer->bass_l; - int32_t treble = channel ? mixer->treble_r : mixer->treble_l; - double bass_treble; - double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double c; + double cd = channel ? mixer->cd_r : mixer->cd_l /* / 3.0 */; + double master = channel ? mixer->master_r : mixer->master_l; + int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + double bass_treble; + double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); if (mixer->output_filter) c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0; @@ -519,9 +521,51 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *p) } void -sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p) +sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double c; + double spk = mixer->speaker; + double master = channel ? mixer->master_r : mixer->master_l; + int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + double bass_treble; + double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + + if (mixer->output_filter) + c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0; + else + c = ((*buffer) * spk) / 3.0; + c *= master; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 8) { + bass_treble = sb_bass_treble_4bits[bass]; + + if (bass > 8) + c += (low_iir(2, channel, c) * bass_treble); + else if (bass < 8) + c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 8) { + bass_treble = sb_bass_treble_4bits[treble]; + + if (treble > 8) + c += (high_iir(2, channel, c) * bass_treble); + else if (treble < 8) + c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c * output_gain; +} + +void +sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; if (!(addr & 1)) { @@ -558,10 +602,10 @@ sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p) } uint8_t -sb_ct1335_mixer_read(uint16_t addr, void *p) +sb_ct1335_mixer_read(uint16_t addr, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + const sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; if (!(addr & 1)) return mixer->index; @@ -589,9 +633,9 @@ sb_ct1335_mixer_reset(sb_t *sb) } void -sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) +sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; if (!(addr & 1)) { @@ -685,10 +729,10 @@ sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) } uint8_t -sb_ct1345_mixer_read(uint16_t addr, void *p) +sb_ct1345_mixer_read(uint16_t addr, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + const sb_t *sb = (sb_t *) priv; + const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; if (!(addr & 1)) return mixer->index; @@ -727,9 +771,9 @@ sb_ct1345_mixer_reset(sb_t *sb) } void -sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) +sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; if (!(addr & 1)) @@ -741,6 +785,8 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) SoundBlaster 16 sets bit 7 if previous mixer index invalid. Status bytes initially 080h on startup for all but level bytes (SB16). */ + sb_log("CT1745: [W] %02X = %02X\n", mixer->index, val); + if (mixer->index == 0) { /* Reset: Changed defaults from -14dB to 0dB */ @@ -750,7 +796,9 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x36] = mixer->regs[0x37] = 0xf8; mixer->regs[0x38] = mixer->regs[0x39] = 0x00; - mixer->regs[0x3a] = mixer->regs[0x3b] = 0x00; + mixer->regs[0x3a] = 0x00; + /* Speaker control - it appears to be in steps of 64. */ + mixer->regs[0x3b] = 0x80; mixer->regs[0x3c] = (OUTPUT_MIC | OUTPUT_CD_R | OUTPUT_CD_L | OUTPUT_LINE_R | OUTPUT_LINE_L); mixer->regs[0x3d] = (INPUT_MIC | INPUT_CD_L | INPUT_LINE_L | INPUT_MIDI_L); @@ -762,12 +810,25 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x44] = mixer->regs[0x45] = 0x80; mixer->regs[0x46] = mixer->regs[0x47] = 0x80; + /* 0x43 = Mic AGC (Automatic Gain Control?) according to Linux's sb.h. + NSC LM4560 datasheet: Bit 0: 1 = Enable, 0 = Disable; + Another source says this: Bit 0: 0 = AGC on (default), 1 = Fixed gain of 20 dB. */ mixer->regs[0x43] = 0x00; + mixer->regs[0x49] = mixer->regs[0x4a] = 0x80; + mixer->regs[0x83] = 0xff; sb->dsp.sb_irqm8 = 0; sb->dsp.sb_irqm16 = 0; sb->dsp.sb_irqm401 = 0; + + mixer->regs[0xfd] = 0x10; + mixer->regs[0xfe] = 0x06; + + mixer->regs[0xff] = sb->dsp.sb_16_dma_supported ? 0x05 : 0x03; + + sb_dsp_setdma16_enabled(&sb->dsp, 0x01); + sb_dsp_setdma16_translate(&sb->dsp, mixer->regs[0xff] & 0x02); } else mixer->regs[mixer->index] = val; @@ -818,31 +879,37 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) Note: Registers 80h and 81h are Read-only for PnP boards. */ case 0x80: - if (val & 0x01) - sb_dsp_setirq(&sb->dsp, 2); - if (val & 0x02) - sb_dsp_setirq(&sb->dsp, 5); - if (val & 0x04) - sb_dsp_setirq(&sb->dsp, 7); - if (val & 0x08) - sb_dsp_setirq(&sb->dsp, 10); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setirq(&sb->dsp, 2); + if (val & 0x02) + sb_dsp_setirq(&sb->dsp, 5); + if (val & 0x04) + sb_dsp_setirq(&sb->dsp, 7); + if (val & 0x08) + sb_dsp_setirq(&sb->dsp, 10); + } break; case 0x81: /* The documentation is confusing. sounds as if multple dma8 channels could be set. */ - if (val & 0x01) - sb_dsp_setdma8(&sb->dsp, 0); - if (val & 0x02) - sb_dsp_setdma8(&sb->dsp, 1); - if (val & 0x08) - sb_dsp_setdma8(&sb->dsp, 3); - if (val & 0x20) - sb_dsp_setdma16(&sb->dsp, 5); - if (val & 0x40) - sb_dsp_setdma16(&sb->dsp, 6); - if (val & 0x80) - sb_dsp_setdma16(&sb->dsp, 7); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setdma8(&sb->dsp, 0); + else if (val & 0x02) + sb_dsp_setdma8(&sb->dsp, 1); + else if (val & 0x08) + sb_dsp_setdma8(&sb->dsp, 3); + + sb_dsp_setdma16(&sb->dsp, 4); + if (val & 0x20) + sb_dsp_setdma16(&sb->dsp, 5); + else if (val & 0x40) + sb_dsp_setdma16(&sb->dsp, 6); + else if (val & 0x80) + sb_dsp_setdma16(&sb->dsp, 7); + } break; case 0x83: @@ -852,15 +919,51 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) case 0x84: /* MPU Control register, per the Linux source code. */ - if (sb->mpu != NULL) { - if ((val & 0x06) == 0x00) - mpu401_change_addr(sb->mpu, 0x330); - else if ((val & 0x06) == 0x04) - mpu401_change_addr(sb->mpu, 0x300); - else if ((val & 0x06) == 0x02) - mpu401_change_addr(sb->mpu, 0); + /* Bits 2-1: MPU-401 address: + 0, 0 = 330h; + 0, 1 = Disabled; + 1, 0 = 300h; + 1, 1 = ???? (Reserved?) + Bit 0: Gameport address: + 0, 0 = 200-207h; + 0, 1 = Disabled + */ + if (!sb->pnp) { + if (sb->mpu != NULL) { + if ((val & 0x06) == 0x00) + mpu401_change_addr(sb->mpu, 0x330); + else if ((val & 0x06) == 0x04) + mpu401_change_addr(sb->mpu, 0x300); + else if ((val & 0x06) == 0x02) + mpu401_change_addr(sb->mpu, 0); + } + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + if (!(val & 0x01)) { + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, 0x200); + } } break; + + case 0xff: + if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) { + /* + Bit 5: High DMA channel enabled (0 = yes, 1 = no); + Bit 2: ????; + Bit 1: ???? (16-bit to 8-bit translation?); + Bit 0: ???? + Seen values: 20, 05, 04, 03 + */ + sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20)); +#ifdef TOGGLABLE_TRANSLATION + sb_dsp_setdma16_translate(&sb->dsp, val & 0x02); +#endif + } + break; + + default: + break; } mixer->output_selector = mixer->regs[0x3c]; @@ -879,7 +982,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->line_r = (mixer->output_selector & OUTPUT_LINE_R) ? (sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] / 32768.0) : 0.0; mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3a] >> 3] / 32768.0; - mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3b] * 3 + 22] / 32768.0; + mixer->speaker = sb_att_7dbstep_2bits[(mixer->regs[0x3b] >> 6) & 0x3] / 32768.0; mixer->input_gain_L = (mixer->regs[0x3f] >> 6); mixer->input_gain_R = (mixer->regs[0x40] >> 6); @@ -897,12 +1000,12 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) } uint8_t -sb_ct1745_mixer_read(uint16_t addr, void *p) +sb_ct1745_mixer_read(uint16_t addr, void *priv) { - sb_t *sb = (sb_t *) p; - sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp; - uint8_t ret = 0xff; + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + uint8_t temp; + uint8_t ret = 0xff; if (!(addr & 1)) ret = mixer->index; @@ -911,7 +1014,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) ret = mixer->regs[mixer->index]; - else + else { switch (mixer->index) { case 0x00: ret = mixer->regs[mixer->index]; @@ -974,6 +1077,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) case 10: ret = 8; break; + + default: + break; } break; @@ -996,6 +1102,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) case 3: ret |= 8; break; + + default: + break; } switch (sb->dsp.sb_16_dmanum) { case 5: @@ -1012,14 +1121,19 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) case 0x82: /* The Interrupt status register, addressed as register 82h on the Mixer register map, - is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, - in which case it should chain to the previous routine. */ + is used by the ISR to determine whether the interrupt is meant for it or for some + other ISR, in which case it should chain to the previous routine. */ /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; - ret = temp; + /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ + temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | + ((sb->dsp.sb_irq401) ? 4 : 0); + if (sb->dsp.sb_type >= SBAWE32) + ret = temp | 0x80; + else + ret = temp | 0x40; break; case 0x83: @@ -1041,20 +1155,28 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) else ret = 0x06; /* Should never happen. */ } + if (!sb->gameport_addr) + ret |= 0x01; break; - case 0x90: - /* 3D Enhancement switch. */ + case 0x49: /* Undocumented register used by some Creative drivers. */ + case 0x4a: /* Undocumented register used by some Creative drivers. */ + case 0x8c: /* Undocumented register used by some Creative drivers. */ + case 0x8e: /* Undocumented register used by some Creative drivers. */ + case 0x90: /* 3D Enhancement switch. */ + case 0xfd: /* Undocumented register used by some Creative drivers. */ + case 0xfe: /* Undocumented register used by some Creative drivers. */ ret = mixer->regs[mixer->index]; break; - /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - case 0xfd: - ret = 16; - break; - - case 0xfe: - ret = 6; + case 0xff: /* Undocumented register used by some Creative drivers. + This and the upper bits of 0x82 seem to affect the + playback volume: + - Register FF = FF: Volume playback normal. + - Register FF = Not FF: Volume playback low unless + bit 6 of 82h is set. */ + if (sb->dsp.sb_type > SBAWE32) + ret = mixer->regs[mixer->index]; break; default: @@ -1062,6 +1184,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) break; } + sb_log("CT1745: [R] %02X = %02X\n", mixer->index, ret); + } + sb_log("CT1745: read REG%02X: %02X\n", mixer->index, ret); return ret; @@ -1072,15 +1197,12 @@ sb_ct1745_mixer_reset(sb_t *sb) { sb_ct1745_mixer_write(4, 0, sb); sb_ct1745_mixer_write(5, 0, sb); - - sb->mixer_sb16.regs[0xfd] = 16; - sb->mixer_sb16.regs[0xfe] = 6; } uint8_t -sb_mcv_read(int port, void *p) +sb_mcv_read(int port, void *priv) { - sb_t *sb = (sb_t *) p; + const sb_t *sb = (sb_t *) priv; sb_log("sb_mcv_read: port=%04x\n", port); @@ -1088,10 +1210,10 @@ sb_mcv_read(int port, void *p) } void -sb_mcv_write(int port, uint8_t val, void *p) +sb_mcv_write(int port, uint8_t val, void *priv) { uint16_t addr; - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1133,18 +1255,18 @@ sb_mcv_write(int port, uint8_t val, void *p) } uint8_t -sb_mcv_feedb(void *p) +sb_mcv_feedb(void *priv) { - sb_t *sb = (sb_t *) p; + const sb_t *sb = (sb_t *) priv; return (sb->pos_regs[2] & 1); } static uint8_t -sb_pro_mcv_read(int port, void *p) +sb_pro_mcv_read(int port, void *priv) { - sb_t *sb = (sb_t *) p; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_pro_mcv_read: port=%04x ret=%02x\n", port, ret); @@ -1152,10 +1274,10 @@ sb_pro_mcv_read(int port, void *p) } static void -sb_pro_mcv_write(int port, uint8_t val, void *p) +sb_pro_mcv_write(int port, uint8_t val, void *priv) { uint16_t addr; - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1212,10 +1334,10 @@ sb_pro_mcv_write(int port, uint8_t val, void *p) } static uint8_t -sb_16_reply_mca_read(int port, void *p) +sb_16_reply_mca_read(int port, void *priv) { - sb_t *sb = (sb_t *) p; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_16_reply_mca_read: port=%04x ret=%02x\n", port, ret); @@ -1223,13 +1345,13 @@ sb_16_reply_mca_read(int port, void *p) } static void -sb_16_reply_mca_write(int port, uint8_t val, void *p) +sb_16_reply_mca_write(int port, uint8_t val, void *priv) { uint16_t addr; uint16_t mpu401_addr; int low_dma; int high_dma; - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1347,6 +1469,9 @@ sb_16_reply_mca_write(int port, uint8_t val, void *p) case 0x60: sb_dsp_setirq(&sb->dsp, 10); break; + + default: + break; } low_dma = sb->pos_regs[3] & 3; @@ -1358,6 +1483,45 @@ sb_16_reply_mca_write(int port, uint8_t val, void *p) sb_dsp_setdma16(&sb->dsp, high_dma); } +void +sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv) +{ + sb_t *sb = (sb_t *) priv; + uint16_t addr = sb->dsp.sb_addr; + + io_removehandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_removehandler(addr + 8, 0x0002, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_removehandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + + sb_dsp_setaddr(&sb->dsp, 0); + + addr = new_addr; + + io_sethandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_sethandler(addr + 8, 0x0002, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + + sb_dsp_setaddr(&sb->dsp, addr); +} + static void sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -1437,14 +1601,20 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) sb_dsp_setdma8(&sb->dsp, val); val = config->dma[1].dma; - if (val != ISAPNP_DMA_DISABLED) - sb_dsp_setdma16(&sb->dsp, val); + sb_dsp_setdma16_enabled(&sb->dsp, val != ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_translate(&sb->dsp, val < ISAPNP_DMA_DISABLED); + if (val != ISAPNP_DMA_DISABLED) { + if (sb->dsp.sb_16_dma_supported) + sb_dsp_setdma16(&sb->dsp, val); + else + sb_dsp_setdma16_8(&sb->dsp, val); + } } break; case 1: /* IDE */ - ide_pnp_config_changed(0, config, (void *) 2); + ide_pnp_config_changed(0, config, (void *) 3); break; case 2: /* Reserved (16) / WaveTable (32+) */ @@ -1458,6 +1628,25 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) case 4: /* StereoEnhance (32) */ break; + + default: + break; + } +} + +static void +sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + sb_t *sb = (sb_t *) priv; + + switch (ld) { + case 0: /* Audio */ + case 1: /* Game */ + sb_16_pnp_config_changed(ld * 3, config, sb); + break; + + default: + break; } } @@ -1476,6 +1665,9 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr case 3: /* WaveTable */ sb_16_pnp_config_changed(ld ^ 1, config, sb); break; + + default: + break; } } @@ -1493,11 +1685,14 @@ sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, voi case 1: /* Game */ sb_16_pnp_config_changed(3, config, sb); break; + + default: + break; } } void * -sb_1_init(const device_t *info) +sb_1_init(UNUSED(const device_t *info)) { /* SB1/2 port mappings, 210h to 260h in 10h steps 2x0 to 2x3 -> CMS chip @@ -1545,7 +1740,7 @@ sb_1_init(const device_t *info) } void * -sb_15_init(const device_t *info) +sb_15_init(UNUSED(const device_t *info)) { /* SB1/2 port mappings, 210h to 260h in 10h steps 2x0 to 2x3 -> CMS chip @@ -1595,7 +1790,7 @@ sb_15_init(const device_t *info) } void * -sb_mcv_init(const device_t *info) +sb_mcv_init(UNUSED(const device_t *info)) { /* SB1/2 port mappings, 210h to 260h in 10h steps 2x6, 2xA, 2xC, 2xE -> DSP chip @@ -1628,7 +1823,7 @@ sb_mcv_init(const device_t *info) } void * -sb_2_init(const device_t *info) +sb_2_init(UNUSED(const device_t *info)) { /* SB2 port mappings, 220h or 240h. 2x0 to 2x3 -> CMS chip @@ -1724,7 +1919,7 @@ sb_pro_v1_opl_write(uint16_t port, uint8_t val, void *priv) } static void * -sb_pro_v1_init(const device_t *info) +sb_pro_v1_init(UNUSED(const device_t *info)) { /* SB Pro port mappings, 220h or 240h. 2x0 to 2x3 -> FM chip, Left and Right (9*2 voices) @@ -1784,7 +1979,7 @@ sb_pro_v1_init(const device_t *info) } static void * -sb_pro_v2_init(const device_t *info) +sb_pro_v2_init(UNUSED(const device_t *info)) { /* SB Pro 2 port mappings, 220h or 240h. 2x0 to 2x3 -> FM chip (18 voices) @@ -1836,7 +2031,7 @@ sb_pro_v2_init(const device_t *info) } static void * -sb_pro_mcv_init(const device_t *info) +sb_pro_mcv_init(UNUSED(const device_t *info)) { /* SB Pro MCV port mappings, 220h or 240h. 2x0 to 2x3 -> FM chip, Left and Right (18 voices) @@ -1868,7 +2063,7 @@ sb_pro_mcv_init(const device_t *info) } static void * -sb_pro_compat_init(const device_t *info) +sb_pro_compat_init(UNUSED(const device_t *info)) { sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); @@ -1890,7 +2085,7 @@ sb_pro_compat_init(const device_t *info) } static void * -sb_16_init(const device_t *info) +sb_16_init(UNUSED(const device_t *info)) { sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); @@ -1900,13 +2095,15 @@ sb_16_init(const device_t *info) sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) - fm_driver_get(FM_YMF262, &sb->opl); + fm_driver_get(info->local, &sb->opl); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -1930,6 +2127,8 @@ sb_16_init(const device_t *info) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -1942,11 +2141,15 @@ sb_16_init(const device_t *info) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + return sb; } static void * -sb_16_reply_mca_init(const device_t *info) +sb_16_reply_mca_init(UNUSED(const device_t *info)) { sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0x00, sizeof(sb_t)); @@ -1955,12 +2158,16 @@ sb_16_reply_mca_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -1977,25 +2184,32 @@ sb_16_reply_mca_init(const device_t *info) sb->pos_regs[0] = 0x38; sb->pos_regs[1] = 0x51; + sb->gameport_addr = 0x200; + return sb; } static void * -sb_16_pnp_init(const device_t *info) +sb_16_pnp_init(UNUSED(const device_t *info)) { sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2007,7 +2221,7 @@ sb_16_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - device_add(&ide_ter_pnp_device); + device_add(&ide_qua_pnp_device); isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); @@ -2017,8 +2231,102 @@ sb_16_pnp_init(const device_t *info) sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); mpu401_change_addr(sb->mpu, 0); - ide_remove_handlers(2); + ide_remove_handlers(3); + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + + return sb; +} + +static int +sb_vibra16xv_available(void) +{ + return rom_present("roms/sound/creative/CT4170 PnP.BIN"); +} + +static int +sb_vibra16c_available(void) +{ + return rom_present("roms/sound/creative/CT4180 PnP.BIN"); +} + +static void * +sb_vibra16_pnp_init(UNUSED(const device_t *info)) +{ + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0x00, sizeof(sb_t)); + + sb->pnp = 1; + + sb->opl_enabled = 1; + fm_driver_get(FM_YMF262, &sb->opl); + + sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ + sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); + sb_ct1745_mixer_reset(sb); + + sb->mixer_enabled = 1; + sb->mixer_sb16.output_filter = 1; + sound_add_handler(sb_get_buffer_sb16_awe32, sb); + sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); + + sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(sb->mpu, 0, sizeof(mpu_t)); + mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&sb->dsp, sb->mpu); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + sb->gameport = gameport_add(&gameport_pnp_device); + + const char *pnp_rom_file = NULL; + switch (info->local) { + case 0: + pnp_rom_file = "roms/sound/creative/CT4170 PnP.BIN"; + break; + + case 1: + pnp_rom_file = "roms/sound/creative/CT4180 PnP.BIN"; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(sb->pnp_rom, 1, 512, fp) == 512) + pnp_rom = sb->pnp_rom; + fclose(fp); + } + } + + switch (info->local) { + case 0: + case 1: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, + NULL, NULL, NULL, sb); + break; + + default: + break; + } + + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, 0); + sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(sb->mpu, 0); + + sb->gameport_addr = 0; gameport_remap(sb->gameport, 0); return sb; @@ -2033,6 +2341,8 @@ sb_16_compat_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2043,47 +2353,51 @@ sb_16_compat_init(const device_t *info) mpu401_init(sb->mpu, 0, 0, M_UART, info->local); sb_dsp_set_mpu(&sb->dsp, sb->mpu); + sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + return sb; } static int sb_awe32_available(void) { - return rom_present("roms/sound/awe32.raw"); + return rom_present("roms/sound/creative/awe32.raw"); } static int sb_32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/CT3600 PnP.BIN"); + return sb_awe32_available() && rom_present("roms/sound/creative/CT3600 PnP.BIN"); } static int sb_awe32_pnp_available(void) { - return sb_awe32_available() && rom_present("roms/sound/CT3980 PnP.BIN"); + return sb_awe32_available() && rom_present("roms/sound/creative/CT3980 PnP.BIN"); } static int sb_awe64_value_available(void) { - return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); } static int sb_awe64_available(void) { - return sb_awe32_available() && rom_present("roms/sound/CT4520 PnP.BIN"); + return sb_awe32_available() && rom_present("roms/sound/creative/CT4520 PnP.BIN"); } static int sb_awe64_gold_available(void) { - return sb_awe32_available() && rom_present("roms/sound/CT4540 PnP.BIN"); + return sb_awe32_available() && rom_present("roms/sound/creative/CT4540 PnP.BIN"); } static void * -sb_awe32_init(const device_t *info) +sb_awe32_init(UNUSED(const device_t *info)) { sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); @@ -2102,6 +2416,8 @@ sb_awe32_init(const device_t *info) sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2125,6 +2441,8 @@ sb_awe32_init(const device_t *info) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -2139,6 +2457,10 @@ sb_awe32_init(const device_t *info) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + return sb; } @@ -2150,16 +2472,22 @@ sb_awe32_pnp_init(const device_t *info) memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? SBAWE64 : SBAWE32, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? + SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2174,35 +2502,38 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); if ((info->local != 2) && (info->local != 3) && (info->local != 4)) - device_add(&ide_ter_pnp_device); + device_add(&ide_qua_pnp_device); - char *pnp_rom_file = NULL; + const char *pnp_rom_file = NULL; switch (info->local) { case 0: - pnp_rom_file = "roms/sound/CT3600 PnP.BIN"; + pnp_rom_file = "roms/sound/creative/CT3600 PnP.BIN"; break; case 1: - pnp_rom_file = "roms/sound/CT3980 PnP.BIN"; + pnp_rom_file = "roms/sound/creative/CT3980 PnP.BIN"; break; case 2: case 3: - pnp_rom_file = "roms/sound/CT4520 PnP.BIN"; + pnp_rom_file = "roms/sound/creative/CT4520 PnP.BIN"; break; case 4: - pnp_rom_file = "roms/sound/CT4540 PnP.BIN"; + pnp_rom_file = "roms/sound/creative/CT4540 PnP.BIN"; + break; + + default: break; } uint8_t *pnp_rom = NULL; if (pnp_rom_file) { - FILE *f = rom_fopen(pnp_rom_file, "rb"); - if (f) { - if (fread(sb->pnp_rom, 1, 512, f) == 512) + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(sb->pnp_rom, 1, 512, fp) == 512) pnp_rom = sb->pnp_rom; - fclose(f); + fclose(fp); } } @@ -2220,6 +2551,9 @@ sb_awe32_pnp_init(const device_t *info) case 4: isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); break; + + default: + break; } sb_dsp_setaddr(&sb->dsp, 0); @@ -2228,28 +2562,31 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); mpu401_change_addr(sb->mpu, 0); - ide_remove_handlers(2); + if ((info->local != 2) && (info->local != 3) && (info->local != 4)) + ide_remove_handlers(3); emu8k_change_addr(&sb->emu8k, 0); + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); return sb; } void -sb_close(void *p) +sb_close(void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; sb_dsp_close(&sb->dsp); free(sb); } static void -sb_awe32_close(void *p) +sb_awe32_close(void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; emu8k_close(&sb->emu8k); @@ -2257,9 +2594,9 @@ sb_awe32_close(void *p) } void -sb_speed_changed(void *p) +sb_speed_changed(void *priv) { - sb_t *sb = (sb_t *) p; + sb_t *sb = (sb_t *) priv; sb_dsp_speed_changed(&sb->dsp); } @@ -2908,6 +3245,13 @@ static const device_config_t sb_16_config[] = { .default_string = "", .default_int = 1 }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -2926,6 +3270,13 @@ static const device_config_t sb_16_config[] = { }; static const device_config_t sb_16_pnp_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -2976,6 +3327,13 @@ static const device_config_t sb_32_pnp_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3189,6 +3547,13 @@ static const device_config_t sb_awe32_config[] = { .default_string = "", .default_int = 1 }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3239,6 +3604,13 @@ static const device_config_t sb_awe32_pnp_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3309,6 +3681,13 @@ static const device_config_t sb_awe64_value_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3375,6 +3754,13 @@ static const device_config_t sb_awe64_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3433,6 +3819,13 @@ static const device_config_t sb_awe64_gold_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3567,7 +3960,21 @@ const device_t sb_16_device = { .name = "Sound Blaster 16", .internal_name = "sb16", .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, + .local = FM_YMF262, + .init = sb_16_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_config +}; + +const device_t sb_vibra16s_onboard_device = { + .name = "Sound Blaster ViBRA 16S (On-Board)", + .internal_name = "sb_vibra16s_onboard", + .flags = DEVICE_ISA | DEVICE_AT, + .local = FM_YMF289B, .init = sb_16_init, .close = sb_close, .reset = NULL, @@ -3577,6 +3984,62 @@ const device_t sb_16_device = { .config = sb_16_config }; +const device_t sb_vibra16s_device = { + .name = "Sound Blaster ViBRA 16S", + .internal_name = "sb_vibra16s", + .flags = DEVICE_ISA | DEVICE_AT, + .local = FM_YMF289B, + .init = sb_16_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_config +}; + +const device_t sb_vibra16xv_device = { + .name = "Sound Blaster ViBRA 16XV", + .internal_name = "sb_vibra16xv", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = sb_vibra16xv_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16c_onboard_device = { + .name = "Sound Blaster ViBRA 16C (On-Board)", + .internal_name = "sb_vibra16c_onboard", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = sb_vibra16c_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16c_device = { + .name = "Sound Blaster ViBRA 16C", + .internal_name = "sb_vibra16c", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = sb_vibra16c_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + const device_t sb_16_reply_mca_device = { .name = "Sound Blaster 16 Reply MCA", .internal_name = "sb16_reply_mca", diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 5b9637a813..6fc7815abb 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -25,6 +25,8 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/snd_sb.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define ADPCM_4 1 #define ADPCM_26 2 @@ -33,8 +35,8 @@ /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 -void pollsb(void *p); -void sb_poll_i(void *p); +void pollsb(void *priv); +void sb_poll_i(void *priv); static int sbe2dat[4][9] = { {0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106}, @@ -63,7 +65,7 @@ static int sb_commands[256] = { }; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d, 0x410 }; +uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 }; /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { @@ -113,7 +115,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -double low_fir_sb16_coef[2][SB16_NCoef]; +double low_fir_sb16_coef[3][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -173,7 +175,7 @@ recalc_sb16_filter(int c, int playback_freq) static void sb_irq_update_pic(void *priv, int set) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + const sb_dsp_t *dsp = (sb_dsp_t *) priv; if (set) picint(1 << dsp->sb_irqnum); else @@ -205,8 +207,8 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) int masked = 0; switch (bit) { - case 0: default: + case 0: dsp->sb_irq8 = set; masked = dsp->sb_irqm8; break; @@ -249,7 +251,7 @@ sb_dsp_irq_update(void *priv, int set) static int sb_dsp_irq_pending(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + const sb_dsp_t *dsp = (sb_dsp_t *) priv; return dsp->sb_irq401; } @@ -408,49 +410,144 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) int sb_8_read_dma(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + const sb_dsp_t *dsp = (sb_dsp_t *) priv; + return dma_channel_read(dsp->sb_8_dmanum); } int sb_8_write_dma(void *priv, uint8_t val) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + const sb_dsp_t *dsp = (sb_dsp_t *) priv; + return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA; } +/* + Supported High DMA Translation Channel + ---------------------------------------------------- + 0 0 0 First 8-bit + 0 0 1 First 8-bit + 0 1 0 Second 8-bit + 0 1 1 Second 8-bit + 1 0 0 First 8-bit + 1 0 1 First 8-bit + 1 1 0 16-bit + 1 1 1 Second 8-bit + */ int sb_16_read_dma(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; - return dma_channel_read(dsp->sb_16_dmanum); + const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; + + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_read(dma_ch); + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_read(dma_ch); + ret = temp; + if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { + temp = dma_channel_read(dma_ch); + if (temp == DMA_NODATA) + ret = DMA_NODATA; + else { + dma_flags = temp & DMA_OVER; + temp &= ~DMA_OVER; + ret |= (temp << 8) | dma_flags; + } + } + } + + return ret; } int sb_16_write_dma(void *priv, uint16_t val) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; - return dma_channel_write(dsp->sb_16_dmanum, val) == DMA_NODATA; + const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; + + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_write(dma_ch, val) == DMA_NODATA; + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_write(dma_ch, val & 0xff); + ret = temp; + if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { + temp = dma_channel_write(dma_ch, val >> 8); + ret = temp; + } + } + + return ret; } void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { + sb_dsp_log("IRQ now: %i\n", irq); dsp->sb_irqnum = irq; } void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { + sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; } void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) { + sb_dsp_log("16-bit DMA now: %i\n", dma); dsp->sb_16_dmanum = dma; } +void +sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma) +{ + sb_dsp_log("16-bit to 8-bit translation DMA now: %i\n", dma); + dsp->sb_16_8_dmanum = dma; +} + +void +sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled) +{ + sb_dsp_log("16-bit DMA now: %sabled\n", enabled ? "en" : "dis"); + dsp->sb_16_dma_enabled = enabled; +} + +void +sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported) +{ + sb_dsp_log("16-bit DMA now: %ssupported\n", supported ? "" : "not "); + dsp->sb_16_dma_supported = supported; +} + +void +sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) +{ + sb_dsp_log("16-bit to 8-bit translation now: %sabled\n", translate ? "en" : "dis"); + dsp->sb_16_dma_translate = translate; +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -473,6 +570,100 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) sb_add_data(dsp, 0); break; + case 0x04: /* ASP set mode register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_mode = dsp->sb_data[0]; + if (dsp->sb_asp_mode & 4) + dsp->sb_asp_ram_index = 0; + sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); + } /* else DSP Status (Obsolete) */ + break; + case 0x05: /* ASP set codec parameter */ + if (dsp->sb_type >= SB16) + sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + break; + case 0x07: + break; + case 0x08: /* ASP get version / AZTECH type/EEPROM access */ + if (IS_AZTECH(dsp)) { + if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ + else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ + else if (dsp->sb_data[0] == 0x08) { + /* EEPROM address to write followed by byte */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); + dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; + break; + } else if (dsp->sb_data[0] == 0x07) { + /* EEPROM address to read */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); + sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); + break; + } else + sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ + break; + } + if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + sb_add_data(dsp, 0xFF); + else if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0x18); + break; + case 0x09: /* AZTECH mode set */ + if (IS_AZTECH(dsp)) { + if (dsp->sb_data[0] == 0x00) { + sb_dsp_log("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } else if (dsp->sb_data[0] == 0x01) { + sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } else + sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen + } + break; + case 0x0E: /* ASP set register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; + + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; + + if (dsp->sb_asp_mode & 2) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } + sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } + break; + case 0x0F: /* ASP get register */ + if (dsp->sb_type >= SB16) { + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; + + if (dsp->sb_asp_mode & 1) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } else if (dsp->sb_data[0] == 0x83) { + dsp->sb_asp_regs[0x83] = 0x18; + } + sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); + } + break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; @@ -483,7 +674,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x17: /* 2-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; - /* Fall through */ + fallthrough; case 0x16: /* 2-bit ADPCM output */ sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); @@ -595,7 +786,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x75: /* 4-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; - /* Fall through */ + fallthrough; case 0x74: /* 4-bit ADPCM output */ sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); @@ -606,7 +797,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x77: /* 2.6-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; - /* Fall through */ + fallthrough; case 0x76: /* 2.6-bit ADPCM output */ sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); @@ -664,7 +855,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xB6: case 0xB7: /* 16-bit DMA output */ if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -677,7 +869,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xBE: case 0xBF: /* 16-bit DMA input */ if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -690,7 +883,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xC6: case 0xC7: /* 8-bit DMA output */ if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -703,7 +897,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xCE: case 0xCF: /* 8-bit DMA input */ if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -782,6 +977,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; + case 0xE7: /* ???? */ + break; case 0xE8: /* Read test register */ sb_add_data(dsp, dsp->sb_test); break; @@ -793,79 +990,6 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("Trigger IRQ\n"); sb_irq(dsp, 0); break; - case 0xE7: /* ???? */ - break; - case 0x07: - case 0xFF: /* No, that's not how you program auto-init DMA */ - break; - case 0x08: /* ASP get version / AZTECH type/EEPROM access */ - if (IS_AZTECH(dsp)) { - if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) - sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ - else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) - sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ - else if (dsp->sb_data[0] == 0x08) { - /* EEPROM address to write followed by byte */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); - dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; - break; - } else if (dsp->sb_data[0] == 0x07) { - /* EEPROM address to read */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); - sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); - break; - } else - sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ - break; - } - if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ - sb_add_data(dsp, 0xFF); - else if (dsp->sb_type >= SB16) - sb_add_data(dsp, 0x18); - break; - case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; - - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; - - dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; - - if (dsp->sb_asp_mode & 2) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } - sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - } - break; - case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) { - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; - - dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; - - if (dsp->sb_asp_mode & 1) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } else if (dsp->sb_data[0] == 0x83) { - dsp->sb_asp_regs[0x83] = 0x18; - } - sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); - sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); - } - break; case 0xF8: if (dsp->sb_type < SB16) sb_add_data(dsp, 0); @@ -878,30 +1002,7 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; break; - case 0x04: /* ASP set mode register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_mode = dsp->sb_data[0]; - if (dsp->sb_asp_mode & 4) - dsp->sb_asp_ram_index = 0; - sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); - } /* else DSP Status (Obsolete) */ - break; - case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) - sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - break; - - case 0x09: /* AZTECH mode set */ - if (IS_AZTECH(dsp)) { - if (dsp->sb_data[0] == 0x00) { - sb_dsp_log("AZT2316A: WSS MODE!\n"); - azt2316a_enable_wss(1, dsp->parent); - } else if (dsp->sb_data[0] == 0x01) { - sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); - azt2316a_enable_wss(0, dsp->parent); - } else - sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen - } + case 0xFF: /* No, that's not how you program auto-init DMA */ break; /* TODO: Some more data about the DSP registeres @@ -917,6 +1018,10 @@ sb_exec_command(sb_dsp_t *dsp) * 0FCh DSP Auxiliary Status SB16 * 0FDh DSP Command Status SB16 */ + + default: + sb_dsp_log("Unknown DSP command: %02X\n", dsp->sb_command); + break; } /* Update 8051 ram with the last DSP command. @@ -930,6 +1035,10 @@ sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if (dsp->sb_type < SB16) + a &= 0xfffe; + switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -982,6 +1091,9 @@ sb_write(uint16_t a, uint8_t v, void *priv) } } break; + + default: + break; } } @@ -991,6 +1103,10 @@ sb_read(uint16_t a, void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; uint8_t ret = 0x00; + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if (dsp->sb_type < SB16) + a &= 0xfffe; + switch (a & 0xf) { case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) { @@ -1046,15 +1162,18 @@ sb_read(uint16_t a, void *priv) sb_dsp_log("SB 16-bit ACK read 0xFF\n"); ret = 0xff; break; + + default: + break; } return ret; } void -sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) +sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len) { - sb_dsp_t *dsp = (sb_dsp_t *) p; + sb_dsp_t *dsp = (sb_dsp_t *) priv; sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, len); @@ -1077,9 +1196,9 @@ sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) } int -sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) +sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - sb_dsp_t *dsp = (sb_dsp_t *) p; + sb_dsp_t *dsp = (sb_dsp_t *) priv; if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) return MPU401_InputSysex(dsp->mpu, buffer, len, abort); @@ -1138,6 +1257,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); recalc_sb16_filter(1, FREQ_44100); + recalc_sb16_filter(2, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); @@ -1192,9 +1312,9 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, } void -pollsb(void *p) +pollsb(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) p; + sb_dsp_t *dsp = (sb_dsp_t *) priv; int tempi; int ref; int data[2]; @@ -1378,6 +1498,9 @@ pollsb(void *p) } else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; + + default: + break; } if (dsp->sb_8_length < 0) { @@ -1426,6 +1549,9 @@ pollsb(void *p) dsp->sbdatr = data[1]; dsp->sb_16_length -= 2; break; + + default: + break; } if (dsp->sb_16_length < 0) { @@ -1451,9 +1577,9 @@ pollsb(void *p) } void -sb_poll_i(void *p) +sb_poll_i(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) p; + sb_dsp_t *dsp = (sb_dsp_t *) priv; int processed = 0; timer_advance_u64(&dsp->input_timer, dsp->sblatchi); @@ -1486,6 +1612,9 @@ sb_poll_i(void *p) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; + + default: + break; } if (dsp->sb_8_length < 0) { @@ -1531,6 +1660,9 @@ sb_poll_i(void *p) dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; break; + + default: + break; } if (dsp->sb_16_length < 0) { @@ -1565,6 +1697,7 @@ sb_dsp_update(sb_dsp_t *dsp) } void -sb_dsp_close(sb_dsp_t *dsp) +sb_dsp_close(UNUSED(sb_dsp_t *dsp)) { + // } diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index 56b3538d8a..519219934f 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -10,6 +10,7 @@ #include <86box/io.h> #include <86box/sound.h> #include <86box/snd_sn76489.h> +#include <86box/plat_unused.h> int sn76489_mute; @@ -33,7 +34,7 @@ sn76489_update(sn76489_t *sn76489) result += (int16_t) (volslog[sn76489->vol[c]] * 127); sn76489->count[c] -= (256 * sn76489->psgconst); - while ((int) sn76489->count[c] < 0) { + while (sn76489->count[c] < 0) { sn76489->count[c] += sn76489->latch[c]; sn76489->stat[c] = -sn76489->stat[c]; } @@ -41,7 +42,7 @@ sn76489_update(sn76489_t *sn76489) result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); sn76489->count[0] -= (512 * sn76489->psgconst); - while ((int) sn76489->count[0] < 0 && sn76489->latch[0]) { + while (sn76489->count[0] < 0 && sn76489->latch[0]) { sn76489->count[0] += (sn76489->latch[0] * 4); if (!(sn76489->noise & 4)) { if (sn76489->shift & 1) @@ -59,9 +60,9 @@ sn76489_update(sn76489_t *sn76489) } void -sn76489_get_buffer(int32_t *buffer, int len, void *p) +sn76489_get_buffer(int32_t *buffer, int len, void *priv) { - sn76489_t *sn76489 = (sn76489_t *) p; + sn76489_t *sn76489 = (sn76489_t *) priv; sn76489_update(sn76489); @@ -74,9 +75,9 @@ sn76489_get_buffer(int32_t *buffer, int len, void *p) } void -sn76489_write(uint16_t addr, uint8_t data, void *p) +sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv) { - sn76489_t *sn76489 = (sn76489_t *) p; + sn76489_t *sn76489 = (sn76489_t *) priv; int freq; sn76489_update(sn76489); @@ -140,6 +141,9 @@ sn76489_write(uint16_t addr, uint8_t data, void *p) data &= 0xf; sn76489->vol[0] = 0xf - data; break; + + default: + break; } } else { if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) { @@ -197,7 +201,7 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre } void * -sn76489_device_init(const device_t *info) +sn76489_device_init(UNUSED(const device_t *info)) { sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); memset(sn76489, 0, sizeof(sn76489_t)); @@ -208,7 +212,7 @@ sn76489_device_init(const device_t *info) } void * -ncr8496_device_init(const device_t *info) +ncr8496_device_init(UNUSED(const device_t *info)) { sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); memset(sn76489, 0, sizeof(sn76489_t)); @@ -219,7 +223,7 @@ ncr8496_device_init(const device_t *info) } void * -tndy_device_init(const device_t *info) +tndy_device_init(UNUSED(const device_t *info)) { sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); memset(sn76489, 0, sizeof(sn76489_t)); @@ -232,9 +236,9 @@ tndy_device_init(const device_t *info) } void -sn76489_device_close(void *p) +sn76489_device_close(void *priv) { - sn76489_t *sn76489 = (sn76489_t *) p; + sn76489_t *sn76489 = (sn76489_t *) priv; free(sn76489); } diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index babc8aee10..0537cd09a6 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -26,6 +26,7 @@ #include <86box/pit.h> #include <86box/snd_speaker.h> #include <86box/sound.h> +#include <86box/plat_unused.h> int speaker_mute = 0; int speaker_gated = 0; @@ -85,17 +86,22 @@ speaker_update(void) } void -speaker_get_buffer(int32_t *buffer, int len, void *p) +speaker_get_buffer(int32_t *buffer, int len, UNUSED(void *priv)) { - int32_t val; + double val_l, val_r; speaker_update(); if (!speaker_mute) { for (int c = 0; c < len * 2; c += 2) { - val = speaker_buffer[c >> 1]; - buffer[c] += val; - buffer[c + 1] += val; + val_l = val_r = (double) speaker_buffer[c >> 1]; + /* Apply PC speaker volume and filters */ + if (filter_pc_speaker != NULL) { + filter_pc_speaker(0, &val_l, filter_pc_speaker_p); + filter_pc_speaker(1, &val_r, filter_pc_speaker_p); + } + buffer[c] += (int32_t) val_l; + buffer[c + 1] += (int32_t) val_r; } } diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index 7c2a18f5a0..1f3c294ced 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -12,6 +12,7 @@ #include <86box/io.h> #include <86box/snd_resid.h> #include <86box/sound.h> +#include <86box/plat_unused.h> typedef struct ssi2001_t { void *psid; @@ -31,9 +32,9 @@ ssi2001_update(ssi2001_t *ssi2001) } static void -ssi2001_get_buffer(int32_t *buffer, int len, void *p) +ssi2001_get_buffer(int32_t *buffer, int len, void *priv) { - ssi2001_t *ssi2001 = (ssi2001_t *) p; + ssi2001_t *ssi2001 = (ssi2001_t *) priv; ssi2001_update(ssi2001); @@ -44,26 +45,26 @@ ssi2001_get_buffer(int32_t *buffer, int len, void *p) } static uint8_t -ssi2001_read(uint16_t addr, void *p) +ssi2001_read(uint16_t addr, void *priv) { - ssi2001_t *ssi2001 = (ssi2001_t *) p; + ssi2001_t *ssi2001 = (ssi2001_t *) priv; ssi2001_update(ssi2001); - return sid_read(addr, p); + return sid_read(addr, priv); } static void -ssi2001_write(uint16_t addr, uint8_t val, void *p) +ssi2001_write(uint16_t addr, uint8_t val, void *priv) { - ssi2001_t *ssi2001 = (ssi2001_t *) p; + ssi2001_t *ssi2001 = (ssi2001_t *) priv; ssi2001_update(ssi2001); - sid_write(addr, val, p); + sid_write(addr, val, priv); } void * -ssi2001_init(const device_t *info) +ssi2001_init(UNUSED(const device_t *info)) { ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); memset(ssi2001, 0, sizeof(ssi2001_t)); @@ -80,9 +81,9 @@ ssi2001_init(const device_t *info) } void -ssi2001_close(void *p) +ssi2001_close(void *priv) { - ssi2001_t *ssi2001 = (ssi2001_t *) p; + ssi2001_t *ssi2001 = (ssi2001_t *) priv; sid_close(ssi2001->psid); diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index a3a7483747..a69d746daa 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -33,6 +33,7 @@ #include <86box/timer.h> #include <86box/snd_ad1848.h> #include <86box/snd_opl.h> +#include <86box/plat_unused.h> /* 530, 11, 3 - 530=23 * 530, 11, 1 - 530=22 @@ -59,14 +60,14 @@ typedef struct wss_t { } wss_t; uint8_t -wss_read(uint16_t addr, void *priv) +wss_read(UNUSED(uint16_t addr), void *priv) { - wss_t *wss = (wss_t *) priv; + const wss_t *wss = (wss_t *) priv; return 4 | (wss->config & 0x40); } void -wss_write(uint16_t addr, uint8_t val, void *priv) +wss_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { wss_t *wss = (wss_t *) priv; @@ -79,20 +80,25 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; + const int32_t *opl_buf = NULL; + + if (wss->opl_enabled) + opl_buf = wss->opl.update(wss->opl.priv); - int32_t *opl_buf = wss->opl.update(wss->opl.priv); ad1848_update(&wss->ad1848); for (int c = 0; c < len * 2; c++) { - buffer[c] += opl_buf[c]; + if (opl_buf) + buffer[c] += opl_buf[c]; buffer[c] += wss->ad1848.buffer[c] / 2; } - wss->opl.reset_buffer(wss->opl.priv); + if (wss->opl_enabled) + wss->opl.reset_buffer(wss->opl.priv); wss->ad1848.pos = 0; } void * -wss_init(const device_t *info) +wss_init(UNUSED(const device_t *info)) { wss_t *wss = malloc(sizeof(wss_t)); memset(wss, 0, sizeof(wss_t)); @@ -131,7 +137,7 @@ wss_init(const device_t *info) static uint8_t ncr_audio_mca_read(int port, void *priv) { - wss_t *wss = (wss_t *) priv; + const wss_t *wss = (wss_t *) priv; return wss->pos_regs[port & 7]; } @@ -186,12 +192,12 @@ ncr_audio_mca_write(int port, uint8_t val, void *priv) static uint8_t ncr_audio_mca_feedb(void *priv) { - wss_t *wss = (wss_t *) priv; + const wss_t *wss = (wss_t *) priv; return (wss->pos_regs[2] & 1); } void * -ncr_audio_init(const device_t *info) +ncr_audio_init(UNUSED(const device_t *info)) { wss_t *wss = malloc(sizeof(wss_t)); memset(wss, 0, sizeof(wss_t)); diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index e7cf37b2ae..59e5691e95 100644 --- a/src/sound/snd_ym7128.c +++ b/src/sound/snd_ym7128.c @@ -5,12 +5,13 @@ #include <86box/86box.h> #include <86box/snd_ym7128.h> +#include <86box/plat_unused.h> static int attenuation[32]; static int tap_position[32]; void -ym7128_init(ym7128_t *ym7128) +ym7128_init(UNUSED(ym7128_t *ym7128)) { int c; double out = 65536.0; @@ -97,6 +98,9 @@ ym7128_write(ym7128_t *ym7128, uint8_t val) case 0x1e: ym7128->t[ym7128->reg_sel - 0x16] = tap_position[ym7128->dat & 0x1f]; break; + + default: + break; } ym7128->regs[ym7128->reg_sel] = ym7128->dat; } @@ -137,8 +141,8 @@ ym7128_apply(ym7128_t *ym7128, int16_t *buffer, int len) samp_l = (samp_l * ym7128->vl * 2) >> 16; samp_r = (samp_r * ym7128->vr * 2) >> 16; - buffer[c] += ((int32_t) samp_l + (int32_t) ym7128->prev_l) / 2; - buffer[c + 1] += ((int32_t) samp_r + (int32_t) ym7128->prev_r) / 2; + buffer[c] += (samp_l + (int32_t) ym7128->prev_l) / 2; + buffer[c + 1] += (samp_r + (int32_t) ym7128->prev_r) / 2; buffer[c + 2] += samp_l; buffer[c + 3] += samp_r; diff --git a/src/sound/sound.c b/src/sound/sound.c index 94fbad3945..ed7f821e0e 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -47,7 +47,7 @@ typedef struct { } SOUND_CARD; typedef struct { - void (*get_buffer)(int32_t *buffer, int len, void *p); + void (*get_buffer)(int32_t *buffer, int len, void *priv); void *priv; } sound_handler_t; @@ -76,8 +76,11 @@ static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; static volatile int cdaudioon = 0; static int cd_thread_enable = 0; -static void (*filter_cd_audio)(int channel, double *buffer, void *p) = NULL; -static void *filter_cd_audio_p = NULL; +static void (*filter_cd_audio)(int channel, double *buffer, void *priv) = NULL; +static void *filter_cd_audio_p = NULL; + +void (*filter_pc_speaker)(int channel, double *buffer, void *priv) = NULL; +void *filter_pc_speaker_p = NULL; static const device_t sound_none_device = { .name = "None", @@ -134,6 +137,9 @@ static const SOUND_CARD sound_cards[] = { { &sb_awe64_value_device }, { &sb_awe64_device }, { &sb_awe64_gold_device }, + { &sb_vibra16c_device }, + { &sb_vibra16s_device }, + { &sb_vibra16xv_device }, { &ssi2001_device }, #if defined(DEV_BRANCH) && defined(USE_PAS16) { &pas16_device }, @@ -196,7 +202,7 @@ sound_card_has_config(int card) return device_has_config(sound_cards[card].device) ? 1 : 0; } -char * +const char * sound_card_get_internal_name(int card) { return device_get_internal_name(sound_cards[card].device); @@ -208,7 +214,7 @@ sound_card_get_from_internal_name(const char *s) int c = 0; while (sound_cards[c].device != NULL) { - if (!strcmp((char *) sound_cards[c].device->internal_name, s)) + if (!strcmp(sound_cards[c].device->internal_name, s)) return c; c++; } @@ -219,13 +225,13 @@ sound_card_get_from_internal_name(const char *s) void sound_card_init(void) { - if (sound_cards[sound_card_current[0]].device) + if ((sound_card_current[0] > SOUND_INTERNAL) && (sound_cards[sound_card_current[0]].device)) device_add(sound_cards[sound_card_current[0]].device); - if (sound_cards[sound_card_current[1]].device) + if ((sound_card_current[1] > SOUND_INTERNAL) && (sound_cards[sound_card_current[1]].device)) device_add(sound_cards[sound_card_current[1]].device); - if (sound_cards[sound_card_current[2]].device) + if ((sound_card_current[2] > SOUND_INTERNAL) && (sound_cards[sound_card_current[2]].device)) device_add(sound_cards[sound_card_current[2]].device); - if (sound_cards[sound_card_current[3]].device) + if ((sound_card_current[3] > SOUND_INTERNAL) && (sound_cards[sound_card_current[3]].device)) device_add(sound_cards[sound_card_current[3]].device); } @@ -246,7 +252,7 @@ sound_cd_clean_buffers(void) } static void -sound_cd_thread(void *param) +sound_cd_thread(UNUSED(void *param)) { uint32_t lba; int r; @@ -425,24 +431,33 @@ sound_init(void) } void -sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) +sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv) { sound_handlers[sound_handlers_num].get_buffer = get_buffer; - sound_handlers[sound_handlers_num].priv = p; + sound_handlers[sound_handlers_num].priv = priv; sound_handlers_num++; } void -sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *p), void *p) +sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) { if ((filter_cd_audio == NULL) || (filter == NULL)) { filter_cd_audio = filter; - filter_cd_audio_p = p; + filter_cd_audio_p = priv; } } void -sound_poll(void *priv) +sound_set_pc_speaker_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) +{ + if ((filter_pc_speaker == NULL) || (filter == NULL)) { + filter_pc_speaker = filter; + filter_pc_speaker_p = priv; + } +} + +void +sound_poll(UNUSED(void *priv)) { timer_advance_u64(&sound_poll_timer, sound_poll_latch); @@ -459,7 +474,7 @@ sound_poll(void *priv) for (c = 0; c < SOUNDBUFLEN * 2; c++) { if (sound_is_float) - outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; + outbuffer_ex[c] = ((float) outbuffer[c]) / (float) 32768.0; else { if (outbuffer[c] > 32767) outbuffer[c] = 32767; @@ -511,15 +526,18 @@ sound_reset(void) filter_cd_audio = NULL; filter_cd_audio_p = NULL; + filter_pc_speaker = NULL; + filter_pc_speaker_p = NULL; + sound_set_cd_volume(65535, 65535); + + /* Reset the MPU-401 already loaded flag and the chain of input/output handlers. */ + midi_in_handlers_clear(); } void sound_card_reset(void) { - /* Reset the MPU-401 already loaded flag and the chain of input/output handlers. */ - midi_in_handlers_clear(); - sound_card_init(); if (mpu401_standalone_enable) diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 9f26fe517a..0d9e7d909f 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -33,6 +33,7 @@ #include <86box/midi.h> #include <86box/plat_dynld.h> #include <86box/sound.h> +#include <86box/plat_unused.h> #if defined(_WIN32) && !defined(USE_FAUDIO) static void *xaudio2_handle = NULL; @@ -57,32 +58,38 @@ static IXAudio2SourceVoice *srcvoicecd = NULL; #define BUFLEN SOUNDBUFLEN static void WINAPI -OnVoiceProcessingPassStart(IXAudio2VoiceCallback *callback, uint32_t bytesRequired) +OnVoiceProcessingPassStart(UNUSED(IXAudio2VoiceCallback *callback), UNUSED(uint32_t bytesRequired)) { + // } static void WINAPI -OnVoiceProcessingPassEnd(IXAudio2VoiceCallback *callback) +OnVoiceProcessingPassEnd(UNUSED(IXAudio2VoiceCallback *callback)) { + // } static void WINAPI -OnStreamEnd(IXAudio2VoiceCallback *callback) +OnStreamEnd(UNUSED(IXAudio2VoiceCallback *callback)) { + // } static void WINAPI -OnBufferStart(IXAudio2VoiceCallback *callback, void *pBufferContext) +OnBufferStart(UNUSED(IXAudio2VoiceCallback *callback), UNUSED(void *pBufferContext)) { + // } static void WINAPI -OnLoopEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) +OnLoopEnd(UNUSED(IXAudio2VoiceCallback *callback), UNUSED(void *pBufferContext)) { + // } static void WINAPI -OnVoiceError(IXAudio2VoiceCallback *callback, void *pBufferContext, HRESULT error) +OnVoiceError(UNUSED(IXAudio2VoiceCallback *callback), UNUSED(void *pBufferContext), UNUSED(HRESULT error)) { + // } static void WINAPI -OnBufferEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) +OnBufferEnd(UNUSED(IXAudio2VoiceCallback *callback), UNUSED(void *pBufferContext)) { free(pBufferContext); } @@ -167,7 +174,7 @@ inital(void) IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW); - char *mdn = midi_out_device_get_internal_name(midi_output_device_current); + const char *mdn = midi_out_device_get_internal_name(midi_output_device_current); if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) { fmt.nSamplesPerSec = midi_freq; diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index bc0cf8b6cd..4f8ba1243c 100644 --- a/src/sound/ymfm/ymfm.h +++ b/src/sound/ymfm/ymfm.h @@ -46,6 +46,8 @@ #include #include +#define SNPRINTF_BUFFER_SIZE_CALC (256 - (end - &buffer[0])) + namespace ymfm { @@ -350,7 +352,7 @@ class ymfm_wavfile { // create file char name[20]; - sprintf(name, "wavlog-%02d.wav", m_index); + snprintf(name, sizeof(name), "wavlog-%02d.wav", m_index); FILE *out = fopen(name, "wb"); // make the wav file header diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp index 14c1aa965c..55cdd643dc 100644 --- a/src/sound/ymfm/ymfm_fm.ipp +++ b/src/sound/ymfm/ymfm_fm.ipp @@ -1522,8 +1522,11 @@ void fm_engine_base::engine_timer_expired(uint32_t tnum) m_modified_channels |= 1 << chnum; } - // reset - m_timer_running[tnum] = false; + // Make sure the array does not go out of bounds to keep gcc happy + if ((tnum < 2) || (sizeof(m_timer_running) > (2 * sizeof(uint8_t)))) { + // reset + m_timer_running[tnum] = false; + } update_timer(tnum, 1, 0); } diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index 499bfceeff..bb91c5dc0b 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -388,7 +388,7 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", chnum, opnum, ch_block_freq(choffs), ch_feedback(choffs), @@ -405,25 +405,25 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op op_eg_sustain(opoffs)); if (OUTPUTS > 1) - end += sprintf(end, " out=%c%c%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-', ch_output_2(choffs) ? '0' : '-', ch_output_3(choffs) ? '1' : '-'); if (op_lfo_am_enable(opoffs) != 0) - end += sprintf(end, " am=%u", lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", lfo_am_depth()); if (op_lfo_pm_enable(opoffs) != 0) - end += sprintf(end, " pm=%u", lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", lfo_pm_depth()); if (waveform_enable() && op_waveform(opoffs) != 0) - end += sprintf(end, " wf=%u", op_waveform(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); if (is_rhythm(choffs)) - end += sprintf(end, " rhy=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); if (DYNAMIC_OPS) { operator_mapping map; operator_map(map); if (bitfield(map.chan[chnum], 16, 8) != 0xff) - end += sprintf(end, " 4op"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " 4op"); } return buffer; @@ -687,7 +687,7 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", chnum, opnum, ch_block_freq(choffs), ch_instrument(choffs), @@ -695,11 +695,11 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) op_multiple(opoffs)); if (bitfield(opoffs, 0) == 1 || (is_rhythm(choffs) && choffs >= 6)) - end += sprintf(end, " vol=%X", op_volume(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " vol=%X", op_volume(opoffs)); else - end += sprintf(end, " tl=%02X", ch_total_level(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " tl=%02X", ch_total_level(choffs)); - end += sprintf(end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", op_ksr(opoffs), op_ksl(opoffs), op_attack_rate(opoffs), @@ -710,13 +710,13 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_sustain(choffs)); if (op_lfo_am_enable(opoffs)) - end += sprintf(end, " am=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=1"); if (op_lfo_pm_enable(opoffs)) - end += sprintf(end, " pm=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=1"); if (op_waveform(opoffs) != 0) - end += sprintf(end, " wf=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=1"); if (is_rhythm(choffs)) - end += sprintf(end, " rhy=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opm.cpp b/src/sound/ymfm/ymfm_opm.cpp index 544bbe89a2..c72badb57a 100644 --- a/src/sound/ymfm/ymfm_opm.cpp +++ b/src/sound/ymfm/ymfm_opm.cpp @@ -356,7 +356,7 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, ch_block_freq(choffs), op_detune2(opoffs), @@ -376,14 +376,14 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); if (noise_enable() && opoffs == 31) - end += sprintf(end, " noise=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opn.cpp b/src/sound/ymfm/ymfm_opn.cpp index 053ad97701..388162dfef 100644 --- a/src/sound/ymfm/ymfm_opn.cpp +++ b/src/sound/ymfm/ymfm_opn.cpp @@ -411,7 +411,7 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", chnum, opnum, block_freq, op_detune(opoffs), @@ -427,21 +427,21 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof op_sustain_level(opoffs)); if (OUTPUTS > 1) - end += sprintf(end, " out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-'); if (op_ssg_eg_enable(opoffs)) - end += sprintf(end, " ssg=%X", op_ssg_eg_mode(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ssg=%X", op_ssg_eg_mode(opoffs)); bool am = (op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += sprintf(end, " lfo=%02X", lfo_rate()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); if (multi_freq() && choffs == 2) - end += sprintf(end, " multi=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " multi=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opq.cpp b/src/sound/ymfm/ymfm_opq.cpp index 3467c0ddf9..e6f6fa5ea4 100644 --- a/src/sound/ymfm/ymfm_opq.cpp +++ b/src/sound/ymfm/ymfm_opq.cpp @@ -341,7 +341,7 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, (opoffs & 1) ? ch_block_freq_24(choffs) : ch_block_freq_13(choffs), int32_t(op_detune(opoffs)) - 0x20, @@ -360,14 +360,14 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += sprintf(end, " lfo=%02X", lfo_rate()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); if (ch_reverb(choffs)) - end += sprintf(end, " reverb"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " reverb"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opz.cpp b/src/sound/ymfm/ymfm_opz.cpp index adeefd79f1..a5ec912aad 100644 --- a/src/sound/ymfm/ymfm_opz.cpp +++ b/src/sound/ymfm/ymfm_opz.cpp @@ -557,14 +557,14 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u", chnum, opnum); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u", chnum, opnum); if (op_fix_mode(opoffs)) - end += sprintf(end, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); else - end += sprintf(end, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); - end += sprintf(end, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", op_detune(opoffs), ch_feedback(choffs), ch_algorithm(choffs), @@ -580,32 +580,32 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_output_1(choffs) ? 'R' : '-'); if (op_eg_shift(opoffs) != 0) - end += sprintf(end, " egshift=%u", op_eg_shift(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " egshift=%u", op_eg_shift(opoffs)); bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); bool am2 = (lfo2_am_depth() != 0 && ch_lfo2_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am2) - end += sprintf(end, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); bool pm2 = (lfo2_pm_depth() != 0 && ch_lfo2_pm_sens(choffs) != 0); if (pm2) - end += sprintf(end, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); if (am2 || pm2) - end += sprintf(end, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); if (op_reverb_rate(opoffs) != 0) - end += sprintf(end, " rev=%u", op_reverb_rate(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rev=%u", op_reverb_rate(opoffs)); if (op_waveform(opoffs) != 0) - end += sprintf(end, " wf=%u", op_waveform(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); if (noise_enable() && opoffs == 31) - end += sprintf(end, " noise=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); return buffer; } diff --git a/src/sound/yrw801.h b/src/sound/yrw801.h new file mode 100644 index 0000000000..0df3c03434 --- /dev/null +++ b/src/sound/yrw801.h @@ -0,0 +1,45 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2022 by RoboSoft Inc. + * + * yrw801.h + */ + +/* Cacodemon345: Added pointer structs from Linux */ + +#pragma once + +#include + +typedef struct +{ + uint16_t tone; + int16_t pitch_offset; + uint8_t key_scaling; + int8_t panpot; + uint8_t vibrato; + uint8_t tone_attenuate; + uint8_t volume_factor; + uint8_t reg_lfo_vibrato; + uint8_t reg_attack_decay1; + uint8_t reg_level_decay2; + uint8_t reg_release_correction; + uint8_t reg_tremolo; +} YRW801_WAVE_DATA; + +typedef struct +{ + uint8_t key_min; + uint8_t key_max; + + YRW801_WAVE_DATA wave_data; +} YRW801_REGION_DATA; + +typedef struct +{ + int count; + + const YRW801_REGION_DATA* regions; +} YRW801_REGION_DATA_PTR; + +extern const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81]; \ No newline at end of file diff --git a/src/thread.cpp b/src/thread.cpp index 1b4311f374..f2a0ceaf02 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -14,9 +14,10 @@ struct event_cpp11_t { extern "C" { thread_t * -thread_create(void (*thread_rout)(void *param), void *param) +thread_create_named(void (*thread_rout)(void *param), void *param, const char *name) { - auto thread = new std::thread([thread_rout, param] { + auto thread = new std::thread([thread_rout, param, name] { + plat_set_thread_name(NULL, name); thread_rout(param); }); return thread; diff --git a/src/timer.c b/src/timer.c index 2d75e532ef..fa8376bde3 100644 --- a/src/timer.c +++ b/src/timer.c @@ -15,10 +15,13 @@ pc_timer_t *timer_head = NULL; /* Are we initialized? */ int timer_inited = 0; +static void timer_advance_ex(pc_timer_t *timer, int start); + void timer_enable(pc_timer_t *timer) { pc_timer_t *timer_node = timer_head; + int ret = 0; if (!timer_inited || (timer == NULL)) return; @@ -29,54 +32,56 @@ timer_enable(pc_timer_t *timer) if (timer->next || timer->prev) fatal("timer_enable - timer->next\n"); - timer->flags |= TIMER_ENABLED; - /*List currently empty - add to head*/ if (!timer_head) { timer_head = timer; timer->next = timer->prev = NULL; timer_target = timer_head->ts.ts32.integer; - return; - } - - if (TIMER_LESS_THAN(timer, timer_head)) { + ret = 1; + } else if (TIMER_LESS_THAN(timer, timer_head)) { timer->next = timer_head; timer->prev = NULL; timer_head->prev = timer; timer_head = timer; timer_target = timer_head->ts.ts32.integer; - return; - } - - if (!timer_head->next) { + ret = 1; + } else if (!timer_head->next) { timer_head->next = timer; timer->prev = timer_head; - return; + ret = 1; } - pc_timer_t *prev = timer_head; - timer_node = timer_head->next; - - while (1) { - /*Timer expires before timer_node. Add to list in front of timer_node*/ - if (TIMER_LESS_THAN(timer, timer_node)) { - timer->next = timer_node; - timer->prev = prev; - timer_node->prev = timer; - prev->next = timer; - return; - } - - /*timer_node is last in the list. Add timer to end of list*/ - if (!timer_node->next) { - timer_node->next = timer; - timer->prev = timer_node; - return; + if (ret == 0) { + pc_timer_t *prev = timer_head; + timer_node = timer_head->next; + + while (1) { + /*Timer expires before timer_node. Add to list in front of timer_node*/ + if (TIMER_LESS_THAN(timer, timer_node)) { + timer->next = timer_node; + timer->prev = prev; + timer_node->prev = timer; + prev->next = timer; + ret = 1; + break; + } + + /*timer_node is last in the list. Add timer to end of list*/ + if (!timer_node->next) { + timer_node->next = timer; + timer->prev = timer_node; + ret = 1; + break; + } + + prev = timer_node; + timer_node = timer_node->next; } - - prev = timer_node; - timer_node = timer_node->next; } + + /* Do not mark it as enabled if it has failed every single condition. */ + if (ret == 1) + timer->flags |= TIMER_ENABLED; } void @@ -121,9 +126,12 @@ timer_process(void) timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) - timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ - else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */ - timer->callback(timer->p); + timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into + multiple <= 1 s periods. */ + else if (timer->callback != NULL) /* Make sure it's not NULL, so that we can + have a NULL callback when no operation + is needed. */ + timer->callback(timer->priv); } timer_target = timer_head->ts.ts32.integer; @@ -159,12 +167,12 @@ timer_init(void) } void -timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer) +timer_add(pc_timer_t *timer, void (*callback)(void *priv), void *priv, int start_timer) { memset(timer, 0, sizeof(pc_timer_t)); timer->callback = callback; - timer->p = p; + timer->priv = priv; timer->flags = 0; timer->prev = timer->next = NULL; if (start_timer) @@ -195,7 +203,7 @@ timer_do_period(pc_timer_t *timer, uint64_t period, int start) timer_advance_u64(timer, period); } -void +static void timer_advance_ex(pc_timer_t *timer, int start) { if (!timer_inited || (timer == NULL)) @@ -215,7 +223,7 @@ timer_advance_ex(pc_timer_t *timer, int start) } } -void +static void timer_on(pc_timer_t *timer, double period, int start) { if (!timer_inited || (timer == NULL)) @@ -232,7 +240,7 @@ timer_on_auto(pc_timer_t *timer, double period) return; if (period > 0.0) - timer_on(timer, period, (timer->period == 0.0)); + timer_on(timer, period, timer->period <= 0.0); else timer_stop(timer); } diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index ede0d5bb61..99d01c5945 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 3.11 +%global romver 4.1 Name: 86Box -Version: 4.0 +Version: 4.1.1 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -27,11 +27,14 @@ Source1: https://github.com/86Box/roms/archive/refs/tags/v%{romver}.zip BuildRequires: cmake BuildRequires: desktop-file-utils BuildRequires: extra-cmake-modules +BuildRequires: fluidsynth-devel BuildRequires: freetype-devel BuildRequires: gcc-c++ BuildRequires: libFAudio-devel BuildRequires: libappstream-glib +BuildRequires: libatomic BuildRequires: libevdev-devel +BuildRequires: libslirp-devel BuildRequires: libxkbcommon-x11-devel BuildRequires: libXi-devel BuildRequires: ninja-build @@ -118,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Tue Feb 28 2023 Robert de Rooy 4.0-1 +* Fri Feb 23 2024 Robert de Rooy 4.1.1-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 59671d0f92..7602ffb11e 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + diff --git a/src/unix/unix.c b/src/unix/unix.c index 8bddc5346d..6c21bfa45c 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -21,6 +21,10 @@ #include #include +#ifdef __APPLE__ +# include "macOSXGlue.h" +#endif + #include <86box/86box.h> #include <86box/mem.h> #include <86box/rom.h> @@ -36,13 +40,13 @@ #include <86box/unix_sdl.h> #include <86box/timer.h> #include <86box/nvr.h> +#include <86box/version.h> #include <86box/video.h> #include <86box/ui.h> #include <86box/gdbstub.h> -#ifdef __APPLE__ -# include "macOSXGlue.h" -#endif +#define __USE_GNU 1 /* shouldn't be done, yet it is */ +#include static int first_use = 1; static uint64_t StartingTime; @@ -190,6 +194,7 @@ dynld_module(const char *name, dllimp_t *table) { dllimp_t *imp; void *modhandle = dlopen(name, RTLD_LAZY | RTLD_GLOBAL); + if (modhandle) { for (imp = table; imp->name != NULL; imp++) { if ((*(void **) imp->func = dlsym(modhandle, imp->name)) == NULL) { @@ -198,6 +203,7 @@ dynld_module(const char *name, dllimp_t *table) } } } + return modhandle; } @@ -246,8 +252,6 @@ plat_get_string(int i) return L"Press CTRL-END to release mouse"; case IDS_2079: return L"Press CTRL-END or middle button to release mouse"; - case IDS_2080: - return L"Failed to initialize FluidSynth"; case IDS_2131: return L"Invalid configuration"; case IDS_4099: @@ -258,16 +262,8 @@ plat_get_string(int i) return L"No PCap devices found"; case IDS_2096: return L"Invalid PCap device"; - case IDS_2111: - return L"Unable to initialize FreeType"; - case IDS_2112: - return L"Unable to initialize SDL, libsdl2 is required"; - case IDS_2132: - return L"libfreetype is required for ESC/P printer emulation."; case IDS_2133: return L"libgs is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."; - case IDS_2134: - return L"libfluidsynth is required for FluidSynth MIDI output."; case IDS_2130: return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; case IDS_2115: @@ -317,6 +313,17 @@ path_slash(char *path) path_normalize(path); } +const char * +path_get_slash(char *path) +{ + char *ret = ""; + + if (path[strlen(path) - 1] != '/') + ret = "/"; + + return ret; +} + void plat_put_backslash(char *s) { @@ -401,7 +408,7 @@ plat_mmap(size_t size, uint8_t executable) #if defined __APPLE__ && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); #else - void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); #endif return (ret < 0) ? NULL : ret; } @@ -423,6 +430,7 @@ plat_get_ticks_common(void) { uint64_t EndingTime; uint64_t ElapsedMicroseconds; + if (first_use) { Frequency = SDL_GetPerformanceFrequency(); StartingTime = SDL_GetPerformanceCounter(); @@ -430,6 +438,7 @@ plat_get_ticks_common(void) } EndingTime = SDL_GetPerformanceCounter(); ElapsedMicroseconds = ((EndingTime - StartingTime) * 1000000) / Frequency; + return ElapsedMicroseconds; } @@ -454,11 +463,13 @@ plat_remove(char *path) void ui_sb_update_icon_state(int tag, int state) { + /* No-op. */ } void ui_sb_update_icon(int tag, int active) { + /* No-op. */ } void @@ -470,25 +481,26 @@ plat_delay_ms(uint32_t count) void ui_sb_update_tip(int arg) { + /* No-op. */ } void ui_sb_update_panes(void) { + /* No-op. */ } void ui_sb_update_text(void) { + /* No-op. */ } void path_get_dirname(char *dest, const char *path) { int c = (int) strlen(path); - char *ptr; - - ptr = (char *) path; + char *ptr = (char *) path; while (c > 0) { if (path[c] == '/' || path[c] == '\\') { @@ -507,6 +519,7 @@ volatile int cpu_thread_run = 1; void ui_sb_set_text_w(wchar_t *wstr) { + /* No-op. */ } int @@ -630,12 +643,14 @@ ui_msgbox_header(int flags, void *header, void *message) { SDL_MessageBoxData msgdata; SDL_MessageBoxButtonData msgbtn; + if (!header) - header = (void *) (flags & MBX_ANSI) ? "86Box" : L"86Box"; + header = (void *) ((flags & MBX_ANSI) ? "86Box" : L"86Box"); if (header <= (void *) 7168) - header = (void *) plat_get_string((int) header); + header = (void *) plat_get_string((uintptr_t) header); if (message <= (void *) 7168) - message = (void *) plat_get_string((int) message); + message = (void *) plat_get_string((uintptr_t) message); + msgbtn.buttonid = 1; msgbtn.text = "OK"; msgbtn.flags = 0; @@ -675,6 +690,7 @@ void plat_get_exe_name(char *s, int size) { char *basepath = SDL_GetBasePath(); + snprintf(s, size, "%s%s", basepath, basepath[strlen(basepath) - 1] == '/' ? "86box" : "/86box"); } @@ -695,6 +711,7 @@ plat_power_off(void) void ui_sb_bugui(char *str) { + /* No-op. */ } extern void sdl_blit(int x, int y, int w, int h); @@ -705,26 +722,17 @@ typedef struct mouseinputdata { int deltaz; int mousebuttons; } mouseinputdata; -SDL_mutex *mousemutex; -static mouseinputdata mousedata; -void -mouse_poll(void) -{ - SDL_LockMutex(mousemutex); - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; - mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; - SDL_UnlockMutex(mousemutex); -} -int real_sdl_w; -int real_sdl_h; +SDL_mutex *mousemutex; +int real_sdl_w; +int real_sdl_h; + void ui_sb_set_ready(int ready) { + /* No-op. */ } + char *xargv[512]; // From musl. @@ -733,6 +741,7 @@ local_strsep(char **str, const char *sep) { char *s = *str; char *end; + if (!s) return NULL; end = s + strcspn(s, sep); @@ -741,6 +750,7 @@ local_strsep(char **str, const char *sep) else end = 0; *str = end; + return s; } @@ -750,10 +760,13 @@ plat_pause(int p) static wchar_t oldtitle[512]; wchar_t title[512]; + if ((!!p) == dopause) + return; + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) nvr_time_sync(); - dopause = p; + do_pause(p); if (p) { wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); wcscpy(title, oldtitle); @@ -770,6 +783,7 @@ plat_init_rom_paths(void) #ifndef __APPLE__ if (getenv("XDG_DATA_HOME")) { char xdg_rom_path[1024] = { 0 }; + strncpy(xdg_rom_path, getenv("XDG_DATA_HOME"), 1024); path_slash(xdg_rom_path); strncat(xdg_rom_path, "86Box/", 1024); @@ -783,6 +797,7 @@ plat_init_rom_paths(void) rom_add_path(xdg_rom_path); } else { char home_rom_path[1024] = { 0 }; + snprintf(home_rom_path, 1024, "%s/.local/share/86Box/", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir); if (!plat_dir_check(home_rom_path)) @@ -797,11 +812,12 @@ plat_init_rom_paths(void) char *xdg_rom_paths = strdup(getenv("XDG_DATA_DIRS")); char *xdg_rom_paths_orig = xdg_rom_paths; char *cur_xdg_rom_path = NULL; + if (xdg_rom_paths) { while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') { xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0'; } - while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ";")) != NULL) { + while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ":")) != NULL) { char real_xdg_rom_path[1024] = { '\0' }; strcat(real_xdg_rom_path, cur_xdg_rom_path); path_slash(real_xdg_rom_path); @@ -815,7 +831,7 @@ plat_init_rom_paths(void) rom_add_path("/usr/share/86Box/roms/"); } #else - char default_rom_path[1024] = { '\0 ' }; + char default_rom_path[1024] = { '\0' }; getDefaultROMPath(default_rom_path); rom_add_path(default_rom_path); #endif @@ -837,7 +853,9 @@ bool process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) { bool err = false; + *id = atoi(xargv[1]); + if (xargv[2][0] == '\'' || xargv[2][0] == '"') { for (int curarg = 2; curarg < cmdargc; curarg++) { if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { @@ -877,6 +895,7 @@ void (*f_rl_callback_handler_remove)(void) = NULL; #else # define LIBEDIT_LIBRARY "libedit.so" #endif + uint32_t timer_onesec(uint32_t interval, void *param) { @@ -891,19 +910,25 @@ monitor_thread(void *param) if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { char *line = NULL; size_t n; + printf("86Box monitor console.\n"); while (!exit_event) { if (feof(stdin)) break; +#ifdef ENABLE_READLINE if (f_readline) line = f_readline("(86Box) "); else { +#endif printf("(86Box) "); - getline(&line, &n, stdin); + (void) !getline(&line, &n, stdin); +#ifdef ENABLE_READLINE } +#endif if (line) { int cmdargc = 0; char *linecpy; + line[strcspn(line, "\r\n")] = '\0'; linecpy = strdup(line); if (!linecpy) { @@ -935,9 +960,46 @@ monitor_thread(void *param) "hardreset - hard reset the emulated system.\n" "pause - pause the the emulated system.\n" "fullscreen - toggle fullscreen.\n" + "version - print version and license information.\n" "exit - exit 86Box.\n"); } else if (strncasecmp(xargv[0], "exit", 4) == 0) { exit_event = 1; + } else if (strncasecmp(xargv[0], "version", 7) == 0) { +# ifndef EMU_GIT_HASH +# define EMU_GIT_HASH "0000000" +# endif + +# if defined(__arm__) || defined(__TARGET_ARCH_ARM) +# define ARCH_STR "arm" +# elif defined(__aarch64__) || defined(_M_ARM64) +# define ARCH_STR "arm64" +# elif defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define ARCH_STR "i386" +# elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define ARCH_STR "x86_64" +# else +# define ARCH_STR "unknown arch" +# endif + +# ifdef USE_DYNAREC +# ifdef USE_NEW_DYNAREC +# define DYNAREC_STR "new dynarec" +# else +# define DYNAREC_STR "old dynarec" +# endif +# else +# define DYNAREC_STR "no dynarec" +# endif + + printf( + "%s v%s [%s] [%s, %s]\n\n" + "An emulator of old computers\n" + "Authors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), " + "Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), " + "Tiseno100, reenigne, and others.\n" + "With previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n" + "Released under the GNU General Public License version 2 or later. See LICENSE for more information.\n", + EMU_NAME, EMU_VERSION_FULL, EMU_GIT_HASH, ARCH_STR, DYNAREC_STR); } else if (strncasecmp(xargv[0], "fullscreen", 10) == 0) { video_fullscreen = video_fullscreen ? 0 : 1; fullscreen_pending = 1; @@ -961,6 +1023,7 @@ monitor_thread(void *param) memset(fn, 0, sizeof(fn)); if (xargv[2][0] == '\'' || xargv[2][0] == '"') { int curarg = 2; + for (curarg = 2; curarg < cmdargc; curarg++) { if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { err = true; @@ -1003,7 +1066,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1023,7 +1088,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1043,7 +1110,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1063,7 +1132,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1094,9 +1165,12 @@ main(int argc, char **argv) { SDL_Event event; void *libedithandle; + int ret = 0; SDL_Init(0); - pc_init(argc, argv); + ret = pc_init(argc, argv); + if (ret == 0) + return 0; if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, L"No ROMs found.", L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."); SDL_Quit(); @@ -1131,7 +1205,7 @@ main(int argc, char **argv) pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ - // plat_pause(0); + plat_pause(0); /* Initialize the rendering window, or fullscreen. */ @@ -1142,6 +1216,7 @@ main(int argc, char **argv) SDL_AddTimer(1000, timer_onesec, NULL); while (!is_quit) { static int mouse_inside = 0; + while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: @@ -1155,7 +1230,7 @@ main(int argc, char **argv) event.wheel.y *= -1; } SDL_LockMutex(mousemutex); - mousedata.deltaz = event.wheel.y; + mouse_set_z(event.wheel.y); SDL_UnlockMutex(mousemutex); } break; @@ -1164,8 +1239,7 @@ main(int argc, char **argv) { if (mouse_capture || video_fullscreen) { SDL_LockMutex(mousemutex); - mousedata.deltax += event.motion.xrel; - mousedata.deltay += event.motion.yrel; + mouse_scale(event.motion.xrel, event.motion.yrel); SDL_UnlockMutex(mousemutex); } break; @@ -1205,10 +1279,10 @@ main(int argc, char **argv) break; } SDL_LockMutex(mousemutex); - if (event.button.state == SDL_PRESSED) { - mousedata.mousebuttons |= buttonmask; - } else - mousedata.mousebuttons &= ~buttonmask; + if (event.button.state == SDL_PRESSED) + mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); + else + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); SDL_UnlockMutex(mousemutex); } break; @@ -1217,6 +1291,7 @@ main(int argc, char **argv) case SDL_RENDER_TARGETS_RESET: { extern void sdl_reinit_texture(void); + sdl_reinit_texture(); break; } @@ -1224,6 +1299,7 @@ main(int argc, char **argv) case SDL_KEYUP: { uint16_t xtkey = 0; + switch (event.key.keysym.scancode) { default: xtkey = sdl_to_xt[event.key.keysym.scancode]; @@ -1296,6 +1372,31 @@ plat_language_code(char *langcode) return 0; } +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + char cpu_string[] = "Unknown"; + + strncpy(outbuf, cpu_string, len); +} + +void +plat_set_thread_name(void *thread, const char *name) +{ +#ifdef __APPLE__ + if (thread) /* Apple pthread can only set self's name */ + return; + char truncated[64]; +#else + char truncated[16]; +#endif + strncpy(truncated, name, sizeof(truncated) - 1); +#ifdef __APPLE__ + pthread_setname_np(truncated); +#else + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); +#endif +} + /* Converts back the language code to LCID */ void plat_language_code_r(uint32_t lcid, char *outbuf, int len) @@ -1307,15 +1408,21 @@ plat_language_code_r(uint32_t lcid, char *outbuf, int len) void joystick_init(void) { + /* No-op. */ } + void joystick_close(void) { + /* No-op. */ } + void joystick_process(void) { + /* No-op. */ } + void startblit(void) { @@ -1332,9 +1439,11 @@ endblit(void) void ui_sb_mt32lcd(char *str) { + /* No-op. */ } void ui_hard_reset_completed(void) { + /* No-op. */ } diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 7ba2471089..61813a7540 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -10,8 +10,7 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * * Copyright 2016-2018 Miran Grca. @@ -146,6 +145,8 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); + if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\')) + fn[strlen(fn) - 1] = '/'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ if (cdrom[id].insert) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 4cf723b00c..3ba8c1ae01 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -51,10 +51,7 @@ int title_set = 0; int resize_pending = 0; int resize_w = 0; int resize_h = 0; -double mouse_sensitivity = 1.0; /* Unused. */ -double mouse_x_error = 0.0; /* Unused. */ -double mouse_y_error = 0.0; /* Unused. */ -static uint8_t interpixels[17842176]; +static void *pixeldata; extern void RenderImGui(void); static void @@ -153,11 +150,15 @@ sdl_blit_shim(int x, int y, int w, int h, int monitor_index) params.y = y; params.w = w; params.h = h; + if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) || (monitor_index >= 1)) - video_copy(interpixels, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); - if (screenshots) - video_screenshot(interpixels, 0, 0, 2048); + for (int row = 0; row < h; ++row) + video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); + + if (monitors[monitor_index].mon_screenshots) + video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); blitreq = 1; + video_blit_complete_monitor(monitor_index); } @@ -170,6 +171,7 @@ sdl_real_blit(SDL_Rect *r_src) int ret; int winx; int winy; + SDL_GL_GetDrawableSize(sdl_win, &winx, &winy); SDL_RenderClear(sdl_render); @@ -216,7 +218,7 @@ sdl_blit(int x, int y, int w, int h) r_src.y = y; r_src.w = w; r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, interpixels, 2048 * 4); + SDL_UpdateTexture(sdl_tex, &r_src, pixeldata, 2048 * 4); blitreq = 0; sdl_real_blit(&r_src); @@ -268,13 +270,16 @@ sdl_close(void) sdl_destroy_texture(); sdl_destroy_window(); + if (pixeldata != NULL) { + free(pixeldata); + pixeldata = NULL; + } + /* Quit. */ SDL_Quit(); sdl_flags = -1; } -static int old_capture = 0; - void sdl_enable(int enable) { @@ -395,7 +400,6 @@ plat_vidapi(char *api) static int sdl_init_common(int flags) { - wchar_t temp[128]; SDL_version ver; /* Get and log the version of the DLL we are using. */ @@ -431,6 +435,8 @@ sdl_init_common(int flags) /* Make sure we get a clean exit. */ atexit(sdl_close); + pixeldata = malloc(2048 * 2048 * 4); + /* Register our renderer! */ video_setblit(sdl_blit_shim); @@ -529,10 +535,13 @@ ui_window_title(wchar_t *str) void ui_init_monitor(int monitor_index) { + /* No-op. */ } + void ui_deinit_monitor(int monitor_index) { + /* No-op. */ } void diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 61f23c3459..d80f8a1e72 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -45,9 +45,9 @@ #define LOG_PREFIX "serial_passthrough: " int -plat_serpt_read(void *p, uint8_t *data) +plat_serpt_read(void *priv, uint8_t *data) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; int res; struct timeval tv; fd_set rdfds; @@ -76,9 +76,9 @@ plat_serpt_read(void *p, uint8_t *data) } void -plat_serpt_close(void *p) +plat_serpt_close(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode == SERPT_MODE_HOSTSER) { tcsetattr(dev->master_fd, TCSANOW, (struct termios *) dev->backend_priv); @@ -94,6 +94,7 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) fd_set wrfds; int res; #endif + size_t res; /* We cannot use select here, this would block the hypervisor! */ #if 0 @@ -109,18 +110,17 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) /* just write it out */ if (dev->mode == SERPT_MODE_HOSTSER) { - int res = 0; do { res = write(dev->master_fd, &data, 1); } while (res == 0 || (res == -1 && (errno == EAGAIN || res == EWOULDBLOCK))); } else - write(dev->master_fd, &data, 1); + res = write(dev->master_fd, &data, 1); } void -plat_serpt_set_params(void *p) +plat_serpt_set_params(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode == SERPT_MODE_HOSTSER) { struct termios term_attr; @@ -149,7 +149,7 @@ plat_serpt_set_params(void *p) BAUDRATE_RANGE(dev->baudrate, 57600, 115200, B57600); BAUDRATE_RANGE(dev->baudrate, 115200, 0xFFFFFFFF, B115200); - term_attr.c_cflag &= CSIZE; + term_attr.c_cflag &= ~CSIZE; switch (dev->data_bits) { case 8: default: @@ -165,13 +165,13 @@ plat_serpt_set_params(void *p) term_attr.c_cflag |= CS5; break; } - term_attr.c_cflag &= CSTOPB; + term_attr.c_cflag &= ~CSTOPB; if (dev->serial->lcr & 0x04) term_attr.c_cflag |= CSTOPB; #if !defined(__linux__) - term_attr.c_cflag &= PARENB | PARODD; + term_attr.c_cflag &= ~(PARENB | PARODD); #else - term_attr.c_cflag &= PARENB | PARODD | CMSPAR; + term_attr.c_cflag &= ~(PARENB | PARODD | CMSPAR); #endif if (dev->serial->lcr & 0x08) { term_attr.c_cflag |= PARENB; @@ -188,9 +188,9 @@ plat_serpt_set_params(void *p) } void -plat_serpt_write(void *p, uint8_t data) +plat_serpt_write(void *priv, uint8_t data) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { case SERPT_MODE_VCON: @@ -297,9 +297,9 @@ open_host_serial_port(serial_passthrough_t *dev) } int -plat_serpt_open_device(void *p) +plat_serpt_open_device(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { case SERPT_MODE_VCON: diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c index 0c2e9bf6b7..88ce014567 100644 --- a/src/unix/unix_thread.c +++ b/src/unix/unix_thread.c @@ -32,7 +32,7 @@ thread_run_wrapper(thread_param *arg) } thread_t * -thread_create(void (*thread_rout)(void *param), void *param) +thread_create_named(void (*thread_rout)(void *param), void *param, const char *name) { pthread_t *thread = malloc(sizeof(pthread_t)); thread_param *thrparam = malloc(sizeof(thread_param)); @@ -40,6 +40,7 @@ thread_create(void (*thread_rout)(void *param), void *param) thrparam->param = param; pthread_create(thread, NULL, (void *(*) (void *) ) thread_run_wrapper, thrparam); + plat_set_thread_name(thread, name); return thread; } @@ -51,7 +52,7 @@ thread_wait(thread_t *arg) } event_t * -thread_create_event() +thread_create_event(void) { event_pthread_t *event = malloc(sizeof(event_pthread_t)); diff --git a/src/upi42.c b/src/upi42.c index e35a0752ff..50f5c44c93 100644 --- a/src/upi42.c +++ b/src/upi42.c @@ -18,6 +18,7 @@ #include #include #include +#include <86box/plat_unused.h> #ifdef UPI42_STANDALONE # define fatal(...) \ @@ -160,7 +161,7 @@ upi42_op_MOV_A_imm(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_MOV_A_PSW(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOV_A_PSW(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = upi42->psw; upi42_mirror_f0(upi42); @@ -168,7 +169,7 @@ upi42_op_MOV_A_PSW(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_MOV_PSW_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOV_PSW_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw = upi42->a; upi42_mirror_f0(upi42); @@ -176,28 +177,28 @@ upi42_op_MOV_PSW_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_MOV_A_T(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOV_A_T(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = upi42->t; return 1; } static int -upi42_op_MOV_T_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOV_T_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->t = upi42->a; return 1; } static int -upi42_op_MOV_STS_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOV_STS_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->sts = (upi42->a & 0xf0) | (upi42->sts & 0x0f); return 1; } static int -upi42_op_MOVP_A_indA(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOVP_A_indA(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = upi42->rom[(upi42->pc & 0xff00) | upi42->a]; upi42->cycs--; @@ -205,7 +206,7 @@ upi42_op_MOVP_A_indA(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_MOVP3_A_indA(upi42_t *upi42, uint32_t fetchdat) +upi42_op_MOVP3_A_indA(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = upi42->rom[0x300 | upi42->a]; upi42->cycs--; @@ -242,7 +243,7 @@ upi42_op_XCHD_A_indRr(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_SWAP_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_SWAP_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = (upi42->a << 4) | (upi42->a >> 4); return 1; @@ -258,7 +259,7 @@ upi42_op_IN_A_Pp(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_IN_A_DBB(upi42_t *upi42, uint32_t fetchdat) +upi42_op_IN_A_DBB(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = upi42->dbb_in; upi42->sts &= ~0x02; /* clear IBF */ @@ -266,7 +267,7 @@ upi42_op_IN_A_DBB(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_OUTL_Pp_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_OUTL_Pp_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->ports_out[fetchdat & 3] = upi42->a; upi42->cycs--; @@ -274,7 +275,7 @@ upi42_op_OUTL_Pp_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_OUT_DBB_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_OUT_DBB_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->dbb_out = upi42->a; upi42->sts |= 0x01; /* set OBF */ @@ -397,21 +398,21 @@ upi42_op_ORLD_Pp_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_RR_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_RR_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = (upi42->a << 7) | (upi42->a >> 1); return 1; } static int -upi42_op_RL_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_RL_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = (upi42->a >> 7) | (upi42->a << 1); return 1; } static int -upi42_op_RRC_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_RRC_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { uint8_t temp = upi42->a; upi42->a = (upi42->psw & 0x80) | (temp >> 1); @@ -420,7 +421,7 @@ upi42_op_RRC_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_RLC_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_RLC_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { uint8_t temp = upi42->a; upi42->a = (temp << 1) | (upi42->psw >> 7); @@ -429,7 +430,7 @@ upi42_op_RLC_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_INC_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_INC_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a++; return 1; @@ -450,7 +451,7 @@ upi42_op_INC_indRr(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_DEC_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_DEC_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a--; return 1; @@ -533,21 +534,21 @@ upi42_op_ADDC_A_imm(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_CLR_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CLR_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = 0; return 1; } static int -upi42_op_CPL_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CPL_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->a = ~upi42->a; return 1; } static int -upi42_op_DA_A(upi42_t *upi42, uint32_t fetchdat) +upi42_op_DA_A(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { if (((upi42->a & 0x0f) > 9) || (upi42->psw & 0x40)) upi42->a += 6; @@ -560,21 +561,21 @@ upi42_op_DA_A(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_CLR_C(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CLR_C(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw &= ~0x80; return 1; } static int -upi42_op_CPL_C(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CPL_C(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw ^= 0x80; return 1; } static int -upi42_op_CLR_F0(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CLR_F0(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw &= ~0x20; upi42_mirror_f0(upi42); @@ -582,7 +583,7 @@ upi42_op_CLR_F0(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_CPL_F0(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CPL_F0(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw ^= 0x20; upi42_mirror_f0(upi42); @@ -590,21 +591,21 @@ upi42_op_CPL_F0(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_CLR_F1(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CLR_F1(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->sts &= ~0x08; return 1; } static int -upi42_op_CPL_F1(upi42_t *upi42, uint32_t fetchdat) +upi42_op_CPL_F1(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->sts ^= 0x08; return 1; } static int -upi42_op_EN_I(upi42_t *upi42, uint32_t fetchdat) +upi42_op_EN_I(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->i = 1; upi42->skip_timer_inc = 1; @@ -612,7 +613,7 @@ upi42_op_EN_I(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_DIS_I(upi42_t *upi42, uint32_t fetchdat) +upi42_op_DIS_I(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->i = 0; upi42->skip_timer_inc = 1; @@ -620,21 +621,21 @@ upi42_op_DIS_I(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_EN_TCNTI(upi42_t *upi42, uint32_t fetchdat) +upi42_op_EN_TCNTI(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->tcnti = 1; return 1; } static int -upi42_op_DIS_TCNTI(upi42_t *upi42, uint32_t fetchdat) +upi42_op_DIS_TCNTI(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->tcnti = upi42->tcnti_raise = 0; return 1; } static int -upi42_op_STRT_T(upi42_t *upi42, uint32_t fetchdat) +upi42_op_STRT_T(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->run_timer = 1; upi42->prescaler = 0; @@ -643,7 +644,7 @@ upi42_op_STRT_T(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_STRT_CNT(upi42_t *upi42, uint32_t fetchdat) +upi42_op_STRT_CNT(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->run_counter = 1; upi42->skip_timer_inc = 1; @@ -651,7 +652,7 @@ upi42_op_STRT_CNT(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_STOP_TCNT(upi42_t *upi42, uint32_t fetchdat) +upi42_op_STOP_TCNT(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->run_timer = upi42->run_counter = 0; upi42->skip_timer_inc = 1; @@ -659,35 +660,35 @@ upi42_op_STOP_TCNT(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_SEL_PMB0(upi42_t *upi42, uint32_t fetchdat) +upi42_op_SEL_PMB0(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->dbf = 0; return 1; } static int -upi42_op_SEL_PMB1(upi42_t *upi42, uint32_t fetchdat) +upi42_op_SEL_PMB1(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->dbf = 1; return 1; } static int -upi42_op_SEL_RB0(upi42_t *upi42, uint32_t fetchdat) +upi42_op_SEL_RB0(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw &= ~0x10; return 1; } static int -upi42_op_SEL_RB1(upi42_t *upi42, uint32_t fetchdat) +upi42_op_SEL_RB1(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->psw |= 0x10; return 1; } static int -upi42_op_NOP(upi42_t *upi42, uint32_t fetchdat) +upi42_op_NOP(UNUSED(upi42_t *upi42), UNUSED(uint32_t fetchdat)) { return 1; } @@ -741,7 +742,7 @@ upi42_op_JMP_imm(upi42_t *upi42, uint32_t fetchdat) } static int -upi42_op_JMPP_indA(upi42_t *upi42, uint32_t fetchdat) +upi42_op_JMPP_indA(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->pc = (upi42->pc & 0xff00) | upi42->a; upi42->cycs--; @@ -774,27 +775,27 @@ UPI42_COND_JMP_IMM(JNIBF, !(upi42->sts & 0x02), ) UPI42_COND_JMP_IMM(JOBF, upi42->sts & 0x01, ) static int -upi42_op_EN_A20(upi42_t *upi42, uint32_t fetchdat) +upi42_op_EN_A20(UNUSED(upi42_t *upi42), UNUSED(uint32_t fetchdat)) { /* Enable fast A20 until reset. */ return 1; } static int -upi42_op_EN_DMA(upi42_t *upi42, uint32_t fetchdat) +upi42_op_EN_DMA(UNUSED(upi42_t *upi42), UNUSED(uint32_t fetchdat)) { return 1; } static int -upi42_op_EN_FLAGS(upi42_t *upi42, uint32_t fetchdat) +upi42_op_EN_FLAGS(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { upi42->flags = 1; return 1; } static int -upi42_op_SUSPEND(upi42_t *upi42, uint32_t fetchdatr) +upi42_op_SUSPEND(upi42_t *upi42, UNUSED(uint32_t fetchdat)) { /* Inhibit execution until reset. */ upi42->suspend = 1; @@ -915,7 +916,7 @@ upi42_exec(void *priv) uint8_t upi42_port_read(void *priv, int port) { - upi42_t *upi42 = (upi42_t *) priv; + const upi42_t *upi42 = (upi42_t *) priv; /* Read base port value. */ port &= 7; @@ -923,6 +924,8 @@ upi42_port_read(void *priv, int port) /* Apply special meanings. */ switch (port) { + default: + break; } upi42_log("UPI42: port_read(%d) = %02X\n", port, ret); @@ -944,7 +947,7 @@ upi42_port_write(void *priv, int port, uint8_t val) /* NOTE: The dbb/sts/cmd functions use I/O handler signatures; port is ignored. */ uint8_t -upi42_dbb_read(uint16_t port, void *priv) +upi42_dbb_read(UNUSED(uint16_t port), void *priv) { upi42_t *upi42 = (upi42_t *) priv; @@ -955,7 +958,7 @@ upi42_dbb_read(uint16_t port, void *priv) } void -upi42_dbb_write(uint16_t port, uint8_t val, void *priv) +upi42_dbb_write(UNUSED(uint16_t port), uint8_t val, void *priv) { upi42_t *upi42 = (upi42_t *) priv; @@ -967,9 +970,9 @@ upi42_dbb_write(uint16_t port, uint8_t val, void *priv) } uint8_t -upi42_sts_read(uint16_t port, void *priv) +upi42_sts_read(UNUSED(uint16_t port), void *priv) { - upi42_t *upi42 = (upi42_t *) priv; + const upi42_t *upi42 = (upi42_t *) priv; uint8_t ret = upi42->sts; upi42_log("UPI42: sts_read(%04X) = %02X\n", port, ret); @@ -977,7 +980,7 @@ upi42_sts_read(uint16_t port, void *priv) } void -upi42_cmd_write(uint16_t port, uint8_t val, void *priv) +upi42_cmd_write(UNUSED(uint16_t port), uint8_t val, void *priv) { upi42_t *upi42 = (upi42_t *) priv; @@ -1053,13 +1056,13 @@ main(int argc, char **argv) /* Load ROM. */ uint8_t rom[4096] = { 0 }; - FILE *f = fopen(argv[1], "rb"); - if (!f) { + FILE *fp = fopen(argv[1], "rb"); + if (!fp) { upi42_log("Could not read ROM file.\n"); return 2; } - size_t rom_size = fread(rom, sizeof(rom[0]), sizeof(rom), f); - fclose(f); + size_t rom_size = fread(rom, sizeof(rom[0]), sizeof(rom), fp); + fclose(fp); /* Determine chip type from ROM. */ upi42_log("%d-byte ROM, ", rom_size); diff --git a/src/usb.c b/src/usb.c index 5f2b95084d..6bdc8e6c00 100644 --- a/src/usb.c +++ b/src/usb.c @@ -20,17 +20,15 @@ #include #include #include -#include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> -#include <86box/timer.h> #include <86box/usb.h> -#include <86box/dma.h> +#include "cpu.h" +#include <86box/plat_unused.h> #ifdef ENABLE_USB_LOG int usb_do_log = ENABLE_USB_LOG; @@ -50,108 +48,12 @@ usb_log(const char *fmt, ...) # define usb_log(fmt, ...) #endif -/* OHCI registers */ -enum -{ - OHCI_HcRevision = 0x00 /* 0x00 */, - OHCI_HcControl = 0x01 /* 0x04 */, - OHCI_HcCommandStatus = 0x02 /* 0x08 */, - OHCI_HcInterruptStatus = 0x03 /* 0x0c */, - OHCI_HcInterruptEnable = 0x04 /* 0x10 */, - OHCI_HcInterruptDisable = 0x05 /* 0x14 */, - OHCI_HcHCCA = 0x06 /* 0x18 */, - OHCI_HcPeriodCurrentED = 0x07 /* 0x1c */, - OHCI_HcControlHeadED = 0x08 /* 0x20 */, - OHCI_HcControlCurrentED = 0x09 /* 0x24 */, - OHCI_HcBulkHeadED = 0x0a /* 0x28 */, - OHCI_HcBulkCurrentED = 0x0b /* 0x2c */, - OHCI_HcDoneHead = 0x0c /* 0x30 */, - OHCI_HcFmInterval = 0x0d /* 0x34 */, - OHCI_HcFmRemaining = 0x0e /* 0x38 */, - OHCI_HcFmNumber = 0x0f /* 0x3c */, - OHCI_HcPeriodicStart = 0x10 /* 0x40 */, - OHCI_HcLSThreshold = 0x11 /* 0x44 */, - OHCI_HcRhDescriptorA = 0x12 /* 0x48 */, - OHCI_HcRhDescriptorB = 0x13 /* 0x4c */, - OHCI_HcRhStatus = 0x14 /* 0x50 */, - OHCI_HcRhPortStatus1 = 0x15 /* 0x54 */, - OHCI_HcRhPortStatus2 = 0x16 /* 0x58 */, - OHCI_HcRhPortStatus3 = 0x17 /* 0x5c */ -}; - -enum -{ - OHCI_aHcRevision = 0x00, - OHCI_aHcControl = 0x04, - OHCI_aHcCommandStatus = 0x08, - OHCI_aHcInterruptStatus = 0x0c, - OHCI_aHcInterruptEnable = 0x10, - OHCI_aHcInterruptDisable = 0x14, - OHCI_aHcHCCA = 0x18, - OHCI_aHcPeriodCurrentED = 0x1c, - OHCI_aHcControlHeadED = 0x20, - OHCI_aHcControlCurrentED = 0x24, - OHCI_aHcBulkHeadED = 0x28, - OHCI_aHcBulkCurrentED = 0x2c, - OHCI_aHcDoneHead = 0x30, - OHCI_aHcFmInterval = 0x34, - OHCI_aHcFmRemaining = 0x38, - OHCI_aHcFmNumber = 0x3c, - OHCI_aHcPeriodicStart = 0x40, - OHCI_aHcLSThreshold = 0x44, - OHCI_aHcRhDescriptorA = 0x48, - OHCI_aHcRhDescriptorB = 0x4c, - OHCI_aHcRhStatus = 0x50, - OHCI_aHcRhPortStatus1 = 0x54, - OHCI_aHcRhPortStatus2 = 0x58, - OHCI_aHcRhPortStatus3 = 0x5c -}; - -/* OHCI HcInterruptEnable/Disable bits */ -enum -{ - OHCI_HcInterruptEnable_SO = 1 << 0, - OHCI_HcInterruptEnable_WDH = 1 << 1, - OHCI_HcInterruptEnable_SF = 1 << 2, - OHCI_HcInterruptEnable_RD = 1 << 3, - OHCI_HcInterruptEnable_UE = 1 << 4, - OHCI_HcInterruptEnable_HNO = 1 << 5, - OHCI_HcInterruptEnable_RHSC = 1 << 6, -}; - -/* OHCI HcControl bits */ -enum -{ - OHCI_HcControl_ControlBulkServiceRatio = 1 << 0, - OHCI_HcControl_PeriodicListEnable = 1 << 1, - OHCI_HcControl_IsochronousEnable = 1 << 2, - OHCI_HcControl_ControlListEnable = 1 << 3, - OHCI_HcControl_BulkListEnable = 1 << 4 -}; - -usb_t* usb_device_inst = NULL; - -static void -usb_interrupt_ohci(usb_t *dev, uint32_t level) -{ - if (dev->ohci_mmio[OHCI_HcControl].b[1] & 1) { - if (dev->usb_params && dev->usb_params->smi_handle && !dev->usb_params->smi_handle(dev, dev->usb_params->parent_priv)) - return; - - if (level) - smi_raise(); - } else if (dev->usb_params != NULL) { - if ((dev->usb_params->parent_priv != NULL) && (dev->usb_params->update_interrupt != NULL)) - dev->usb_params->update_interrupt(dev, dev->usb_params->parent_priv); - } -} - static uint8_t -uhci_reg_read(uint16_t addr, void *p) +uhci_reg_read(uint16_t addr, void *priv) { - usb_t *dev = (usb_t *) p; - uint8_t ret; - uint8_t *regs = dev->uhci_io; + const usb_t *dev = (usb_t *) priv; + uint8_t ret; + const uint8_t *regs = dev->uhci_io; addr &= 0x0000001f; @@ -161,9 +63,9 @@ uhci_reg_read(uint16_t addr, void *p) } static void -uhci_reg_write(uint16_t addr, uint8_t val, void *p) +uhci_reg_write(uint16_t addr, uint8_t val, void *priv) { - usb_t *dev = (usb_t *) p; + usb_t *dev = (usb_t *) priv; uint8_t *regs = dev->uhci_io; addr &= 0x0000001f; @@ -185,13 +87,16 @@ uhci_reg_write(uint16_t addr, uint8_t val, void *p) case 0x0c: regs[0x0c] = (val & 0x7f); break; + + default: + break; } } static void -uhci_reg_writew(uint16_t addr, uint16_t val, void *p) +uhci_reg_writew(uint16_t addr, uint16_t val, void *priv) { - usb_t *dev = (usb_t *) p; + usb_t *dev = (usb_t *) priv; uint16_t *regs = (uint16_t *) dev->uhci_io; addr &= 0x0000001f; @@ -212,8 +117,8 @@ uhci_reg_writew(uint16_t addr, uint16_t val, void *p) regs[addr >> 1] = ((regs[addr >> 1] & 0xedbb) | (val & 0x1244)) & ~(val & 0x080a); break; default: - uhci_reg_write(addr, val & 0xff, p); - uhci_reg_write(addr + 1, (val >> 8) & 0xff, p); + uhci_reg_write(addr, val & 0xff, priv); + uhci_reg_write(addr + 1, (val >> 8) & 0xff, priv); break; } } @@ -231,716 +136,223 @@ uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable) io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); } -typedef struct -{ - uint32_t HccaInterrruptTable[32]; - uint16_t HccaFrameNumber; - uint16_t HccaPad1; - uint32_t HccaDoneHead; -} usb_hcca_t; - -/* Transfer descriptors */ -typedef struct -{ - uint32_t Control; - uint32_t CBP; - uint32_t NextTD; - uint32_t BE; -} usb_td_t; - -/* Endpoint descriptors */ -typedef struct -{ - uint32_t Control; - uint32_t TailP; - uint32_t HeadP; - uint32_t NextED; -} usb_ed_t; - -#define ENDPOINT_DESC_LIMIT 32 - static uint8_t -ohci_mmio_read(uint32_t addr, void *p) +ohci_mmio_read(uint32_t addr, void *priv) { - usb_t *dev = (usb_t *) p; - uint8_t ret = 0x00; -#ifdef ENABLE_USB_LOG - uint32_t old_addr = addr; -#endif + const usb_t *dev = (usb_t *) priv; + uint8_t ret = 0x00; addr &= 0x00000fff; - ret = dev->ohci_mmio[addr >> 2].b[addr & 3]; - - switch (addr) { - case 0x101: - ret = (ret & 0xfe) | (!!mem_a20_key); - break; - case OHCI_aHcRhPortStatus1 + 1: - case OHCI_aHcRhPortStatus2 + 1: - case OHCI_aHcRhPortStatus3 + 1: - ret |= 0x1; - break; - case OHCI_aHcInterruptDisable: - case OHCI_aHcInterruptDisable + 1: - case OHCI_aHcInterruptDisable + 2: - case OHCI_aHcInterruptDisable + 3: - ret = dev->ohci_mmio[OHCI_HcInterruptEnable].b[addr & 3]; - default: - break; - } + ret = dev->ohci_mmio[addr]; if (addr == 0x101) ret = (ret & 0xfe) | (!!mem_a20_key); -#ifdef ENABLE_USB_LOG - usb_log("[R] %08X = %04X\n", old_addr, ret); -#endif - return ret; } -static uint16_t -ohci_mmio_readw(uint32_t addr, void *p) -{ - return ohci_mmio_read(addr, p) | (ohci_mmio_read(addr + 1, p) << 8); -} - -static uint32_t -ohci_mmio_readl(uint32_t addr, void *p) -{ - return ohci_mmio_readw(addr, p) | (ohci_mmio_readw(addr + 2, p) << 16); -} - -static void -ohci_update_irq(usb_t *dev) -{ - uint32_t level = !!(dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l); - - if (level != dev->irq_level) { - dev->irq_level = level; - usb_interrupt_ohci(dev, level); - } -} - -void -ohci_set_interrupt(usb_t *dev, uint8_t bit) -{ - if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0x80)) - return; - - if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] & bit)) - return; - - if (dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] & bit) - return; - - dev->ohci_mmio[OHCI_HcInterruptStatus].b[0] |= bit; - - /* TODO: Does setting UnrecoverableError also assert PERR# on any emulated USB chipsets? */ - - ohci_update_irq(dev); -} - -/* TODO: Actually use this function somewhere. */ -#if 0 -/* Next two functions ported over from QEMU. */ -static int ohci_copy_td_input(usb_t* dev, usb_td_t *td, - uint8_t *buf, int len) -{ - uint32_t ptr; - uint32_t n; - - ptr = td->CBP; - n = 0x1000 - (ptr & 0xfff); - if (n > len) { - n = len; - } - dma_bm_write(ptr, buf, n, 1); - if (n == len) { - return 0; - } - ptr = td->BE & ~0xfffu; - buf += n; - dma_bm_write(ptr, buf, len - n, 1); - return 0; -} -#endif - -static int ohci_copy_td_output(usb_t* dev, usb_td_t *td, - uint8_t *buf, int len) -{ - uint32_t ptr; - uint32_t n; - - ptr = td->CBP; - n = 0x1000 - (ptr & 0xfff); - if (n > len) { - n = len; - } - dma_bm_read(ptr, buf, n, 1); - if (n == len) { - return 0; - } - ptr = td->BE & ~0xfffu; - buf += n; - dma_bm_read(ptr, buf, len - n, 1); - return 0; -} - -#define OHCI_TD_DIR(val) ((val >> 19) & 3) -#define OHCI_ED_DIR(val) ((val >> 11) & 3) - -uint8_t -ohci_service_transfer_desc(usb_t* dev, usb_ed_t* endpoint_desc) -{ - uint32_t td_addr = endpoint_desc->HeadP & ~0xf; - usb_td_t td; - uint8_t dir; - uint8_t pid_token = 255; - uint32_t len = 0; - uint32_t pktlen = 0; - uint32_t actual_length = 0; - uint32_t i = 0; - uint8_t device_result = 0; - usb_device_t* target = NULL; - - dma_bm_read(td_addr, (uint8_t*)&td, sizeof(usb_td_t), 4); - - switch (dir = OHCI_ED_DIR(endpoint_desc->Control)) { - case 1: - case 2: - break; - default: - dir = OHCI_TD_DIR(td.Control); - break; - } - - switch (dir) { - case 0: /* Setup */ - pid_token = USB_PID_SETUP; - break; - case 1: /* OUT */ - pid_token = USB_PID_OUT; - break; - case 2: /* IN */ - pid_token = USB_PID_IN; - break; - default: - return 1; - } - - if (td.CBP && td.BE) { - if ((td.CBP & 0xfffff000) != (td.BE & 0xfffff000)) { - len = (td.BE & 0xfff) + 0x1001 - (td.CBP & 0xfff); - } else { - if (td.CBP > td.BE) { - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_UE); - return 1; - } - - len = (td.BE - td.CBP) + 1; - } - if (len > sizeof(dev->ohci_usb_buf)) { - len = sizeof(dev->ohci_usb_buf); - } - - pktlen = len; - if (len && pid_token != USB_PID_IN) { - pktlen = (endpoint_desc->Control >> 16) & 0xFFF; - if (pktlen > len) { - pktlen = len; - } - ohci_copy_td_output(dev, &td, dev->ohci_usb_buf, pktlen); - } - } - - for (i = 0; i < 2; i++) { - if (!dev->ohci_devices[i]) - continue; - - assert(dev->ohci_devices[i]->device_get_address != NULL); - - if (dev->ohci_devices[i]->device_get_address(dev->ohci_devices[i]->priv) != (endpoint_desc->Control & 0x7f)) - continue; - - target = dev->ohci_devices[i]; - break; - } - - if (!target) - return 1; - - device_result = target->device_process(target->priv, dev->ohci_usb_buf, &actual_length, pid_token, (endpoint_desc->Control & 0x780) >> 7, !(endpoint_desc->Control & (1 << 18))); - - if ((actual_length == pktlen) || (pid_token == USB_PID_IN && (endpoint_desc->Control & (1 << 18)) && device_result == USB_ERROR_NO_ERROR)) { - if (len == actual_length) { - td.CBP = 0; - } else { - if ((td.CBP & 0xfff) + actual_length > 0xfff) { - td.CBP = (td.BE & ~0xfff) + ((td.CBP + actual_length) & 0xfff); - } else { - td.CBP += actual_length; - } - } - - td.Control |= (1 << 25); /* dataToggle[1] */ - td.Control ^= (1 << 24); /* dataToggle[0] */ - td.Control &= ~0xFC000000; /* Set both ErrorCount and ConditionCode to 0. */ - - if (pid_token != USB_PID_IN && len != actual_length) { - goto exit_no_retire; - } - - endpoint_desc->HeadP &= ~0x2; - if (td.Control & (1 << 24)) { - endpoint_desc->HeadP |= 0x2; - } - } else { - if (actual_length != 0xFFFFFFFF && actual_length >= 0) { - td.Control &= ~0xF0000000; - td.Control |= 0x90000000; - } else { - switch (device_result) { - case USB_ERROR_NAK: - return 1; - } - dev->ohci_interrupt_counter = 0; - } - - endpoint_desc->HeadP |= 0x1; - } - - endpoint_desc->HeadP &= 0xf; - endpoint_desc->HeadP |= td.NextTD & ~0xf; - td.NextTD = dev->ohci_mmio[OHCI_HcDoneHead].l; - dev->ohci_mmio[OHCI_HcDoneHead].l = td_addr; - i = (td.Control >> 21) & 7; - if (i < dev->ohci_interrupt_counter) { - dev->ohci_interrupt_counter = i; - } -exit_no_retire: - dma_bm_write(td_addr, (uint8_t*)&td, sizeof(usb_td_t), 4); - return !(td.Control & 0xF0000000); -} - -uint8_t -ohci_service_endpoint_desc(usb_t* dev, uint32_t head) -{ - usb_ed_t endpoint_desc; - uint8_t active = 0; - uint32_t next = 0; - uint32_t limit_counter = 0; - - if (head == 0) - return 0; - - for (uint32_t cur = head; cur && limit_counter++ < ENDPOINT_DESC_LIMIT; cur = next) { - dma_bm_read(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4); - - next = endpoint_desc.NextED & ~0xFu; - - if ((endpoint_desc.Control & (1 << 13)) || (endpoint_desc.HeadP & (1 << 0))) - continue; - - if (endpoint_desc.Control & 0x8000) { - fatal("OHCI: Isochronous transfers not implemented!\n"); - } - - active = 1; - - while ((endpoint_desc.HeadP & ~0xFu) != endpoint_desc.TailP) { - ohci_service_transfer_desc(dev, &endpoint_desc); - } - - dma_bm_write(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4); - } - - return active; -} - -void -ohci_end_of_frame(usb_t* dev) -{ - usb_hcca_t hcca; - if (dev->ohci_initial_start) - return; - dma_bm_read(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4); - - if (dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_PeriodicListEnable) { - ohci_service_endpoint_desc(dev, hcca.HccaInterrruptTable[dev->ohci_mmio[OHCI_HcFmNumber].l & 0x1f]); - } - - if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_ControlListEnable) - && (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x2)) { - uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcControlHeadED].l); - if (!result) { - dev->ohci_mmio[OHCI_HcControlHeadED].l = 0; - dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x2; - } - } - - if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_BulkListEnable) - && (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x4)) { - uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcBulkHeadED].l); - if (!result) { - dev->ohci_mmio[OHCI_HcBulkHeadED].l = 0; - dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x4; - } - } - - if (dev->ohci_interrupt_counter == 0 && !(dev->ohci_mmio[OHCI_HcInterruptStatus].l & OHCI_HcInterruptEnable_WDH)) { - if (dev->ohci_mmio[OHCI_HcDoneHead].l == 0) { - fatal("OHCI: HcDoneHead is still NULL!"); - } - - if (dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l) { - dev->ohci_mmio[OHCI_HcDoneHead].l |= 1; - } - - hcca.HccaDoneHead = dev->ohci_mmio[OHCI_HcDoneHead].l; - dev->ohci_mmio[OHCI_HcDoneHead].l = 0; - dev->ohci_interrupt_counter = 7; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_WDH); - } - - if (dev->ohci_interrupt_counter != 0 && dev->ohci_interrupt_counter != 7) { - dev->ohci_interrupt_counter--; - } - - dev->ohci_mmio[OHCI_HcFmNumber].w[0]++; - hcca.HccaFrameNumber = dev->ohci_mmio[OHCI_HcFmNumber].w[0]; - - dma_bm_write(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4); -} - -void -ohci_start_of_frame(usb_t* dev) -{ - dev->ohci_initial_start = 0; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_SO); -} - -void -ohci_update_frame_counter(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcFmRemaining].w[0] &= 0x3fff; - if (dev->ohci_mmio[OHCI_HcFmRemaining].w[0] == 0) { - ohci_end_of_frame(dev); - dev->ohci_mmio[OHCI_HcFmRemaining].w[0] = dev->ohci_mmio[OHCI_HcFmInterval].w[0] & 0x3fff; - dev->ohci_mmio[OHCI_HcFmRemaining].l &= ~(1 << 31); - dev->ohci_mmio[OHCI_HcFmRemaining].l |= dev->ohci_mmio[OHCI_HcFmInterval].l & (1 << 31); - ohci_start_of_frame(dev); - timer_on_auto(&dev->ohci_frame_timer, 1. / 12.); - return; - } - dev->ohci_mmio[OHCI_HcFmRemaining].w[0]--; - timer_on_auto(&dev->ohci_frame_timer, 1. / 12.); -} - -void -ohci_port_reset_callback(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x10; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x10; -} - -void -ohci_port_reset_callback_2(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x10; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x10; -} - -static void -ohci_soft_reset(usb_t* dev) -{ - uint32_t old_HcControl = (dev->ohci_mmio[OHCI_HcControl].l & 0x100) | 0xc0; - memset(dev->ohci_mmio, 0x00, 4096); - dev->ohci_mmio[OHCI_HcRevision].b[0] = 0x10; - dev->ohci_mmio[OHCI_HcRevision].b[1] = 0x01; - dev->ohci_mmio[OHCI_HcRhDescriptorA].b[0] = 0x02; - dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] = 0x02; - dev->ohci_mmio[OHCI_HcFmInterval].l = 0x27782edf; /* FrameInterval = 11999, FSLargestDataPacket = 10104 */ - dev->ohci_mmio[OHCI_HcLSThreshold].l = 0x628; - dev->ohci_mmio[OHCI_HcInterruptEnable].l |= (1 << 31); - dev->ohci_mmio[OHCI_HcControl].l = old_HcControl; - dev->ohci_interrupt_counter = 7; - ohci_update_irq(dev); -} - static void -ohci_mmio_write(uint32_t addr, uint8_t val, void *p) +ohci_mmio_write(uint32_t addr, uint8_t val, void *priv) { - usb_t *dev = (usb_t *) p; + usb_t *dev = (usb_t *) priv; uint8_t old; -#ifdef ENABLE_USB_LOG - usb_log("[W] %08X = %04X\n", addr, val); -#endif - addr &= 0x00000fff; switch (addr) { - case OHCI_aHcControl: - old = dev->ohci_mmio[OHCI_HcControl].b[0]; -#ifdef ENABLE_USB_LOG - usb_log("OHCI: OHCI state 0x%X\n", (val & 0xc0)); -#endif + case 0x04: if ((val & 0xc0) == 0x00) { /* UsbReset */ - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] = dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] = 0x16; - for (int i = 0; i < 2; i++) { - if (dev->ohci_devices[i]) { - dev->ohci_devices[i]->device_reset(dev->ohci_devices[i]->priv); - } - } - } else if ((val & 0xc0) == 0x80 && (old & 0xc0) != (val & 0xc0)) { - dev->ohci_mmio[OHCI_HcFmRemaining].l = 0; - dev->ohci_initial_start = 1; - timer_on_auto(&dev->ohci_frame_timer, 1000.); + dev->ohci_mmio[0x56] = dev->ohci_mmio[0x5a] = 0x16; } break; - case OHCI_aHcCommandStatus: + case 0x08: /* HCCOMMANDSTATUS */ /* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */ if (val & 0x08) { - dev->ohci_mmio[OHCI_HcInterruptStatus].b[3] = 0x40; - if ((dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0x40) == 0x40) { + dev->ohci_mmio[0x0f] = 0x40; + if ((dev->ohci_mmio[0x13] & 0xc0) == 0xc0) smi_raise(); - } } /* bit HostControllerReset must be cleared for the controller to be seen as initialized */ if (val & 0x01) { - ohci_soft_reset(dev); - + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; val &= ~0x01; } break; - case OHCI_aHcHCCA: - return; - case OHCI_aHcInterruptEnable: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f); - dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] &= ~(val & 0x7f); - ohci_update_irq(dev); - return; - case OHCI_aHcInterruptEnable + 1: - case OHCI_aHcInterruptEnable + 2: - return; - case OHCI_aHcInterruptEnable + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0); - dev->ohci_mmio[OHCI_HcInterruptDisable].b[3] &= ~(val & 0xc0); - ohci_update_irq(dev); - return; - case OHCI_aHcInterruptDisable: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f); - dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] &= ~(val & 0x7f); - ohci_update_irq(dev); - return; - case OHCI_aHcInterruptDisable + 1: - case OHCI_aHcInterruptDisable + 2: - return; - case OHCI_aHcInterruptDisable + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0); - dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] &= ~(val & 0xc0); - ohci_update_irq(dev); - return; - case OHCI_aHcInterruptStatus: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x7f); + case 0x0c: + dev->ohci_mmio[addr] &= ~(val & 0x7f); return; - case OHCI_aHcInterruptStatus + 1: - case OHCI_aHcInterruptStatus + 2: + case 0x0d: + case 0x0e: return; - case OHCI_aHcInterruptStatus + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x40); + case 0x0f: + dev->ohci_mmio[addr] &= ~(val & 0x40); return; - case OHCI_aHcFmRemaining + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x80); + case 0x3b: + dev->ohci_mmio[addr] = (val & 0x80); return; - case OHCI_aHcFmRemaining + 1: - case OHCI_aHcPeriodicStart + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x3f); + case 0x39: + case 0x41: + dev->ohci_mmio[addr] = (val & 0x3f); return; - case OHCI_aHcLSThreshold + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x0f); + case 0x45: + dev->ohci_mmio[addr] = (val & 0x0f); return; - case OHCI_aHcFmRemaining + 2: - case OHCI_aHcFmNumber + 2: - case OHCI_aHcFmNumber + 3: - case OHCI_aHcPeriodicStart + 2: - case OHCI_aHcPeriodicStart + 3: - case OHCI_aHcLSThreshold + 2: - case OHCI_aHcLSThreshold + 3: - case OHCI_aHcRhDescriptorA: - case OHCI_aHcRhDescriptorA + 2: + case 0x3a: + case 0x3e: + case 0x3f: + case 0x42: + case 0x43: + case 0x46: + case 0x47: + case 0x48: + case 0x4a: return; - case OHCI_aHcRhDescriptorA + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x1b); + case 0x49: + dev->ohci_mmio[addr] = (val & 0x1b); if (val & 0x02) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; } return; - case OHCI_aHcRhDescriptorA + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x03); + case 0x4b: + dev->ohci_mmio[addr] = (val & 0x03); return; - case OHCI_aHcRhDescriptorB: - case OHCI_aHcRhDescriptorB + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x06); - if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x04)) { - if (!(dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] & 0x01)) - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] |= 0x01; + case 0x4c: + case 0x4e: + dev->ohci_mmio[addr] = (val & 0x06); + if ((addr == 0x4c) && !(val & 0x04)) { + if (!(dev->ohci_mmio[0x58] & 0x01)) + dev->ohci_mmio[0x5a] |= 0x01; + dev->ohci_mmio[0x58] |= 0x01; } - if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x02)) { - if (!(dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] & 0x01)) - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] |= 0x01; + if ((addr == 0x4c) && !(val & 0x02)) { + if (!(dev->ohci_mmio[0x54] & 0x01)) + dev->ohci_mmio[0x56] |= 0x01; + dev->ohci_mmio[0x54] |= 0x01; } return; - case OHCI_aHcRhDescriptorB + 1: - case OHCI_aHcRhDescriptorB + 3: + case 0x4d: + case 0x4f: return; - case OHCI_aHcRhStatus: + case 0x50: if (val & 0x01) { - if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; - } else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) { - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; } - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) { - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; + if (!(dev->ohci_mmio[0x4e] & 0x04)) { + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; } } } return; - case OHCI_aHcRhStatus + 1: + case 0x51: if (val & 0x80) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x80; + dev->ohci_mmio[addr] |= 0x80; return; - case OHCI_aHcRhStatus + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x02); + case 0x52: + dev->ohci_mmio[addr] &= ~(val & 0x02); if (val & 0x01) { - if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; - } else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) { - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) + dev->ohci_mmio[0x55] |= 0x01; + if (!(dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[0x59] |= 0x01; } } return; - case OHCI_aHcRhStatus + 3: + case 0x53: if (val & 0x80) - dev->ohci_mmio[OHCI_HcRhStatus].b[1] &= ~0x80; + dev->ohci_mmio[0x51] &= ~0x80; return; - case OHCI_aHcRhPortStatus1: - case OHCI_aHcRhPortStatus2: - old = dev->ohci_mmio[addr >> 2].b[addr & 3]; + case 0x54: + case 0x58: + old = dev->ohci_mmio[addr]; if (val & 0x10) { if (old & 0x01) { - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x10; - timer_on_auto(&dev->ohci_port_reset_timer[(addr - OHCI_aHcRhPortStatus1) / 4], 10000.); - if (dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]) - dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]->device_reset(dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]->priv); + dev->ohci_mmio[addr] |= 0x10; + /* TODO: The clear should be on a 10 ms timer. */ + dev->ohci_mmio[addr] &= ~0x10; + dev->ohci_mmio[addr + 2] |= 0x10; } else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } if (val & 0x08) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04; - if (val & 0x04) { - if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04; - else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; - } + dev->ohci_mmio[addr] &= ~0x04; + if (val & 0x04) + dev->ohci_mmio[addr] |= 0x04; if (val & 0x02) { if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x02; + dev->ohci_mmio[addr] |= 0x02; else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } if (val & 0x01) { if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x02; + dev->ohci_mmio[addr] &= ~0x02; else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } - if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x04) && (old & 0x04)) - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x04; - /* if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x02)) - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x02; */ + if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04)) + dev->ohci_mmio[addr + 2] |= 0x04; +#if 0 + if (!(dev->ohci_mmio[addr] & 0x02)) + dev->ohci_mmio[addr + 2] |= 0x02; +#endif return; - case OHCI_aHcRhPortStatus1 + 1: - if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; + case 0x55: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; } - if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; + if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] |= 0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; } return; - case OHCI_aHcRhPortStatus2 + 1: - if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01; - if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01; - return; - case OHCI_aHcRhPortStatus1 + 2: - case OHCI_aHcRhPortStatus2 + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x1f); + case 0x59: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] &= ~0x01; + if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] |= 0x01; return; - case OHCI_aHcRhPortStatus1 + 3: - case OHCI_aHcRhPortStatus2 + 3: + case 0x56: + case 0x5a: + dev->ohci_mmio[addr] &= ~(val & 0x1f); return; - case OHCI_aHcDoneHead: - case OHCI_aHcBulkCurrentED: - case OHCI_aHcBulkHeadED: - case OHCI_aHcControlCurrentED: - case OHCI_aHcControlHeadED: - case OHCI_aHcPeriodCurrentED: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xf0); + case 0x57: + case 0x5b: return; - } - - dev->ohci_mmio[addr >> 2].b[addr & 3] = val; -} -static void -ohci_mmio_writew(uint32_t addr, uint16_t val, void *p) -{ - ohci_mmio_write(addr, val & 0xff, p); - ohci_mmio_write(addr + 1, val >> 8, p); -} + default: + break; + } -static void -ohci_mmio_writel(uint32_t addr, uint32_t val, void *p) -{ - ohci_mmio_writew(addr, val & 0xffff, p); - ohci_mmio_writew(addr + 2, val >> 16, p); + dev->ohci_mmio[addr] = val; } void @@ -954,65 +366,6 @@ ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000)) mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000); - - usb_log("ohci_update_mem_mapping(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base); -} - -uint8_t -usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type) -{ - switch (bus_type) { - case USB_BUS_OHCI: - { - for (int i = 0; i < 2; i++) { - if (!dev->ohci_devices[i]) { - uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l; - dev->ohci_devices[i] = device; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] |= 0x1; - if ((dev->ohci_mmio[OHCI_HcControl].b[0] & 0xc0) == 0xc0) { - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RD); - } - if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x1; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC); - } - return i; - } - } - } - break; - } - return 255; -} - -void -usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type) -{ - switch (bus_type) { - case USB_BUS_OHCI: - { - if (port > 2) - return; - if (dev->ohci_devices[port]) { - uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l; - dev->ohci_devices[port] = NULL; - if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x1) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x1; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x1; - } - if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x2) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x2; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x2; - } - if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l) - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC); - return; - } - - } - break; - } - return; } static void @@ -1020,21 +373,20 @@ usb_reset(void *priv) { usb_t *dev = (usb_t *) priv; - memset(dev->uhci_io, 0x00, sizeof(dev->uhci_io)); + memset(dev->uhci_io, 0x00, 128); dev->uhci_io[0x0c] = 0x40; dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80; - ohci_soft_reset(dev); - dev->ohci_mmio[OHCI_HcControl].l = 0x00; + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); dev->uhci_enable = 0; mem_mapping_disable(&dev->ohci_mmio_mapping); dev->ohci_enable = 0; - - usb_log("usb_reset(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base); - usb_log("usb_reset(): map = %08X\n", &dev->ohci_mmio_mapping); } static void @@ -1046,40 +398,39 @@ usb_close(void *priv) } static void * -usb_init_ext(const device_t *info, void *params) +usb_init(UNUSED(const device_t *info)) { usb_t *dev; - dev = (usb_t *) calloc(1, sizeof(usb_t)); + dev = (usb_t *) malloc(sizeof(usb_t)); if (dev == NULL) return (NULL); + memset(dev, 0x00, sizeof(usb_t)); - dev->usb_params = (usb_params_t *) params; - - mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0x1000, - ohci_mmio_read, ohci_mmio_readw, ohci_mmio_readl, - ohci_mmio_write, ohci_mmio_writew, ohci_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); - - mem_mapping_disable(&dev->ohci_mmio_mapping); + memset(dev->uhci_io, 0x00, 128); + dev->uhci_io[0x0c] = 0x40; + dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80; - timer_add(&dev->ohci_frame_timer, ohci_update_frame_counter, dev, 0); /* Unused for now, to be used for frame counting. */ - timer_add(&dev->ohci_port_reset_timer[0], ohci_port_reset_callback, dev, 0); - timer_add(&dev->ohci_port_reset_timer[1], ohci_port_reset_callback_2, dev, 0); + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; + mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0, + ohci_mmio_read, NULL, NULL, + ohci_mmio_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); usb_reset(dev); - usb_device_inst = dev; - return dev; } const device_t usb_device = { .name = "Universal Serial Bus", .internal_name = "usb", - .flags = DEVICE_PCI | DEVICE_EXTPARAMS, + .flags = DEVICE_PCI, .local = 0, - .init_ext = usb_init_ext, + .init = usb_init, .close = usb_close, .reset = usb_reset, { .available = NULL }, diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index a81c9aed27..8e50ecbf93 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -18,20 +18,16 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c - vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c + vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c - vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c + vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c vid_sis.c) -if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) - target_sources(vid PRIVATE vid_mga.c) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/agpgart.c b/src/video/agpgart.c index 523fcc9968..b8ae2bdc8d 100644 --- a/src/video/agpgart.c +++ b/src/video/agpgart.c @@ -24,6 +24,7 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/agpgart.h> +#include <86box/plat_unused.h> #ifdef ENABLE_AGPGART_LOG int agpgart_do_log = ENABLE_AGPGART_LOG; @@ -129,7 +130,7 @@ agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv) } static void * -agpgart_init(const device_t *info) +agpgart_init(UNUSED(const device_t *info)) { agpgart_t *dev = malloc(sizeof(agpgart_t)); memset(dev, 0, sizeof(agpgart_t)); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 9ec196d860..ff14701649 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -7,13 +7,13 @@ * This file is part of the 86Box distribution. * * Emulation of the 8514/A card from IBM for the MCA bus and - * generic ISA bus clones without vendor extensions. + * ISA bus clones. * * * * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022-2024 TheCollector1995. */ #include #include @@ -21,6 +21,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> @@ -33,14 +34,61 @@ #include <86box/plat.h> #include <86box/thread.h> #include <86box/video.h> +#include <86box/vid_8514a.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_ati_eeprom.h> +#include <86box/vid_ati_mach8.h> #include "cpu.h" -static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *p); -static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p); -static uint8_t ibm8514_accel_inb(uint16_t port, void *p); -static uint16_t ibm8514_accel_inw(uint16_t port, void *p); +#ifdef ATI_8514_ULTRA +#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" +#endif + +static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); +static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv); +static uint8_t ibm8514_accel_inb(uint16_t port, void *priv); +static uint16_t ibm8514_accel_inw(uint16_t port, void *priv); + +#ifdef ENABLE_IBM8514_LOG +int ibm8514_do_log = ENABLE_IBM8514_LOG; + +static void +ibm8514_log(const char *fmt, ...) +{ + va_list ap; + + if (ibm8514_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ibm8514_log(fmt, ...) +#endif + +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ + } + +#define READ8(addr, var) \ + switch ((addr) & 1) { \ + case 0: \ + temp = (var) & 0xff; \ + break; \ + case 1: \ + temp = ((var) >> 8) & 0xff; \ + break; \ + } + #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd <= 1) || (cmd == 5)) { \ @@ -52,7 +100,11 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *p); } #define READ(addr, dat) \ - dat = dev->vram[(addr) & (dev->vram_mask)]; + if (dev->bpp) { \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ + } else { \ + dat = (dev->vram[(addr) & (dev->vram_mask)]); \ + } #define MIX(mixmode, dest_dat, src_dat) \ { \ @@ -121,13 +173,13 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *p); dest_dat = MAX(src_dat, dest_dat); \ break; \ case 0x15: \ - dest_dat = (dest_dat - src_dat) / 2; \ + dest_dat = (dest_dat - src_dat) >> 1; \ break; \ case 0x16: \ - dest_dat = (src_dat - dest_dat) / 2; \ + dest_dat = (src_dat - dest_dat) >> 1; \ break; \ case 0x17: \ - dest_dat = (dest_dat + src_dat) / 2; \ + dest_dat = (dest_dat + src_dat) >> 1; \ break; \ case 0x18: \ dest_dat = MAX(0, (dest_dat - src_dat)); \ @@ -139,7 +191,7 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *p); dest_dat = MAX(0, (src_dat - dest_dat)); \ break; \ case 0x1b: \ - dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + dest_dat = MIN(~0, (dest_dat + src_dat)); \ break; \ case 0x1c: \ dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ @@ -151,19 +203,26 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *p); dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ break; \ case 0x1f: \ - dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + dest_dat = (~0 < (src_dat + dest_dat)) ? ~0 : ((src_dat + dest_dat) >> 1); \ break; \ } \ } #define WRITE(addr, dat) \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; + if (dev->bpp) { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } + +int ibm8514_active = 0; int ibm8514_cpu_src(svga_t *svga) { - ibm8514_t *dev = &svga->dev8514; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (!(dev->accel.cmd & 0x100)) return 0; @@ -177,7 +236,7 @@ ibm8514_cpu_src(svga_t *svga) int ibm8514_cpu_dest(svga_t *svga) { - ibm8514_t *dev = &svga->dev8514; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (!(dev->accel.cmd & 0x100)) return 0; @@ -189,18 +248,18 @@ ibm8514_cpu_dest(svga_t *svga) } void -ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len) +ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, int len) { - ibm8514_t *dev = &svga->dev8514; - uint8_t nibble = 0; - uint32_t pixelxfer = 0; - uint32_t monoxfer = 0xffffffff; - int pixcnt = 0; - int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - int frgd_mix = (dev->accel.frgd_mix >> 5) & 3; - int bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; - int cmd = dev->accel.cmd >> 13; - int and3 = dev->accel.cur_x & 3; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t nibble = 0; + uint32_t pixelxfer = 0; + uint32_t monoxfer = 0xffffffff; + int pixcnt = 0; + int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; + int frgd_mix = (dev->accel.frgd_mix >> 5) & 3; + int bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; + int cmd = dev->accel.cmd >> 13; + int and3 = dev->accel.cur_x & 3; if (dev->accel.cmd & 0x100) { if (len != 1) { @@ -413,37 +472,36 @@ ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len) static void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if (port != 0x9ae8 && port != 0xe2e8) + ibm8514_log("Port OUT FIFO=%04x, val=%04x, len=%d.\n", port, val, len); switch (port) { case 0x82e8: case 0xc2e8: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else { + else dev->accel.cur_y = val & 0x7ff; - } break; case 0x82e9: case 0xc2e9: - if (len == 1) { + if (len == 1) dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - } break; case 0x86e8: case 0xc6e8: - if (len == 1) { + if (len == 1) dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - } else { + else dev->accel.cur_x = val & 0x7ff; - } break; case 0x86e9: case 0xc6e9: - if (len == 1) { + if (len == 1) dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); - } break; case 0x8ae8: @@ -451,6 +509,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; else { + dev->accel.desty = val & 0x07ff; dev->accel.desty_axstp = val & 0x3fff; if (val & 0x2000) dev->accel.desty_axstp |= ~0x1fff; @@ -470,6 +529,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; else { + dev->accel.destx = val & 0x07ff; dev->accel.destx_distp = val & 0x3fff; if (val & 0x2000) dev->accel.destx_distp |= ~0x1fff; @@ -487,6 +547,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) case 0x92e8: if (len != 1) dev->test = val; + fallthrough; case 0xd2e8: if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; @@ -511,6 +572,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x700) | val; else { dev->accel.maj_axis_pcnt = val & 0x7ff; + dev->accel.maj_axis_pcnt_no_limit = val; } break; case 0x96e9: @@ -529,8 +591,11 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->data_available = 0; dev->data_available2 = 0; dev->accel.cmd = val; - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; + if (port == 0xdae8) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } + ibm8514_log("8514/A CMD=%04x.\n", dev->accel.cmd); ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; @@ -557,10 +622,11 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.short_stroke = val; dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); @@ -573,15 +639,16 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x9ee9: case 0xdee9: + dev->accel.ssv_state = 1; if (len == 1) { dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); @@ -700,12 +767,19 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) else { dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) { - dev->accel.clip_top = val & 0x3ff; - } - if ((dev->accel.multifunc_cntl >> 12) == 2) { - dev->accel.clip_left = val & 0x3ff; - } + if ((dev->accel.multifunc_cntl >> 12) == 1) + dev->accel.clip_top = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 3) + dev->accel.multifunc[3] = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 4) + dev->accel.multifunc[4] = val & 0x7ff; + + ibm8514_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); if (port == 0xfee8) dev->accel.cmd_back = 1; else @@ -717,27 +791,36 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 1) { dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) + dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; + if (port == 0xfee9) dev->accel.cmd_back = 1; else dev->accel.cmd_back = 0; } break; + + default: + break; } } void -ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p) +ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; svga_out(port, val, svga); } uint8_t -ibm8514_ramdac_in(uint16_t port, void *p) +ibm8514_ramdac_in(uint16_t port, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; uint8_t ret; ret = svga_in(port, svga); @@ -803,170 +886,175 @@ ibm8514_io_set(svga_t *svga) static void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t old = 0; - if (port & 0x8000) { + if (port & 0x8000) ibm8514_accel_out_fifo(svga, port, val, len); - } else { + else { switch (port) { case 0x2e8: - if (len == 1) - dev->htotal = (dev->htotal & 0xff00) | val; - else { - dev->htotal = val; - svga_recalctimings(svga); - } - break; case 0x2e9: - if (len != 1) { - dev->htotal = (dev->htotal & 0xff) | (val << 8); - // pclog("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); - svga_recalctimings(svga); - } + WRITE8(port, dev->htotal, val); break; case 0x6e8: - dev->hdisp = val; - // pclog("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); - svga_recalctimings(svga); + case 0x6e9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } + } + ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); break; case 0xae8: - // pclog("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); - svga_recalctimings(svga); + case 0xae9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07); + } + } + ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); break; case 0xee8: - // pclog("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); - svga_recalctimings(svga); + case 0xee9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; + } + } + ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); break; case 0x12e8: - if (len == 1) - dev->vtotal = (dev->vtotal & 0x1f00) | val; - else { - dev->vtotal = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x12e9: - if (len == 1) { - dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); - svga_recalctimings(svga); + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; } break; case 0x16e8: - if (len == 1) - dev->vdisp = (dev->vdisp & 0x1f00) | val; - else { - dev->vdisp = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x16e9: - if (len == 1) { - dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); - svga_recalctimings(svga); + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; } + ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); break; case 0x1ae8: - if (len == 1) - dev->vsyncstart = (dev->vsyncstart & 0x1f00) | val; - else { - dev->vsyncstart = val & 0x1fff; - svga_recalctimings(svga); - } - break; case 0x1ae9: - if (len == 1) { - dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); - svga_recalctimings(svga); + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; } break; case 0x1ee8: - dev->vsyncwidth = val; - // pclog("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - svga_recalctimings(svga); + case 0x1ee9: + ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); break; case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - // pclog("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); - svga_recalctimings(svga); + ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); break; case 0x42e8: - if (len == 1) { - dev->subsys_stat &= ~val; - } else { - dev->subsys_stat &= ~(val & 0xff); - dev->subsys_cntl = (val >> 8); - } + old = dev->subsys_stat; + if (val & 1) + dev->subsys_stat &= ~1; + if (val & 2) + dev->subsys_stat &= ~2; + if (val & 4) + dev->subsys_stat &= ~4; + if (val & 8) + dev->subsys_stat &= ~8; break; case 0x42e9: - if (len == 1) { - dev->subsys_cntl = val; - } + old = dev->subsys_cntl; + dev->subsys_cntl = val; + if ((old ^ val) & 1) + dev->subsys_stat |= 1; + if ((old ^ val) & 2) + dev->subsys_stat |= 2; + if ((old ^ val) & 4) + dev->subsys_stat |= 4; + if ((old ^ val) & 8) + dev->subsys_stat |= 8; break; case 0x4ae8: - if (!val) - break; - dev->accel.advfunc_cntl = val & 7; - ibm8514_on = (dev->accel.advfunc_cntl & 1); - vga_on = !ibm8514_on; - //pclog("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); + case 0x4ae9: + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; + vga_on = !dev->on[port & 1]; + dev->vendor_mode[port & 1] = 0; + ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); svga_recalctimings(svga); break; + + + default: + break; } } } static void -ibm8514_accel_outb(uint16_t port, uint8_t val, void *p) +ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; + ibm8514_accel_out(port, val, svga, 1); } static void -ibm8514_accel_outw(uint16_t port, uint16_t val, void *p) +ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; + ibm8514_accel_out(port, val, svga, 2); } static uint32_t ibm8514_accel_in(uint16_t port, svga_t *svga, int len) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint32_t temp = 0; int cmd; - int vpos = dev->displine + svga->y_add; - int vblankend = svga->vblankstart + svga->crtc[0x16]; + int vpos = 0; + int vblankend = svga->vblankstart + svga->crtc[0x16]; switch (port) { case 0x2e8: - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) temp |= 2; } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) temp |= 2; } break; case 0x6e8: - temp = dev->hdisp; + temp = dev->hdisped; break; case 0x22e8: @@ -989,9 +1077,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) break; case 0x42e8: - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; + cmd = dev->accel.cmd >> 13; + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; if (vpos >= svga->vblankstart || vpos <= vblankend) dev->subsys_stat |= 1; } else { @@ -1009,10 +1098,21 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) temp |= 0x80; break; + case 0x82e8: + case 0xc2e8: + if (len != 1) + temp = dev->accel.cur_y; + break; + + case 0x86e8: + case 0xc6e8: + if (len != 1) + temp = dev->accel.cur_x; + break; + case 0x92e8: - if (len != 1) { + if (len != 1) temp = dev->test; - } break; case 0x9ae8: @@ -1065,28 +1165,33 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) } } break; + + default: + break; } return temp; } static uint8_t -ibm8514_accel_inb(uint16_t port, void *p) +ibm8514_accel_inb(uint16_t port, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; + return ibm8514_accel_in(port, svga, 1); } static uint16_t -ibm8514_accel_inw(uint16_t port, void *p) +ibm8514_accel_inw(uint16_t port, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; + return ibm8514_accel_in(port, svga, 2); } void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (!cpu_input) { dev->accel.ssv_len = ssv & 0x0f; @@ -1102,29 +1207,38 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t } void -ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len) +ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len)) { - ibm8514_t *dev = &svga->dev8514; - uint8_t src_dat = 0; - uint8_t dest_dat; - uint8_t old_dest_dat; - int frgd_mix; - int bkgd_mix; - uint16_t clip_b = dev->accel.multifunc[3] & 0x7ff; - uint16_t clip_r = dev->accel.multifunc[4] & 0x7ff; - int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - uint8_t mix_mask = 0x80; - uint8_t compare = dev->accel.color_cmp & 0xff; - int compare_mode = dev->accel.multifunc[0x0a] & 0x38; - int cmd = dev->accel.cmd >> 13; - uint8_t wrt_mask = dev->accel.wrt_mask & 0xff; - uint8_t rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); - uint8_t rd_mask_polygon = dev->accel.rd_mask & 0xff; - uint8_t frgd_color = dev->accel.frgd_color; - uint8_t bkgd_color = dev->accel.bkgd_color; - uint32_t old_mix_dat; - int and3 = dev->accel.cur_x & 3; - uint8_t poly_src = 0; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t *vram_w = (uint16_t *) dev->vram; + uint16_t src_dat = 0; + uint16_t dest_dat; + uint16_t old_dest_dat; + int frgd_mix; + int bkgd_mix; + uint16_t clip_b = dev->accel.multifunc[3]; + uint16_t clip_r = dev->accel.multifunc[4]; + int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; + uint16_t mix_mask = dev->bpp ? 0x8000 : 0x80; + uint16_t compare = dev->accel.color_cmp; + int compare_mode = dev->accel.multifunc[0x0a] & 0x38; + int cmd = dev->accel.cmd >> 13; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t rd_mask = dev->accel.rd_mask; + uint16_t rd_mask_polygon = dev->accel.rd_mask; + uint16_t frgd_color = dev->accel.frgd_color; + uint16_t bkgd_color = dev->accel.bkgd_color; + uint32_t old_mix_dat; + int and3 = dev->accel.cur_x & 3; + + if (!dev->bpp) { + compare &= 0xff; + frgd_color &= 0xff; + bkgd_color &= 0xff; + rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); + rd_mask &= 0xff; + rd_mask_polygon &= 0xff; + } if (dev->accel.cmd & 0x100) { dev->force_busy = 1; @@ -1136,16 +1250,20 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (cpu_input) { if ((dev->accel.cmd & 2) || (pixcntl == 2)) { - if ((frgd_mix == 2) || (bkgd_mix == 2)) { + if ((frgd_mix == 2) || (bkgd_mix == 2)) count >>= 3; - } else if (pixcntl == 2) { - if (dev->accel.cmd & 2) { + else if (pixcntl == 2) { + if (dev->accel.cmd & 2) count >>= 1; - } else + else count >>= 3; } - } else { + } else count >>= 3; + + if (dev->bpp) { + if ((dev->accel.cmd & 0x200) && (count == 2)) + count >>= 1; } } @@ -1246,26 +1364,38 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } 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 (dev->accel.ssv_draw) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } } } } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (!dev->accel.ssv_len) break; @@ -1299,14 +1429,133 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx++; dev->accel.cy++; break; + + default: + break; } dev->accel.ssv_len--; } + } else { + while (count-- && (dev->accel.ssv_len >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left) && (dev->accel.cx <= clip_r) && + (dev->accel.cy >= dev->accel.clip_top) && (dev->accel.cy <= clip_b)) { + 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; - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + default: + break; + } + + 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 (dev->accel.ssv_draw) { + if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (!dev->accel.ssv_len) + break; + + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { + dev->accel.err_term += dev->accel.destx_distp; + /*Step minor axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cy--; + break; + case 0x20: + dev->accel.cy--; + break; + case 0x40: + dev->accel.cx--; + break; + case 0x60: + dev->accel.cx++; + break; + case 0x80: + dev->accel.cy++; + break; + case 0xa0: + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cx--; + break; + case 0xe0: + dev->accel.cx++; + break; + + default: + break; + } + } else + dev->accel.err_term += dev->accel.desty_axstp; + + /*Step major axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx--; + break; + case 0x20: + dev->accel.cx++; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cy++; + break; + + default: + break; + } + + dev->accel.ssv_len--; + } } + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; break; case 1: /*Draw line*/ @@ -1315,15 +1564,15 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) { - dev->accel.cx |= ~0x3ff; - } - if (dev->accel.cur_y & 0x400) { - dev->accel.cy |= ~0x3ff; - } + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; dev->accel.sy = dev->accel.maj_axis_pcnt; + ibm8514_log("Line Draw 8514/A, 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", 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 & 2) { if (dev->accel.cmd & 8) { @@ -1383,7 +1632,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); - } else + } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -1392,12 +1641,16 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } + } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1477,7 +1730,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == 0) { break; @@ -1512,6 +1768,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx++; dev->accel.cy++; break; + + default: + break; } dev->accel.sy--; @@ -1538,11 +1797,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1561,70 +1823,43 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.temp_cnt--; mix_dat >>= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == 0) { break; } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cy--; - break; - case 0x20: - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: - dev->accel.cx++; - break; - case 0x80: - dev->accel.cy++; - break; - case 0xa0: - dev->accel.cy++; - break; - case 0xc0: - dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) dev->accel.cx++; - break; - case 0x40: - dev->accel.cy--; - break; - case 0x60: - dev->accel.cy--; - break; - case 0x80: + else dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: - dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } dev->accel.sy--; @@ -1654,11 +1889,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1677,70 +1915,42 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; - if (dev->accel.sy == 0) { + if (dev->accel.sy == 0) break; - } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cy--; - break; - case 0x20: - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) dev->accel.cx++; - break; - case 0x80: - dev->accel.cy++; - break; - case 0xa0: - dev->accel.cy++; - break; - case 0xc0: + else dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) dev->accel.cx++; - break; - case 0x40: - dev->accel.cy--; - break; - case 0x60: - dev->accel.cy--; - break; - case 0x80: + else dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: - dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } dev->accel.sy--; @@ -1767,15 +1977,17 @@ 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; - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.fill_state = 0; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; if (cmd == 4) dev->accel.cmd |= 2; @@ -1821,8 +2033,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else { if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { - dev->accel.output = 1; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + dev->accel.output = 1; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + else + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; } } } @@ -1833,7 +2048,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { dev->accel.input = 1; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + else + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; } } else if (dev->accel.cmd & 2) { if (dev->accel.cmd & 8) { @@ -1864,11 +2082,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -1939,7 +2160,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; switch (dev->accel.cmd & 0xe0) { case 0x00: @@ -1960,20 +2184,22 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0xe0: dev->accel.cx++; break; + + default: + break; } dev->accel.sx--; if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (and3 == 1) { + if (and3 == 1) dev->accel.sx += 4; - } else if (and3 == 2) { + else if (and3 == 2) dev->accel.sx += 5; - } else if (and3 == 3) { + else if (and3 == 3) dev->accel.sx += 6; - } else { + else dev->accel.sx += 3; - } if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx + 1); @@ -1999,9 +2225,16 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0xe0: dev->accel.cy++; break; + + default: + break; } - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2033,11 +2266,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -2052,7 +2288,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2077,7 +2316,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2107,11 +2350,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } } @@ -2125,7 +2371,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } mix_dat >>= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2148,9 +2397,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cmd & 2) { if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; } } @@ -2159,7 +2408,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2213,8 +2466,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cy++; else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; + + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + } else { + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; + } dev->accel.sy--; return; } @@ -2232,8 +2491,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cy++; else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; + + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + } else { + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; + } dev->accel.sy--; return; } @@ -2262,7 +2527,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2280,8 +2548,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + } else { + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + } dev->accel.sy--; return; } @@ -2300,8 +2573,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + } else { + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + } dev->accel.sy--; return; } @@ -2333,11 +2611,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; break; + + default: + break; } READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -2358,7 +2639,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2379,7 +2663,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2411,6 +2699,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: src_dat = 0; break; + + default: + break; } READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -2449,7 +2740,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; dev->accel.cur_x = dev->accel.cx; @@ -2460,7 +2755,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else { dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat = old_mix_dat; } @@ -2478,6 +2773,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: src_dat = 0; break; + + default: + break; } READ(dev->accel.dest + dev->accel.cx, dest_dat); @@ -2513,7 +2811,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; if (dev->accel.sy < 0) { @@ -2525,66 +2827,53 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } else { - if (dev->accel.multifunc[0x0a] & 6) { - while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.multifunc[0x0a] & 6) == 4) { + while (count-- && (dev->accel.sy >= 0)) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - 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 = 0; - break; - case 3: - src_dat = 0; - break; - } + READ(dev->accel.dest + dev->accel.cx, mix_dat); + if ((mix_dat & rd_mask_polygon) == rd_mask_polygon) + dev->accel.fill_state = !dev->accel.fill_state; - READ(dev->accel.dest + dev->accel.cx, poly_src); - if (dev->accel.multifunc[0x0a] & 2) { - poly_src = ((poly_src & wrt_mask) == wrt_mask); + READ(dev->accel.dest + dev->accel.cx, dest_dat); + old_dest_dat = dest_dat; + if (dev->accel.fill_state) { + if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) { + MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat); + ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat); + dest_dat &= ~rd_mask_polygon; + } else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) { + ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask); + dest_dat &= ~(rd_mask_polygon & wrt_mask); + } } else { - poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); - } - - if (poly_src) { - dev->accel.fill_state = !dev->accel.fill_state; + if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) + dest_dat &= ~rd_mask_polygon; + else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) + dest_dat &= ~(rd_mask_polygon & wrt_mask); } - if (dev->accel.fill_state) { - READ(dev->accel.dest + dev->accel.cx, dest_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); - WRITE(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))) { + ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - mix_dat <<= 1; - mix_dat |= 1; - - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx++; - } else { + else dev->accel.cx--; - } dev->accel.sx--; if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.fill_state = 0; + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx) + 1; - } else { + else dev->accel.cx += (dev->accel.sx) + 1; - } if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -2592,21 +2881,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cy--; dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + ibm8514_log(".\n"); return; } } } } else { + ibm8514_log("Rectangle Fill Normal CMD=%04x, CURRENT(%d,%d), sx=%d, FR(%02x), linedraw=%d.\n", dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.sx, frgd_color, dev->accel.linedraw); while (count-- && dev->accel.sy >= 0) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; + if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ + src_dat = frgd_color; break; case 1: src_dat = frgd_color; @@ -2617,15 +2909,22 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: src_dat = 0; 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; 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.cx, dest_dat); + + if (dev->accel.cmd & 0x10) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } } } @@ -2639,11 +2938,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx--; if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx) + 1; - } else + else dev->accel.cx += (dev->accel.sx) + 1; if (dev->accel.cmd & 0x80) @@ -2651,7 +2951,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; if (dev->accel.sy < 0) { @@ -2667,13 +2971,25 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } break; - case 5: /*Draw Polygon Boundary Line*/ + case 5: /*Draw Polygon Boundary Line*/ { if (!cpu_input) { - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - dev->accel.oldcy = dev->accel.cy; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; - dev->accel.sy = 0; + dev->accel.sy = dev->accel.maj_axis_pcnt_no_limit; + + if (dev->accel.cmd & 0x80) + dev->accel.oldcy = dev->accel.cy + 1; + else + dev->accel.oldcy = dev->accel.cy - 1; + + dev->accel.oldcx = 0; + + ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cur_x_nolimit, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.clip_left, clip_r, dev->accel.clip_top, clip_b, compare_mode, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -2686,125 +3002,200 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cur_x > 1023) - dev->accel.cx = 0; + if (dev->accel.cmd & 8) { + while (count-- && (dev->accel.sy >= 0)) { + if (dev->accel.cx < 0) + dev->accel.cx = 0; + if (dev->accel.cy < 0) + dev->accel.cy = 0; - if ((dev->accel.cx) >= dev->accel.clip_left && ((dev->accel.cx) <= clip_r) && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b) { - 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 & 0xff; - break; - case 3: - src_dat = 0; - break; - } + if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + 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; - 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 ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) { - if (!dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == (dev->accel.oldcy + 1))) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); - } else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) { - WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + default: + break; + } + + + 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 (dev->accel.cmd & 0x10) { + if (dev->accel.sy && (dev->accel.cmd & 4)) { + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + } + } else if (!(dev->accel.cmd & 4)) { + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); + } + } } } } - } - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; + mix_dat <<= 1; + mix_dat |= 1; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; - if (dev->accel.sy == dev->accel.maj_axis_pcnt) { - break; - } + if (!dev->accel.sy) + break; - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ switch (dev->accel.cmd & 0xe0) { case 0x00: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; + dev->accel.cx++; break; case 0x20: + dev->accel.cx++; dev->accel.oldcy = dev->accel.cy; dev->accel.cy--; break; case 0x40: - dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy--; break; case 0x60: - dev->accel.cx++; + dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy--; break; case 0x80: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; + dev->accel.cx--; break; case 0xa0: + dev->accel.cx--; dev->accel.oldcy = dev->accel.cy; dev->accel.cy++; break; case 0xc0: - dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy++; break; case 0xe0: dev->accel.cx++; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy++; + break; + + default: break; } - } else - dev->accel.err_term += dev->accel.desty_axstp; - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: - dev->accel.cx++; - break; - case 0x40: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x60: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; + dev->accel.sy--; + } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if (dev->accel.cx < 0) + dev->accel.cx = 0; + if (dev->accel.cy < 0) + dev->accel.cy = 0; + + if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + 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; + } + + 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 ((dev->accel.cmd & 0x14) == 0x14) { + if (dev->accel.sy) { + if (dev->accel.cmd & 0x40) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else { + if (dev->accel.oldcy != dev->accel.cy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } + } + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (!dev->accel.sy) break; - case 0xe0: + + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; - break; - } + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } - dev->accel.sy++; + dev->accel.sy--; + } } - break; + } + break; - case 6: /*BitBlt*/ + case 6: /*BitBlt*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { dev->accel.x_count = 0; @@ -2813,24 +3204,25 @@ 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; - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - dev->accel.dy = dev->accel.desty_axstp & 0x3ff; + dev->accel.dx = dev->accel.destx; + dev->accel.dy = dev->accel.desty; - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; - if (dev->accel.desty_axstp & 0x400) - dev->accel.dy |= ~0x3ff; + if (dev->accel.destx >= 0x600) + dev->accel.dx |= ~0x5ff; + if (dev->accel.desty >= 0x600) + dev->accel.dy |= ~0x5ff; - dev->accel.cx = dev->accel.cur_x & 0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.dest = dev->accel.dy * dev->pitch; + dev->accel.fill_state = 0; if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 2) { @@ -2876,7 +3268,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -2886,12 +3278,16 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, 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); WRITE(dev->accel.dest + dev->accel.dx, dest_dat); @@ -2900,12 +3296,18 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; - if (dev->accel.cmd & 0x20) + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; dev->accel.cx++; - else + } else { + dev->accel.dx--; dev->accel.cx--; + } dev->accel.sx--; if (dev->accel.sx < 0) { @@ -2916,16 +3318,23 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; dev->accel.cx -= (dev->accel.sx) + 1; - } else + } else { + dev->accel.dx += (dev->accel.sx) + 1; dev->accel.cx += (dev->accel.sx) + 1; + } - if (dev->accel.cmd & 0x80) + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; dev->accel.cy++; - else + } else { + dev->accel.dy--; dev->accel.cy--; + } - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.src = dev->accel.cy * dev->pitch; + dev->accel.dest = dev->accel.dy * dev->pitch; dev->accel.sy--; return; } @@ -2952,7 +3361,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -2962,6 +3371,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -2974,7 +3386,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } mix_dat >>= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) { dev->accel.dx++; @@ -3003,12 +3418,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cmd & 2) { if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.dx = dev->accel.destx; + if (dev->accel.destx >= 0x600) + dev->accel.dx |= ~0x5ff; } } @@ -3037,6 +3452,7 @@ 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.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { + if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3056,7 +3472,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -3066,6 +3482,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3079,7 +3498,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) { dev->accel.dx++; @@ -3123,7 +3545,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat count = dev->accel.maj_axis_pcnt + 1; dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { mix_dat >>= 8; dev->accel.temp_cnt = 8; } @@ -3141,6 +3563,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: READ(dev->accel.src + dev->accel.cx, src_dat); break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3197,7 +3622,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else { dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat = old_mix_dat; } @@ -3215,6 +3640,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: READ(dev->accel.src + dev->accel.cx, src_dat); break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3269,8 +3697,39 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } else { + if ((dev->accel_bpp == 24) && ((dev->local & 0xff) >= 0x02) && (dev->accel.cmd == 0xc2b5)) { + int64_t cx; + int64_t dx; + + cx = (int64_t) dev->accel.cx; + dx = (int64_t) dev->accel.dx; + + while (1) { + if ((dx >= (((int64_t)dev->accel.clip_left) * 3)) && (dx <= (((uint64_t)clip_r) * 3)) && + (dev->accel.dy >= (dev->accel.clip_top << 1)) && (dev->accel.dy <= (clip_b << 1))) { + + READ(dev->accel.src + (dev->accel.ge_offset << 2) + cx, src_dat); + READ(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); + + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); + } + + cx++; + dx++; + + dev->accel.sx--; + if (dev->accel.sx < 0) + return; + } + return; + } + + ibm8514_log("BitBLT 8514/A=%04x, selfrmix=%d, selbkmix=%d, d(%d,%d), c(%d,%d), pixcntl=%d, sy=%d, frgdmix=%02x, bkgdmix=%02x, rdmask=%02x, wrtmask=%02x, linedraw=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, dev->accel.rd_mask, wrt_mask, dev->accel.linedraw); while (count-- && dev->accel.sy >= 0) { - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { + if ((dev->accel.dx >= dev->accel.clip_left) && (dev->accel.dx <= clip_r) && + (dev->accel.dy >= dev->accel.clip_top) && (dev->accel.dy <= clip_b)) { if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3295,11 +3754,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: READ(dev->accel.src + dev->accel.cx, src_dat); if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { + if ((dev->accel.cmd & 0x10) && !(dev->accel.cmd & 0x40)) { src_dat = ((src_dat & rd_mask) == rd_mask); } } break; + + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3308,8 +3770,13 @@ 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); - - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + if (dev->accel.cmd & 4) { + if (dev->accel.sx > 0) { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } } } mix_dat <<= 1; @@ -3325,15 +3792,18 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx--; if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } + dev->accel.dx = dev->accel.destx; + + if (dev->accel.destx >= 0x600) + dev->accel.dx |= ~0x5ff; + + dev->accel.cx = dev->accel.cur_x; + + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; if (dev->accel.cmd & 0x80) { dev->accel.dy++; @@ -3347,28 +3817,48 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.sy--; - if (dev->accel.sy < 0) { + if (dev->accel.sy < 0) return; - } } } } } } break; + + default: + break; } } -static void +void +ibm8514_render_blank(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + uint32_t *line_ptr = &svga->monitor->target_buffer->line[dev->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (uint32_t)(dev->h_disp) * sizeof(uint32_t); + + if (dev->h_disp > 0) + memset(line_ptr, 0, line_width); +} + +void ibm8514_render_8bpp(svga_t *svga) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint32_t *p; uint32_t dat; - if ((dev->displine + svga->y_add) < 0) { + if ((dev->displine + svga->y_add) < 0) return; - } if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; @@ -3379,16 +3869,16 @@ ibm8514_render_8bpp(svga_t *svga) for (int x = 0; x <= dev->h_disp; x += 8) { dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); - p[0] = dev->map8[dat & 0xff]; - p[1] = dev->map8[(dat >> 8) & 0xff]; - p[2] = dev->map8[(dat >> 16) & 0xff]; - p[3] = dev->map8[(dat >> 24) & 0xff]; + p[0] = dev->pallook[dat & 0xff]; + p[1] = dev->pallook[(dat >> 8) & 0xff]; + p[2] = dev->pallook[(dat >> 16) & 0xff]; + p[3] = dev->pallook[(dat >> 24) & 0xff]; dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]); - p[4] = dev->map8[dat & 0xff]; - p[5] = dev->map8[(dat >> 8) & 0xff]; - p[6] = dev->map8[(dat >> 16) & 0xff]; - p[7] = dev->map8[(dat >> 24) & 0xff]; + p[4] = dev->pallook[dat & 0xff]; + p[5] = dev->pallook[(dat >> 8) & 0xff]; + p[6] = dev->pallook[(dat >> 16) & 0xff]; + p[7] = dev->pallook[(dat >> 24) & 0xff]; dev->ma += 8; p += 8; @@ -3397,6 +3887,214 @@ ibm8514_render_8bpp(svga_t *svga) } } +void +ibm8514_render_15bpp(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) { + return; + } + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x += 8) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]); + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]); + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]); + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; + } + dev->ma += (x << 1); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_16bpp(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) { + return; + } + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x += 8) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; + } + dev->ma += (x << 1); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_24bpp(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (int x = 0; x <= dev->h_disp; x += 4) { + dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + p[x] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = dat & 0xffffff; + + dev->ma += 12; + } + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_BGR(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (int x = 0; x <= dev->h_disp; x += 4) { + dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dev->ma += 12; + } + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_ABGR8888(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x++) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + dev->ma += (x * 4); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_32bpp(svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || dev->changedvram[(dev->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x++) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + p[x] = dat & 0xffffff; + } + dev->ma += (x * 4); + dev->ma &= dev->vram_mask; + } +} + static void ibm8514_render_overscan_left(ibm8514_t *dev, svga_t *svga) { @@ -3427,115 +4125,153 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) } void -ibm8514_poll(ibm8514_t *dev, svga_t *svga) +ibm8514_poll(void *priv) { + svga_t *svga = (svga_t *)priv; + ibm8514_t *dev = (ibm8514_t *)svga->dev8514; uint32_t x; int wx; int wy; - if (!dev->linepos) { - timer_advance_u64(&svga->timer, svga->dispofftime); - dev->linepos = 1; + ibm8514_log("IBM 8514/A poll.\n"); + if (dev->on[0] || dev->on[1]) { + ibm8514_log("ON!\n"); + if (!dev->linepos) { + if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; + } - if (dev->dispon) { - dev->hdisp_on = 1; + if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } - dev->ma &= dev->vram_mask; + timer_advance_u64(&svga->timer8514, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer(); - } + if (dev->dispon) { + dev->hdisp_on = 1; - svga->render(svga); + dev->ma &= dev->vram_mask; - svga->x_add = (overscan_x >> 1); - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = (overscan_x >> 1); + if (dev->firstline == 2000) { + dev->firstline = dev->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } - if (dev->lastline < dev->displine) - dev->lastline = dev->displine; - } + if (dev->hwcursor_on) + dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = (overscan_x >> 1); + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = (overscan_x >> 1); + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, dev->displine + svga->y_add); + dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + + if (dev->lastline < dev->displine) + dev->lastline = dev->displine; + } - dev->displine++; - if (dev->interlace) dev->displine++; - if (dev->displine > 1500) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, svga->dispontime); - dev->hdisp_on = 0; - - dev->linepos = 0; - if (dev->dispon) { - if (dev->sc == dev->rowcount) { - dev->sc = 0; - dev->maback += (dev->rowoffset << 3); - if (dev->interlace) + if (dev->interlace) + dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (dev->displine > 1500) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer8514, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; + + dev->linepos = 0; + if (dev->dispon) { + if (dev->sc == dev->rowcount) { + dev->sc = 0; dev->maback += (dev->rowoffset << 3); - dev->maback &= dev->vram_mask; - dev->ma = dev->maback; - } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + if (dev->interlace) + dev->maback += (dev->rowoffset << 3); + + dev->maback &= dev->vram_mask; + dev->ma = dev->maback; + } else { + dev->sc++; + dev->sc &= 0x1f; + dev->ma = dev->maback; + } } - } - dev->vc++; - dev->vc &= 2047; + dev->vc++; + dev->vc &= 0x7ff; - if (dev->vc == dev->dispend) { - dev->dispon = 0; + if (dev->vc == dev->dispend) { + dev->dispon = 0; - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; - } + for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { + if (dev->changedvram[x]) + dev->changedvram[x]--; + } - if (svga->fullchange) - svga->fullchange--; - } - if (dev->vc == dev->v_syncstart) { - dev->dispon = 0; - x = dev->h_disp; + if (svga->fullchange) + svga->fullchange--; + } + if (dev->vc == dev->v_syncstart) { + dev->dispon = 0; + svga->cgastat |= 8; + x = dev->h_disp; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->interlace && !dev->oddeven) + dev->lastline++; + if (dev->interlace && dev->oddeven) + dev->firstline--; - wx = x; + wx = x; + wy = dev->lastline - dev->firstline; + svga_doblit(wx, wy, svga); - wy = dev->lastline - dev->firstline; - svga_doblit(wx, wy, svga); + dev->firstline = 2000; + dev->lastline = 0; - dev->firstline = 2000; - dev->lastline = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->firstline_draw = 2000; - dev->lastline_draw = 0; + dev->oddeven ^= 1; - dev->oddeven ^= 1; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; - changeframecount = dev->interlace ? 3 : 2; + if (dev->interlace && dev->oddeven) + dev->ma = dev->maback = (dev->rowoffset << 1); + else + dev->ma = dev->maback = 0; - if (dev->interlace && dev->oddeven) - dev->ma = dev->maback = (dev->rowoffset << 1); - else - dev->ma = dev->maback = 0; + dev->ma = (dev->ma << 2); + dev->maback = (dev->maback << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->sc = 0; + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; - dev->ma = (dev->ma << 2); - dev->maback = (dev->maback << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->sc = 0; - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + svga->x_add = (overscan_x >> 1); - svga->x_add = (overscan_x >> 1); + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } @@ -3543,89 +4279,43 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) void ibm8514_recalctimings(svga_t *svga) { - ibm8514_t *dev = &svga->dev8514; - - if (ibm8514_on) { - dev->h_disp = (dev->hdisp + 1) << 3; - dev->pitch = dev->h_disp; - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = ((dev->vdisp >> 1) + 1); - if (dev->dispend == 766) - dev->dispend = 768; - //pclog("HDISP = %d, VTOTAL = %d, DISPEND = %d, hires = %02x\n", dev->h_disp, dev->v_total, dev->dispend, dev->accel.advfunc_cntl & 4); - { -#if 0 - if (dev->dispend == 480) { - dev->h_disp = 640; - dev->rowoffset = 128; - dev->pitch = 1024; - } else if ((dev->dispend == 600) || (dev->dispend == 598)) { - dev->h_disp = 800; - dev->rowoffset = 128; - dev->dispend = 600; - dev->pitch = 1024; - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } else { - if (dev->accel.advfunc_cntl & 4) { - if (!dev->hdisp) { - dev->rowoffset = 128; - dev->h_disp = 1024; - dev->pitch = dev->h_disp; - } - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } else { - dev->rowoffset = 128; - dev->h_disp = 640; - dev->dispend = 480; - dev->pitch = 1024; - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } - } + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + svga->render8514 = ibm8514_render_blank; +#ifdef ATI_8514_ULTRA + if (dev->extensions) { + if (svga->ext8514 != NULL) + ati8514_recalctimings(svga); + } else #endif - } - - if (dev->accel.advfunc_cntl & 4) { - if (!vga_on && dev->ibm_mode) { - if (dev->h_disp == 8) { + { + if (dev->on[0] || dev->on[1]) { + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; + dev->dispend = dev->vdisp; + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->accel.advfunc_cntl & 4) { + dev->pitch = 1024; + if (!dev->h_disp) { dev->h_disp = 1024; dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; } - } - - if (dev->dispend == 598) - dev->dispend = 600; - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - dev->rowoffset = 0x80; - dev->pitch = 1024; - - // pclog("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if (!vga_on && dev->ibm_mode) { - dev->h_disp = 640; - dev->dispend = 480; + dev->pitch = 640; + if (!dev->h_disp) { + dev->h_disp = 640; + dev->dispend = 480; + } + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } if (dev->interlace) { @@ -3636,22 +4326,21 @@ ibm8514_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } - dev->rowoffset = 0x80; - dev->pitch = 1024; - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + dev->rowoffset = 0x80; + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; + ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } - svga->render = ibm8514_render_8bpp; - //pclog("Pitch = %d, mode = %d.\n", dev->pitch, dev->ibm_mode); } - // pclog("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); + ibm8514_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); } static uint8_t ibm8514_mca_read(int port, void *priv) { - svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = &svga->dev8514; + const svga_t *svga = (svga_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; return (dev->pos_regs[port & 7]); } @@ -3660,7 +4349,7 @@ static void ibm8514_mca_write(int port, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; /* MCA does not write registers below 0x0100. */ if (port < 0x0102) @@ -3673,70 +4362,168 @@ ibm8514_mca_write(int port, uint8_t val, void *priv) static uint8_t ibm8514_mca_feedb(void *priv) { - svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = &svga->dev8514; + const svga_t *svga = (svga_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; return dev->pos_regs[2] & 1; } static void - * - ibm8514_init(const device_t *info) +ibm8514_mca_reset(void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + ibm8514_log("MCA reset.\n"); + dev->on[0] = 0; + dev->on[1] = 0; + vga_on = 1; + ibm8514_mca_write(0x102, 0, svga); +} + +static void * +ibm8514_init(const device_t *info) { if (svga_get_pri() == NULL) return NULL; - svga_t *svga = svga_get_pri(); - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = svga_get_pri(); + ibm8514_t *dev = (ibm8514_t *) calloc(1, sizeof(ibm8514_t)); + + svga->dev8514 = dev; + svga->ext8514 = NULL; dev->vram_size = 1024 << 10; dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc(dev->vram_size >> 12, 1); dev->vram_mask = dev->vram_size - 1; - dev->map8 = svga->pallook; + dev->map8 = dev->pallook; + dev->local = 0; + + dev->type = info->flags; + dev->bpp = 0; + +#ifdef ATI_8514_ULTRA + dev->extensions = device_get_config_int("extensions"); + + switch (dev->extensions) { + case 1: + if (rom_present(BIOS_MACH8_ROM_PATH)) { + mach = (mach_t *) calloc(1, sizeof(mach_t)); + svga->ext8514 = mach; + ati8514_init(svga, svga->ext8514, svga->dev8514); + + if (dev->type & DEVICE_MCA) { + rom_init(&dev->bios_rom, + BIOS_MACH8_ROM_PATH, + 0xc6800, 0x1000, 0x0fff, + 0x0800, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&dev->bios_rom.mapping); + dev->pos_regs[0] = 0x88; + dev->pos_regs[1] = 0x80; + mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); + ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0); + } else { + rom_init(&dev->bios_rom, + BIOS_MACH8_ROM_PATH, + 0xd0000, 0x1000, 0x0fff, + 0x0800, MEM_MAPPING_EXTERNAL); + ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); + } + break; + } + fallthrough; - dev->type = info->flags; - dev->ibm_mode = 1; + default: + ibm8514_io_set(svga); + if (dev->type & DEVICE_MCA) { + dev->pos_regs[0] = 0x7f; + dev->pos_regs[1] = 0xef; + mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); + } + break; + } +#else ibm8514_io_set(svga); - if (info->flags & DEVICE_MCA) { + if (dev->type & DEVICE_MCA) { dev->pos_regs[0] = 0x7f; dev->pos_regs[1] = 0xef; - mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, NULL, svga); + mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); } +#endif + + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); return svga; } static void -ibm8514_close(void *p) +ibm8514_close(void *priv) { - svga_t *svga = (svga_t *) p; - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + +#ifdef ATI_8514_ULTRA + mach_t *mach = (mach_t *) svga->ext8514; + + if (mach) + free(mach); +#endif if (dev) { free(dev->vram); free(dev->changedvram); + + free(dev); } } static void -ibm8514_speed_changed(void *p) +ibm8514_speed_changed(void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; svga_recalctimings(svga); } static void -ibm8514_force_redraw(void *p) +ibm8514_force_redraw(void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; svga->fullchange = changeframecount; } +#ifdef ATI_8514_ULTRA +// clang-format off +static const device_config_t ext8514_config[] = { + { + .name = "extensions", + .description = "Vendor", + .type = CONFIG_SELECTION, + .default_int = 0, + .selection = { + { + .description = "IBM", + .value = 0 + }, + { + .description = "ATI", + .value = 1 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; +#endif + // clang-format off const device_t gen8514_isa_device = { .name = "Generic 8514/A clone (ISA)", @@ -3770,7 +4557,7 @@ const device_t ibm8514_mca_device = { void ibm8514_device_add(void) { - if (!ibm8514_enabled) + if (!ibm8514_standalone_enabled) return; if (machine_has_bus(machine, MACHINE_BUS_MCA)) diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 2b37eb6fd6..b54f6b89ee 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -35,8 +35,8 @@ #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) # define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #endif -#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" -#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" +#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) @@ -57,14 +57,16 @@ typedef struct ati18800_t { uint8_t regs[256]; int index; + int type; + uint32_t memory; } ati18800_t; static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static void -ati18800_out(uint16_t addr, uint8_t val, void *p) +ati18800_out(uint16_t addr, uint8_t val, void *priv) { - ati18800_t *ati18800 = (ati18800_t *) p; + ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; uint8_t old; @@ -76,23 +78,27 @@ ati18800_out(uint16_t addr, uint8_t val, void *p) ati18800->index = val; break; case 0x1cf: + old = ati18800->regs[ati18800->index]; ati18800->regs[ati18800->index] = val; switch (ati18800->index) { case 0xb0: - svga_recalctimings(svga); + if ((old ^ val) & 6) + svga_recalctimings(svga); break; case 0xb2: case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati18800->regs[0xbe] & 8) { /*Read/write bank mode*/ + svga->read_bank = ((ati18800->regs[0xb2] & 0xe0) >> 5) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; break; case 0xb3: ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); break; + + default: + break; } break; @@ -118,14 +124,17 @@ ati18800_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -ati18800_in(uint16_t addr, void *p) +ati18800_in(uint16_t addr, void *priv) { - ati18800_t *ati18800 = (ati18800_t *) p; + ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; uint8_t temp = 0xff; @@ -165,22 +174,74 @@ ati18800_in(uint16_t addr, void *p) static void ati18800_recalctimings(svga_t *svga) { - ati18800_t *ati18800 = (ati18800_t *) svga->p; - - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } + const ati18800_t *ati18800 = (ati18800_t *) svga->priv; + int clock_sel; + + clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); - if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; + if (ati18800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; svga->rowoffset <<= 1; - svga->ma <<= 1; + svga->gdcreg[5] &= ~0x40; + } + + if (ati18800->regs[0xb0] & 6) { + svga->gdcreg[5] |= 0x40; + if ((ati18800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((ati18800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + } + break; + } + break; + + default: + break; + } + } } } @@ -192,41 +253,38 @@ ati18800_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); + ati18800->type = info->local; + switch (info->local) { -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - case ATI18800_WONDER: -#endif default: #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) + case ATI18800_WONDER: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; #endif case ATI18800_VGA88: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 256; break; case ATI18800_EDGE16: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 512; break; } - if (info->local == ATI18800_EDGE16) { - svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } else { - svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } + svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10, + ati18800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + ati18800->svga.clock_gen = device_add(&ati18810_device); + ati18800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); ati18800->svga.miscout = 1; + ati18800->svga.bpp = 8; ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); @@ -254,9 +312,9 @@ ati18800_available(void) } static void -ati18800_close(void *p) +ati18800_close(void *priv) { - ati18800_t *ati18800 = (ati18800_t *) p; + ati18800_t *ati18800 = (ati18800_t *) priv; svga_close(&ati18800->svga); @@ -264,17 +322,17 @@ ati18800_close(void *p) } static void -ati18800_speed_changed(void *p) +ati18800_speed_changed(void *priv) { - ati18800_t *ati18800 = (ati18800_t *) p; + ati18800_t *ati18800 = (ati18800_t *) priv; svga_recalctimings(&ati18800->svga); } static void -ati18800_force_redraw(void *p) +ati18800_force_redraw(void *priv) { - ati18800_t *ati18800 = (ati18800_t *) p; + ati18800_t *ati18800 = (ati18800_t *) priv; ati18800->svga.fullchange = changeframecount; } @@ -296,7 +354,7 @@ const device_t ati18800_wonder_device = { #endif const device_t ati18800_vga88_device = { - .name = "ATI-18800-1", + .name = "ATI 18800-1", .internal_name = "ati18800v", .flags = DEVICE_ISA, .local = ATI18800_VGA88, @@ -310,7 +368,7 @@ const device_t ati18800_vga88_device = { }; const device_t ati18800_device = { - .name = "ATI-18800-5", + .name = "ATI VGA Edge 16", .internal_name = "ati18800", .flags = DEVICE_ISA, .local = ATI18800_EDGE16, diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index b41e1ca825..368312fcbc 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -108,9 +108,9 @@ ati28800_log(const char *fmt, ...) static void ati28800_recalctimings(svga_t *svga); static void -ati28800_out(uint16_t addr, uint8_t val, void *p) +ati28800_out(uint16_t addr, uint8_t val, void *priv) { - ati28800_t *ati28800 = (ati28800_t *) p; + ati28800_t *ati28800 = (ati28800_t *) priv; svga_t *svga = &ati28800->svga; uint8_t old; @@ -136,6 +136,10 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) if ((old ^ val) & 0x80) svga_recalctimings(svga); break; + case 0xad: + if ((old ^ val) & 0x0c) + svga_recalctimings(svga); + break; case 0xb0: if ((old ^ val) & 0x60) svga_recalctimings(svga); @@ -169,6 +173,9 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) if ((old ^ val) & 2) svga_recalctimings(svga); break; + + default: + break; } break; @@ -205,14 +212,17 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static void -ati28800k_out(uint16_t addr, uint8_t val, void *p) +ati28800k_out(uint16_t addr, uint8_t val, void *priv) { - ati28800_t *ati28800 = (ati28800_t *) p; + ati28800_t *ati28800 = (ati28800_t *) priv; svga_t *svga = &ati28800->svga; uint16_t oldaddr = addr; @@ -225,7 +235,7 @@ ati28800k_out(uint16_t addr, uint8_t val, void *p) ati28800->ksc5601_mode_enabled = val & 0x20; svga_recalctimings(svga); } - ati28800_out(oldaddr, val, p); + ati28800_out(oldaddr, val, priv); break; case 0x3DD: ati28800->port_03dd_val = val; @@ -259,20 +269,23 @@ ati28800k_out(uint16_t addr, uint8_t val, void *p) if (val & 2) ati28800->in_get_korean_font_kind_set = 1; break; + + default: + break; } break; } break; default: - ati28800_out(oldaddr, val, p); + ati28800_out(oldaddr, val, priv); break; } } static uint8_t -ati28800_in(uint16_t addr, void *p) +ati28800_in(uint16_t addr, void *priv) { - ati28800_t *ati28800 = (ati28800_t *) p; + ati28800_t *ati28800 = (ati28800_t *) priv; svga_t *svga = &ati28800->svga; uint8_t temp; @@ -346,12 +359,12 @@ ati28800_in(uint16_t addr, void *p) } static uint8_t -ati28800k_in(uint16_t addr, void *p) +ati28800k_in(uint16_t addr, void *priv) { - ati28800_t *ati28800 = (ati28800_t *) p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - uint8_t temp = 0xFF; + ati28800_t *ati28800 = (ati28800_t *) priv; + const svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; + uint8_t temp = 0xFF; if (addr != 0x3da) ati28800_log("ati28800k_in : %04X ", addr); @@ -380,7 +393,7 @@ ati28800k_in(uint16_t addr, void *p) } break; default: - temp = ati28800_in(oldaddr, p); + temp = ati28800_in(oldaddr, priv); break; } if (addr != 0x3da) @@ -391,7 +404,14 @@ ati28800k_in(uint16_t addr, void *p) static void ati28800_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *) svga->p; + ati28800_t *ati28800 = (ati28800_t *) svga->priv; + int clock_sel; + + if (ati28800->regs[0xad] & 0x08) + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2]; + + clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | + ((ati28800->regs[0xb9] & 2) << 1); if (ati28800->regs[0xa3] & 0x10) svga->ma_latch |= 0x10000; @@ -399,78 +419,45 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { - case 0x00: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0; - break; - case 0x01: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0; - break; - case 0x02: - ati28800_log("clock 2\n"); - break; - case 0x03: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; - case 0x04: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x05: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0; - break; - case 0x06: - ati28800_log("clock 2\n"); - break; - case 0x07: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - break; - case 0x08: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0; - break; - case 0x09: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0; - break; - case 0x0A: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0; - break; - case 0x0B: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0; - break; - case 0x0C: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x0D: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0; - break; - case 0x0E: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; - break; - case 0x0F: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; - default: - break; - } - if (ati28800->regs[0xb8] & 0x40) svga->clock *= 2; if (ati28800->regs[0xa7] & 0x80) svga->clock *= 3; - if (ati28800->regs[0xb6] & 0x10) { + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; + svga->dots_per_clock <<= 1; svga->gdcreg[5] &= ~0x40; } if (ati28800->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; - } - - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((ati28800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->dots_per_clock <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, " + "planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", + svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, + ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, + ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80); switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ @@ -493,8 +480,10 @@ ati28800_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; case 15: @@ -503,12 +492,18 @@ ati28800_recalctimings(svga_t *svga) else { svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; svga->rowoffset <<= 1; svga->ma_latch <<= 1; } break; + default: + break; } break; + + default: + break; } } } @@ -517,7 +512,7 @@ ati28800_recalctimings(svga_t *svga) static void ati28800k_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *) svga->p; + const ati28800_t *ati28800 = (ati28800_t *) svga->priv; ati28800_recalctimings(svga); @@ -550,8 +545,8 @@ ati28800k_init(const device_t *info) ati28800->ksc5601_mode_enabled = 0; switch (ati28800->type_korean) { - case 0: default: + case 0: rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); loadfont(FONT_ATIKOR_PATH, 6); break; @@ -571,6 +566,8 @@ ati28800k_init(const device_t *info) ati28800k_in, ati28800k_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); @@ -637,6 +634,8 @@ ati28800_init(const device_t *info) ati28800_in, ati28800_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, @@ -705,9 +704,9 @@ ati28800_close(void *priv) } static void -ati28800_speed_changed(void *p) +ati28800_speed_changed(void *priv) { - ati28800_t *ati28800 = (ati28800_t *) p; + ati28800_t *ati28800 = (ati28800_t *) priv; svga_recalctimings(&ati28800->svga); } diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 107b630399..ac2a0f7cbe 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -44,17 +44,22 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/rom.h> #include <86box/timer.h> #include <86box/video.h> +#include <86box/vid_8514a.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_unused.h> typedef struct ati68860_ramdac_t { uint8_t regs[16]; void (*render)(struct svga_t *svga); - int dac_addr, dac_pos; - int dac_r, dac_g; + int dac_addr; + int dac_pos; + int dac_r; + int dac_g; PALETTE pal; uint32_t pallook[2]; @@ -62,22 +67,23 @@ typedef struct ati68860_ramdac_t { } ati68860_ramdac_t; void -ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; switch (addr) { case 0: - svga_out(0x3c8, val, svga); + svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, val, svga); break; case 1: - svga_out(0x3c9, val, svga); + svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, val, svga); break; case 2: - svga_out(0x3c6, val, svga); + svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, val, svga); break; case 3: - svga_out(0x3c7, val, svga); + svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, val, svga); break; default: ramdac->regs[addr & 0xf] = val; @@ -113,6 +119,9 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) ramdac->dac_pos = 0; ramdac->dac_addr = (ramdac->dac_addr + 1) & 255; break; + + default: + break; } break; case 0xb: @@ -121,7 +130,8 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) ramdac->render = svga_render_4bpp_highres; break; case 0x83: - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; break; case 0xa0: case 0xb0: @@ -146,36 +156,41 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) ramdac->render = svga_render_RGBA8888_highres; break; default: - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; break; } break; case 0xc: svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); break; + + default: + break; } break; } } uint8_t -ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) +ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; - uint8_t temp = 0; + const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp = 0; switch (addr) { case 0: - temp = svga_in(0x3c8, svga); + temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, svga); break; case 1: - temp = svga_in(0x3c9, svga); + temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, svga); break; case 2: - temp = svga_in(0x3c6, svga); + temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, svga); break; case 3: - temp = svga_in(0x3c7, svga); + temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, svga); break; case 4: case 8: @@ -198,9 +213,9 @@ ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) } void -ati68860_set_ramdac_type(void *p, int type) +ati68860_set_ramdac_type(void *priv, int type) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; if (ramdac->ramdac_type != type) { ramdac->ramdac_type = type; @@ -217,28 +232,29 @@ ati68860_set_ramdac_type(void *p, int type) } static void * -ati68860_ramdac_init(const device_t *info) +ati68860_ramdac_init(UNUSED(const device_t *info)) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) malloc(sizeof(ati68860_ramdac_t)); memset(ramdac, 0, sizeof(ati68860_ramdac_t)); - ramdac->render = svga_render_8bpp_highres; + /*FIXME*/ + ramdac->render = svga_render_8bpp_clone_highres; return ramdac; } void -ati68860_ramdac_set_render(void *p, svga_t *svga) +ati68860_ramdac_set_render(void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; svga->render = ramdac->render; } void -ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) +ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; ramdac->pallook[i] = col; } @@ -246,11 +262,11 @@ ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) void ati68860_hwcursor_draw(svga_t *svga, int displine) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - int offset; - uint8_t dat; - uint32_t col0 = ramdac->pallook[0]; - uint32_t col1 = ramdac->pallook[1]; + const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + int offset; + uint8_t dat; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; offset = svga->dac_hwcursor_latch.xoff; for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) { diff --git a/src/video/vid_ati68875_ramdac.c b/src/video/vid_ati68875_ramdac.c new file mode 100644 index 0000000000..447a8eca85 --- /dev/null +++ b/src/video/vid_ati68875_ramdac.c @@ -0,0 +1,167 @@ +/* + * 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. + * + * Emulation of the Mach32-compatible ATI 68875 RAMDAC and clones. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2023 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/plat_unused.h> + +typedef struct ati68875_ramdac_t { + uint8_t gen_cntl; + uint8_t in_clk_sel; + uint8_t out_clk_sel; + uint8_t mux_cntl; + uint8_t palette_page_sel; + uint8_t test_reg; +} ati68875_ramdac_t; + +void +ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: + svga_out(addr, val, svga); + break; + case 0x08: /* General Control Register (RS value = 1000) */ + ramdac->gen_cntl = val; + break; + case 0x09: /* Input Clock Selection Register (RS value = 1001) */ + ramdac->in_clk_sel = val; + break; + case 0x0a: /* Output Clock Selection Register (RS value = 1010) */ + ramdac->out_clk_sel = val; + break; + case 0x0b: /* MUX Control Register (RS value = 1011) */ + ramdac->mux_cntl = val; + break; + case 0x0c: /* Palette Page Register (RS value = 1100) */ + ramdac->palette_page_sel = val; + break; + case 0x0e: /* Test Register (RS value = 1110) */ + ramdac->test_reg = val; + break; + case 0x0f: /* Reset State (RS value = 1111) */ + ramdac->mux_cntl = 0x2d; + break; + + default: + break; + } + + return; +} + +uint8_t +ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) +{ + const ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + uint8_t temp = 0; + + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: + temp = svga_in(addr, svga); + break; + case 0x08: /* General Control Register (RS value = 1000) */ + temp = ramdac->gen_cntl; + break; + case 0x09: /* Input Clock Selection Register (RS value = 1001) */ + temp = ramdac->in_clk_sel; + break; + case 0x0a: /* Output Clock Selection Register (RS value = 1010) */ + temp = ramdac->out_clk_sel; + break; + case 0x0b: /* MUX Control Register (RS value = 1011) */ + temp = ramdac->mux_cntl; + break; + case 0x0c: /* Palette Page Register (RS value = 1100) */ + temp = ramdac->palette_page_sel; + break; + case 0x0e: /* Test Register (RS value = 1110) */ + switch (ramdac->test_reg & 0x07) { + case 0x03: + temp = 0x75; + break; + + default: + break; + } + break; + + default: + break; + } + + return temp; +} + +static void * +ati68875_ramdac_init(UNUSED(const device_t *info)) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) malloc(sizeof(ati68875_ramdac_t)); + memset(ramdac, 0, sizeof(ati68875_ramdac_t)); + + ramdac->mux_cntl = 0x2d; + + return ramdac; +} + +static void +ati68875_ramdac_close(void *priv) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + +const device_t ati68875_ramdac_device = { + .name = "ATI 68875 RAMDAC", + .internal_name = "ati68875_ramdac", + .flags = 0, + .local = 0, + .init = ati68875_ramdac_init, + .close = ati68875_ramdac_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 2e10216e47..054d83d364 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -26,33 +26,54 @@ #include <86box/timer.h> #include <86box/nvr.h> #include <86box/vid_ati_eeprom.h> +#include <86box/plat_fallthrough.h> void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) { - FILE *f; + FILE *fp; int size; eeprom->type = type; strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); - f = nvr_fopen(eeprom->fn, "rb"); + fp = nvr_fopen(eeprom->fn, "rb"); size = eeprom->type ? 512 : 128; - if (!f) { + if (!fp) { memset(eeprom->data, 0xff, size); return; } - if (fread(eeprom->data, 1, size, f) != size) + if (fread(eeprom->data, 1, size, fp) != size) memset(eeprom->data, 0, size); - fclose(f); + fclose(fp); +} + +void +ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn) +{ + FILE *fp; + int size; + eeprom->type = 0; + strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); + fp = nvr_fopen(eeprom->fn, "rb"); + size = 128; + if (!fp) { /*The ATI Graphics Ultra bios expects an immediate write to nvram if none is present at boot time otherwise + it would hang the machine.*/ + memset(eeprom->data, 0, size); + fp = nvr_fopen(eeprom->fn, "wb"); + fwrite(eeprom->data, 1, size, fp); + } + if (fread(eeprom->data, 1, size, fp) != size) + memset(eeprom->data, 0, size); + fclose(fp); } void ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = nvr_fopen(eeprom->fn, "wb"); - if (!f) + FILE *fp = nvr_fopen(eeprom->fn, "wb"); + if (!fp) return; - fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); + fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, fp); + fclose(fp); } void @@ -73,7 +94,7 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) if (!dat) break; eeprom->state = EEPROM_OPCODE; - /* fall through */ + fallthrough; case EEPROM_OPCODE: eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); eeprom->count--; @@ -99,6 +120,9 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->state = EEPROM_INPUT; eeprom->dat = 0; break; + + default: + break; } } break; @@ -140,6 +164,9 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) case EEPROM_OP_EWEN: eeprom->wp = 0; break; + + default: + break; } eeprom->state = EEPROM_IDLE; eeprom->out = 1; @@ -163,9 +190,15 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->state = EEPROM_IDLE; eeprom->out = 1; break; + + default: + break; } } break; + + default: + break; } } eeprom->oldena = ena; @@ -180,6 +213,9 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->state = EEPROM_IDLE; } break; + + default: + break; } } } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 273dbdcf6e..9aa3963839 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -67,8 +67,7 @@ enum { FIFO_WRITE_DWORD = (0x03 << 24) }; -typedef struct -{ +typedef struct fifo_entry_t { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -92,11 +91,14 @@ typedef struct mach64_t { uint8_t regs[256]; int index; - int type, pci; + int type; + int pci; + + uint8_t pci_slot; + uint8_t irq_state; uint8_t pci_regs[256]; uint8_t int_line; - int card; int bank_r[2]; int bank_w[2]; @@ -111,6 +113,7 @@ typedef struct mach64_t { uint32_t crtc_gen_cntl; uint8_t crtc_int_cntl; + uint32_t crtc_h_sync_strt_wid; uint32_t crtc_h_total_disp; uint32_t crtc_v_sync_strt_wid; uint32_t crtc_v_total_disp; @@ -157,50 +160,77 @@ typedef struct mach64_t { uint32_t ovr_wid_top_bottom; uint32_t pat_cntl; - uint32_t pat_reg0, pat_reg1; + uint32_t pat_reg0; + uint32_t pat_reg1; - uint32_t sc_left_right, sc_top_bottom; + uint32_t sc_left_right; + uint32_t sc_top_bottom; - uint32_t scratch_reg0, scratch_reg1; + uint32_t scratch_reg0; + uint32_t scratch_reg1; uint32_t src_cntl; uint32_t src_off_pitch; uint32_t src_y_x; uint32_t src_y_x_start; - uint32_t src_height1_width1, src_height2_width2; + uint32_t src_height1_width1; + uint32_t src_height2_width2; uint32_t write_mask; uint32_t chain_mask; - uint32_t linear_base, old_linear_base; + uint32_t linear_base; uint32_t io_base; - struct - { + struct { int op; - int dst_x, dst_y; - int dst_x_start, dst_y_start; - int src_x, src_y; - int src_x_start, src_y_start; - int xinc, yinc; - int x_count, y_count; - int src_x_count, src_y_count; - int src_width1, src_height1; - int src_width2, src_height2; - uint32_t src_offset, src_pitch; - uint32_t dst_offset, dst_pitch; - int mix_bg, mix_fg; - int source_bg, source_fg, source_mix; + int dst_x; + int dst_y; + int dst_x_start; + int dst_y_start; + int src_x; + int src_y; + int src_x_start; + int src_y_start; + int xinc; + int yinc; + int x_count; + int y_count; + int xx_count; + int src_x_count; + int src_y_count; + int src_width1; + int src_height1; + int src_width2; + int src_height2; + uint32_t src_offset; + uint32_t src_pitch; + uint32_t dst_offset; + uint32_t dst_pitch; + int mix_bg; + int mix_fg; + int source_bg; + int source_fg; + int source_mix; int source_host; - int dst_width, dst_height; + int dst_width; + int dst_height; int busy; int pattern[8][8]; uint8_t pattern_clr4x2[2][4]; uint8_t pattern_clr8x1[8]; - int sc_left, sc_right, sc_top, sc_bottom; - int dst_pix_width, src_pix_width, host_pix_width; - int dst_size, src_size, host_size; + int sc_left; + int sc_right; + int sc_top; + int sc_bottom; + int dst_pix_width; + int src_pix_width; + int host_pix_width; + int dst_size; + int src_size; + int host_size; + int temp_cnt; uint32_t dp_bkgd_clr; uint32_t dp_frgd_clr; @@ -216,7 +246,8 @@ typedef struct mach64_t { } accel; fifo_entry_t fifo[FIFO_SIZE]; - atomic_int fifo_read_idx, fifo_write_idx; + atomic_int fifo_read_idx; + atomic_int fifo_write_idx; thread_t *fifo_thread; event_t *wake_fifo_thread; @@ -237,26 +268,32 @@ typedef struct mach64_t { uint32_t config_stat0; - uint32_t cur_clr0, cur_clr1; + uint32_t cur_clr0; + uint32_t cur_clr1; uint32_t overlay_dat[1024]; - uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; - uint32_t overlay_video_key_clr, overlay_video_key_msk; + uint32_t overlay_graphics_key_clr; + uint32_t overlay_graphics_key_msk; + uint32_t overlay_video_key_clr; + uint32_t overlay_video_key_msk; uint32_t overlay_key_cntl; uint32_t overlay_scale_inc; uint32_t overlay_scale_cntl; - uint32_t overlay_y_x_start, overlay_y_x_end; + uint32_t overlay_y_x_start; + uint32_t overlay_y_x_end; uint32_t scaler_height_width; int scaler_format; int scaler_update; - uint32_t buf_offset[2], buf_pitch[2]; + uint32_t buf_offset[2]; + uint32_t buf_pitch[2]; int overlay_v_acc; uint8_t thread_run; - void *i2c, *ddc; + void *i2c; + void *ddc; } mach64_t; static video_timings_t timing_mach64_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; @@ -361,9 +398,9 @@ mach64_log(const char *fmt, ...) #endif void -mach64_out(uint16_t addr, uint8_t val, void *p) +mach64_out(uint16_t addr, uint8_t val, void *priv) { - mach64_t *mach64 = p; + mach64_t *mach64 = priv; svga_t *svga = &mach64->svga; uint8_t old; @@ -385,7 +422,7 @@ mach64_out(uint16_t addr, uint8_t val, void *p) case 0x3C8: case 0x3C9: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga); else svga_out(addr, val, svga); return; @@ -404,12 +441,12 @@ mach64_out(uint16_t addr, uint8_t val, void *p) svga->crtcreg = val & 0x3f; return; case 0x3D5: + if (svga->crtcreg > 0x20) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x18) - return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -419,20 +456,23 @@ mach64_out(uint16_t addr, uint8_t val, void *p) svga->fullchange = 3; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } } } break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -mach64_in(uint16_t addr, void *p) +mach64_in(uint16_t addr, void *priv) { - mach64_t *mach64 = p; + mach64_t *mach64 = priv; svga_t *svga = &mach64->svga; if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) @@ -449,15 +489,18 @@ mach64_in(uint16_t addr, void *p) case 0x3C8: case 0x3C9: if (mach64->type == MACH64_GX) - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, svga); + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), svga->ramdac, svga); return svga_in(addr, svga); case 0x3D4: return svga->crtcreg; case 0x3D5: - if (svga->crtcreg > 0x18) + if (svga->crtcreg > 0x20) return 0xff; return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); } @@ -465,13 +508,17 @@ mach64_in(uint16_t addr, void *p) void mach64_recalctimings(svga_t *svga) { - mach64_t *mach64 = (mach64_t *) svga->p; + const mach64_t *mach64 = (mach64_t *) svga->priv; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->hblankstart = (mach64->crtc_h_sync_strt_wid & 255) + + ((mach64->crtc_h_sync_strt_wid >> 8) & 7); + svga->hblank_end_val = (svga->hblankstart + + ((mach64->crtc_h_sync_strt_wid >> 16) & 31) - 1) & 63; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen); @@ -487,42 +534,44 @@ mach64_recalctimings(svga_t *svga) case BPP_4: if (mach64->type != MACH64_GX) svga->render = svga_render_4bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_8: if (mach64->type != MACH64_GX) svga->render = svga_render_8bpp_highres; - svga->hdisp *= 8; - svga->rowoffset /= 2; + svga->hdisp <<= 3; + svga->rowoffset >>= 1; break; case BPP_15: if (mach64->type != MACH64_GX) svga->render = svga_render_15bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_16: if (mach64->type != MACH64_GX) svga->render = svga_render_16bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_24: if (mach64->type != MACH64_GX) svga->render = svga_render_24bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; svga->rowoffset = (svga->rowoffset * 3) / 2; break; case BPP_32: if (mach64->type != MACH64_GX) svga->render = svga_render_32bpp_highres; - svga->hdisp *= 8; - svga->rowoffset *= 2; + svga->hdisp <<= 3; + svga->rowoffset <<= 1; + break; + + default: break; } svga->vram_display_mask = mach64->vram_mask; - } else { + } else svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; - } } void @@ -530,7 +579,7 @@ mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + if (mach64->pci && !(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mach64_log("Update mapping - PCI disabled\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&mach64->linear_mapping); @@ -543,31 +592,36 @@ mach64_updatemapping(mach64_t *mach64) mem_mapping_disable(&mach64->mmio_mapping); switch (svga->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&svga->mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&svga->mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } + + mach64_log("Mach64 linear aperture = %08x.\n", mach64->linear_base); if (mach64->linear_base) { if (mach64->type == MACH64_GX) { if ((mach64->config_cntl & 3) == 2) { @@ -600,11 +654,12 @@ mach64_update_irqs(mach64_t *mach64) } if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) - pci_set_irq(mach64->card, PCI_INTA); + pci_set_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); else - pci_clear_irq(mach64->card, PCI_INTA); + pci_clear_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); } +#if 0 static __inline void wake_fifo_thread(mach64_t *mach64) { @@ -619,6 +674,7 @@ mach64_wait_fifo_idle(mach64_t *mach64) thread_wait_event(mach64->fifo_not_full_event, 1); } } +#endif #define READ8(addr, var) \ switch ((addr) &3) { \ @@ -691,7 +747,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x11e: case 0x11f: WRITE8(addr, mach64->dst_height_width, val); - /*FALLTHROUGH*/ + fallthrough; case 0x113: if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) { mach64_start_fill(mach64); @@ -914,7 +970,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2a4: case 0x2a5: addr += 2; - /*FALLTHROUGH*/ + fallthrough; case 0x2aa: case 0x2ab: WRITE8(addr, mach64->sc_left_right, val); @@ -929,7 +985,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2b0: case 0x2b1: addr += 2; - /*FALLTHROUGH*/ + fallthrough; case 0x2b6: case 0x2b7: WRITE8(addr, mach64->sc_top_bottom, val); @@ -1019,6 +1075,9 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) else mach64->host_cntl &= ~HOST_BYTE_ALIGN; break; + + default: + break; } } static void @@ -1115,6 +1174,7 @@ mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) } } +#if 0 static void fifo_thread(void *param) { @@ -1140,6 +1200,9 @@ fifo_thread(void *param) case FIFO_WRITE_DWORD: mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); break; + + default: + break; } mach64->fifo_read_idx++; @@ -1175,14 +1238,20 @@ mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) wake_fifo_thread(mach64); } +#endif void mach64_start_fill(mach64_t *mach64) { - mach64->accel.dst_x = 0; - mach64->accel.dst_y = 0; + mach64->accel.dst_x = 0; + mach64->accel.dst_y = 0; + mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; + if ((mach64->dst_y_x >> 16) & 0x1000) + mach64->accel.dst_x_start |= ~0xfff; + mach64->accel.dst_y_start = mach64->dst_y_x & 0x3fff; + if (mach64->dst_y_x & 0x4000) + mach64->accel.dst_y_start |= ~0x3fff; mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; @@ -1192,12 +1261,19 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.dst_width = (mach64->accel.dst_width & ~7) + 8; } - mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.xx_count = 0; + + mach64->accel.src_x = 0; + mach64->accel.src_y = 0; - mach64->accel.src_x = 0; - mach64->accel.src_y = 0; mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y_start = mach64->src_y_x & 0xfff; + if ((mach64->src_y_x >> 16) & 0x1000) + mach64->accel.src_x_start |= ~0xfff; + mach64->accel.src_y_start = mach64->src_y_x & 0x3fff; + if (mach64->src_y_x & 0x4000) + mach64->accel.src_y_start |= ~0x3fff; + if (mach64->src_cntl & SRC_LINEAR_EN) mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ else @@ -1219,11 +1295,11 @@ mach64_start_fill(mach64_t *mach64) mach64->src_height1_width1, mach64->src_height2_width2); - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3; mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; mach64->accel.mix_bg = mach64->dp_mix & 0x1f; @@ -1255,10 +1331,12 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1271,7 +1349,9 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff); mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff); mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff); - } else if (mach64->pat_cntl & 4) { + } + + if (mach64->pat_cntl & 4) { mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff); mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff); mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff); @@ -1308,16 +1388,24 @@ void mach64_start_line(mach64_t *mach64) { mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y = mach64->dst_y_x & 0xfff; + if ((mach64->dst_y_x >> 16) & 0x1000) + mach64->accel.dst_x |= ~0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0x3fff; + if (mach64->dst_y_x & 0x4000) + mach64->accel.dst_y |= ~0x3fff; mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y = mach64->src_y_x & 0xfff; + if ((mach64->src_y_x >> 16) & 0x1000) + mach64->accel.src_x |= ~0xfff; + mach64->accel.src_y = mach64->src_y_x & 0x3fff; + if (mach64->src_y_x & 0x4000) + mach64->accel.src_y |= ~0x3fff; - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3; mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; mach64->accel.mix_bg = mach64->dp_mix & 0x1f; @@ -1344,15 +1432,14 @@ mach64_start_line(mach64_t *mach64) else mach64->accel.dst_offset >>= mach64->accel.dst_size; - /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1446,18 +1533,19 @@ mach64_start_line(mach64_t *mach64) break; \ case 0x17: \ dest_dat = (dest_dat + src_dat) >> 1; \ + break; \ } #define WRITE(addr, width) \ if (width == 0) { \ svga->vram[(addr) &mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) &mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else if (width == 1) { \ *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else if (width == 2) { \ *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else { \ if (dest_dat & 1) { \ if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ @@ -1470,7 +1558,7 @@ mach64_start_line(mach64_t *mach64) else \ svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \ } \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } void @@ -1478,29 +1566,36 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) { svga_t *svga = &mach64->svga; int cmp_clr = 0; + int mix = 0; if (!mach64->accel.busy) { mach64_log("mach64_blit : return as not busy\n"); return; } + switch (mach64->accel.op) { case OP_RECT: while (count) { - uint32_t src_dat = 0; + uint8_t write_mask = 0; + uint32_t src_dat = 0; uint32_t dest_dat; uint32_t host_dat = 0; uint32_t old_dest_dat; - int mix = 0; - int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; - int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; + int dst_x; + int dst_y; int src_x; - int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; + int src_y; + + dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; + dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0x3fff; if (mach64->src_cntl & SRC_LINEAR_EN) src_x = mach64->accel.src_x; else src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; + src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0x3fff; + if (mach64->accel.source_host) { host_dat = cpu_dat; switch (mach64->accel.host_size) { @@ -1515,6 +1610,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 2: count -= 32; break; + + default: + break; } } else count--; @@ -1525,12 +1623,16 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mix = cpu_dat & 1; cpu_dat >>= 1; } else { - mix = cpu_dat >> 31; + mix = cpu_dat >> 0x1f; cpu_dat <<= 1; } break; case MONO_SRC_PAT: - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (!mach64->accel.xx_count) + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + } else + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; break; case MONO_SRC_1: mix = 1; @@ -1542,6 +1644,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT); } break; + + default: + break; } if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) { @@ -1553,24 +1658,42 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_frgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (mach64->accel.xinc == -1) { + if (mach64->accel.xx_count == 2) + src_dat = mach64->accel.dp_frgd_clr & 0xff; + else if (mach64->accel.xx_count == 1) + src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; + else + src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + } else { + if (mach64->accel.xx_count == 2) + src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + else if (mach64->accel.xx_count == 1) + src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; + else + src_dat = mach64->accel.dp_frgd_clr & 0xff; + } } else src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_bkgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (mach64->accel.xinc == -1) { + if (mach64->accel.xx_count == 2) + src_dat = mach64->accel.dp_bkgd_clr & 0xff; + else if (mach64->accel.xx_count == 1) + src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; + else + src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + } else { + if (mach64->accel.xx_count == 2) + src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + else if (mach64->accel.xx_count == 1) + src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; + else + src_dat = mach64->accel.dp_bkgd_clr & 0xff; + } } else src_dat = mach64->accel.dp_bkgd_clr; break; @@ -1582,6 +1705,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) src_dat = mach64->accel.pattern_clr8x1[dst_x & 7]; break; } + default: src_dat = 0; break; @@ -1595,7 +1719,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) { - READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); + READ(mach64->accel.dst_offset + ((dst_y) *mach64->accel.dst_pitch) + (dst_x), dest_dat, mach64->accel.dst_size); switch (mach64->accel.clr_cmp_fn) { case 1: /*TRUE*/ @@ -1607,24 +1731,36 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 5: /*DST_CLR == CLR_CMP_CLR*/ cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; break; + + default: + break; } if (!cmp_clr) { old_dest_dat = dest_dat; MIX - dest_dat - = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (mach64->accel.xinc == -1) { + if (mach64->accel.xx_count == 2) + write_mask = mach64->accel.write_mask & 0xff; + else if (mach64->accel.xx_count == 1) + write_mask = (mach64->accel.write_mask >> 8) & 0xff; + else + write_mask = (mach64->accel.write_mask >> 16) & 0xff; + } else { + if (mach64->accel.xx_count == 2) + write_mask = (mach64->accel.write_mask >> 16) & 0xff; + else if (mach64->accel.xx_count == 1) + write_mask = (mach64->accel.write_mask >> 8) & 0xff; + else + write_mask = mach64->accel.write_mask & 0xff; + } + dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask); + } else + dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); } - WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); - } - } - - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) != (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); - mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); - mach64->accel.write_mask = ((mach64->accel.write_mask >> 8) & 0xffff) | (mach64->accel.write_mask << 16); + WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size); } } @@ -1636,6 +1772,8 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64->accel.src_x = 0; if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; + if ((mach64->src_y_x_start >> 16) & 0x1000) + mach64->accel.src_x_start |= ~0xfff; mach64->accel.src_x_count = mach64->accel.src_width2; } else mach64->accel.src_x_count = mach64->accel.src_width1; @@ -1643,9 +1781,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } mach64->accel.x_count--; + mach64->accel.xx_count = (mach64->accel.xx_count + 1) % 3; if (mach64->accel.x_count <= 0) { - mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.dst_x = 0; + mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.xx_count = 0; + mach64->accel.dst_x = 0; mach64->accel.dst_y += mach64->accel.yinc; mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; mach64->accel.src_x_count = mach64->accel.src_width1; @@ -1657,7 +1797,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (mach64->accel.src_y_count <= 0) { mach64->accel.src_y = 0; if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { - mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; + mach64->accel.src_y_start = mach64->src_y_x_start & 0x3fff; + if (mach64->src_y_x_start & 0x4000) + mach64->accel.src_y_start |= ~0x3fff; mach64->accel.src_y_count = mach64->accel.src_height2; } else mach64->accel.src_y_count = mach64->accel.src_height1; @@ -1665,9 +1807,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } mach64->accel.poly_draw = 0; - mach64->accel.dst_height--; - if (mach64->accel.dst_height <= 0) { /*Blit finished*/ mach64_log("mach64 blit finished\n"); @@ -1695,14 +1835,14 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { int x = 0; while (count) { - uint32_t src_dat = 0; + uint32_t src_dat = 0; uint32_t dest_dat; uint32_t host_dat = 0; int mix = 0; if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64->accel.src_size) { + switch (mach64->accel.host_size) { case 0: cpu_dat >>= 8; count -= 8; @@ -1714,6 +1854,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 2: count -= 32; break; + + default: + break; } } else count--; @@ -1737,6 +1880,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case MONO_SRC_BLITSRC: READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, mix, WIDTH_1BIT); break; + + default: + break; } if ((mach64->accel.dst_x >= mach64->accel.sc_left) && (mach64->accel.dst_x <= mach64->accel.sc_right) && (mach64->accel.dst_y >= mach64->accel.sc_top) && (mach64->accel.dst_y <= mach64->accel.sc_bottom)) { @@ -1778,17 +1924,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 5: /*DST_CLR == CLR_CMP_CLR*/ cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; break; + + default: + break; } if (!cmp_clr) MIX - if (!(mach64->dst_cntl & DST_Y_MAJOR)) - { - if (x == 0) - dest_dat &= ~1; - } - else { + if (!(mach64->dst_cntl & DST_Y_MAJOR)) { + if (!x) + dest_dat &= ~1; + } else { if (x == (mach64->accel.x_count - 1)) dest_dat &= ~1; } @@ -1823,7 +1970,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } } else { while (count) { - uint32_t src_dat = 0; + uint32_t src_dat = 0; uint32_t dest_dat; uint32_t host_dat = 0; int mix = 0; @@ -1831,7 +1978,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64->accel.src_size) { + switch (mach64->accel.host_size) { case 0: cpu_dat >>= 8; count -= 8; @@ -1843,6 +1990,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 2: count -= 32; break; + + default: + break; } } else count--; @@ -1904,12 +2054,15 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case 5: /*DST_CLR == CLR_CMP_CLR*/ cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; break; + + default: + break; } if (!cmp_clr) MIX - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } mach64->accel.x_count--; @@ -1941,6 +2094,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64->accel.src_y++; mach64->accel.dst_y++; break; + + default: + break; } mach64_log("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); if (mach64->accel.err >= 0) { @@ -1967,12 +2123,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64->accel.src_x++; mach64->accel.dst_x++; break; + + default: + break; } } else mach64->accel.err += mach64->dst_bres_inc; } } break; + + default: + break; } } @@ -2072,6 +2234,9 @@ pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) mach64_log(" %g\n", mach64->pll_freq[c]); } break; + + default: + break; } } @@ -2079,7 +2244,7 @@ pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) static void mach64_vblank_start(svga_t *svga) { - mach64_t *mach64 = (mach64_t *) svga->p; + mach64_t *mach64 = (mach64_t *) svga->priv; int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; mach64->crtc_int_cntl |= 4; @@ -2101,9 +2266,9 @@ mach64_vblank_start(svga_t *svga) } uint8_t -mach64_ext_readb(uint32_t addr, void *p) +mach64_ext_readb(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; uint8_t ret = 0xff; if (!(addr & 0x400)) { @@ -2187,6 +2352,12 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x03: READ8(addr, mach64->crtc_h_total_disp); break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + READ8(addr, mach64->crtc_h_sync_strt_wid); + break; case 0x08: case 0x09: case 0x0a: @@ -2347,6 +2518,7 @@ mach64_ext_readb(uint32_t addr, void *p) mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); else mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); + READ8(addr, mach64->config_cntl); break; case 0xe0: @@ -2366,32 +2538,32 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x101: case 0x102: case 0x103: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_off_pitch); break; case 0x104: case 0x105: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x108: case 0x109: case 0x11c: case 0x11d: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->dst_y_x); break; case 0x10c: case 0x10d: case 0x10e: case 0x10f: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x110: case 0x111: addr += 2; - /*FALLTHROUGH*/ + fallthrough; case 0x114: case 0x115: case 0x118: @@ -2400,7 +2572,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x11b: case 0x11e: case 0x11f: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_height_width); break; @@ -2408,28 +2580,28 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x121: case 0x122: case 0x123: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_lnth); break; case 0x124: case 0x125: case 0x126: case 0x127: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_err); break; case 0x128: case 0x129: case 0x12a: case 0x12b: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_inc); break; case 0x12c: case 0x12d: case 0x12e: case 0x12f: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_dec); break; @@ -2437,7 +2609,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x131: case 0x132: case 0x133: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; @@ -2445,75 +2617,75 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x181: case 0x182: case 0x183: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_off_pitch); break; case 0x184: case 0x185: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x188: case 0x189: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x); break; case 0x18c: case 0x18d: case 0x18e: case 0x18f: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x190: case 0x191: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height1_width1); break; case 0x194: case 0x195: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x198: case 0x199: case 0x19a: case 0x19b: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x19c: case 0x19d: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a0: case 0x1a1: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x_start); break; case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a8: case 0x1a9: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height2_width2); break; case 0x1ac: case 0x1ad: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; @@ -2521,7 +2693,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x1b5: case 0x1b6: case 0x1b7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_cntl); break; @@ -2529,7 +2701,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x241: case 0x242: case 0x243: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->host_cntl); break; @@ -2537,14 +2709,14 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x281: case 0x282: case 0x283: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg0); break; case 0x284: case 0x285: case 0x286: case 0x287: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg1); break; @@ -2552,7 +2724,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x289: case 0x28a: case 0x28b: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_cntl); break; @@ -2560,16 +2732,16 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2a1: case 0x2a8: case 0x2a9: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; case 0x2a4: case 0x2a5: addr += 2; - /*FALLTHROUGH*/ + fallthrough; case 0x2aa: case 0x2ab: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; @@ -2577,16 +2749,16 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2ad: case 0x2b4: case 0x2b5: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; case 0x2b0: case 0x2b1: addr += 2; - /*FALLTHROUGH*/ + fallthrough; case 0x2b6: case 0x2b7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; @@ -2594,14 +2766,14 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2c1: case 0x2c2: case 0x2c3: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_bkgd_clr); break; case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_frgd_clr); break; @@ -2609,7 +2781,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2c9: case 0x2ca: case 0x2cb: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->write_mask); break; @@ -2617,7 +2789,7 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2cd: case 0x2ce: case 0x2cf: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->chain_mask); break; @@ -2625,21 +2797,21 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x2d1: case 0x2d2: case 0x2d3: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_pix_width); break; case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_mix); break; case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_src); break; @@ -2647,57 +2819,53 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x301: case 0x302: case 0x303: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_clr); break; case 0x304: case 0x305: case 0x306: case 0x307: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_mask); break; case 0x308: case 0x309: case 0x30a: case 0x30b: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_cntl); break; case 0x310: case 0x311: - if (!FIFO_EMPTY) - wake_fifo_thread(mach64); ret = 0; - if (FIFO_FULL) - ret = 0xff; break; case 0x320: case 0x321: case 0x322: case 0x323: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->context_mask); break; case 0x330: case 0x331: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; case 0x332: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr - 2, mach64->src_cntl); break; case 0x333: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr - 3, mach64->pat_cntl); break; case 0x338: - ret = FIFO_EMPTY ? 0 : 1; + ret = 0; break; default: @@ -2709,10 +2877,11 @@ mach64_ext_readb(uint32_t addr, void *p) return ret; } uint16_t -mach64_ext_readw(uint32_t addr, void *p) +mach64_ext_readw(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + const mach64_t *mach64 = (mach64_t *) priv; uint16_t ret; + if (!(addr & 0x400)) { mach64_log("nmach64_ext_readw: addr=%04x\n", addr); ret = 0xffff; @@ -2728,8 +2897,8 @@ mach64_ext_readw(uint32_t addr, void *p) break; default: - ret = mach64_ext_readb(addr, p); - ret |= mach64_ext_readb(addr + 1, p) << 8; + ret = mach64_ext_readb(addr, priv); + ret |= mach64_ext_readb(addr + 1, priv) << 8; break; } if ((addr & 0x3fc) != 0x018) @@ -2737,10 +2906,11 @@ mach64_ext_readw(uint32_t addr, void *p) return ret; } uint32_t -mach64_ext_readl(uint32_t addr, void *p) +mach64_ext_readl(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; - uint32_t ret; + const mach64_t *mach64 = (mach64_t *) priv; + uint32_t ret; + if (!(addr & 0x400)) { mach64_log("nmach64_ext_readl: addr=%04x\n", addr); ret = 0xffffffff; @@ -2760,8 +2930,8 @@ mach64_ext_readl(uint32_t addr, void *p) break; default: - ret = mach64_ext_readw(addr, p); - ret |= mach64_ext_readw(addr + 2, p) << 16; + ret = mach64_ext_readw(addr, priv); + ret |= mach64_ext_readw(addr + 2, priv) << 16; break; } if ((addr & 0x3fc) != 0x018) @@ -2770,9 +2940,9 @@ mach64_ext_readl(uint32_t addr, void *p) } void -mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) +mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); @@ -2872,11 +3042,14 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0xa7: WRITE8(addr, mach64->buf_pitch[1], val); break; + + default: + break; } mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + mach64_accel_write_fifo(mach64, addr & 0x3ff, val); } else switch (addr & 0x3ff) { case 0x00: @@ -2885,6 +3058,15 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x03: WRITE8(addr, mach64->crtc_h_total_disp, val); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + WRITE8(addr, mach64->crtc_h_sync_strt_wid, val); + svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x08: case 0x09: @@ -2892,6 +3074,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x0b: WRITE8(addr, mach64->crtc_v_total_disp, val); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x0c: case 0x0d: @@ -2899,6 +3082,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x0f: WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x14: @@ -2907,7 +3091,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x17: WRITE8(addr, mach64->crtc_off_pitch, val); svga_recalctimings(&mach64->svga); - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x18: @@ -2928,6 +3112,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) svga->fb_only = 0; svga->dpms = !!(mach64->crtc_gen_cntl & 0x0c); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x40: @@ -3086,55 +3271,58 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) if (mach64->type != MACH64_GX) WRITE8(addr, mach64->config_stat0, val); break; + + default: + break; } } void -mach64_ext_writew(uint32_t addr, uint16_t val, void *p) +mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; mach64_log("mach64_ext_writew : addr %08X val %04X\n", addr, val); if (!(addr & 0x400)) { mach64_log("mach64_ext_writew: addr=%04x val=%04x\n", addr, val); - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); + mach64_ext_writeb(addr, val, priv); + mach64_ext_writeb(addr + 1, val >> 8, priv); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val); } else switch (addr & 0x3fe) { default: - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); + mach64_ext_writeb(addr, val, priv); + mach64_ext_writeb(addr + 1, val >> 8, priv); break; } } void -mach64_ext_writel(uint32_t addr, uint32_t val, void *p) +mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; if ((addr & 0x3c0) != 0x200) mach64_log("mach64_ext_writel : addr %08X val %08X\n", addr, val); if (!(addr & 0x400)) { mach64_log("mach64_ext_writel: addr=%04x val=%08x\n", addr, val); - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); + mach64_ext_writew(addr, val, priv); + mach64_ext_writew(addr + 2, val >> 16, priv); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val); } else switch (addr & 0x3fc) { default: - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); + mach64_ext_writew(addr, val, priv); + mach64_ext_writew(addr + 2, val >> 16, priv); break; } } uint8_t -mach64_ext_inb(uint16_t port, void *p) +mach64_ext_inb(uint16_t port, void *priv) { - mach64_t *mach64 = (mach64_t *) p; - uint8_t ret; + mach64_t *mach64 = (mach64_t *) priv; + uint8_t ret = 0xff; switch (port) { case 0x02ec: @@ -3145,135 +3333,135 @@ mach64_ext_inb(uint16_t port, void *p) case 0x7eed: case 0x7eee: case 0x7eef: - ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), priv); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), priv); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), priv); break; case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef: - ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), priv); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), priv); break; case 0x1aec: - ret = mach64_ext_readb(0x400 | 0x18, p); + ret = mach64_ext_readb(0x400 | 0x18, priv); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), priv); break; case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), priv); break; case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), priv); break; case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), priv); break; case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), priv); break; case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), priv); break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), priv); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), priv); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), priv); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), priv); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), priv); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), priv); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), priv); break; case 0x56ec: - ret = mach64_ext_readb(0x400 | 0xb4, p); + ret = mach64_ext_readb(0x400 | 0xb4, priv); break; case 0x56ed: case 0x56ee: - ret = mach64_ext_readb(0x400 | 0xb5, p); + ret = mach64_ext_readb(0x400 | 0xb5, priv); break; case 0x5aec: - ret = mach64_ext_readb(0x400 | 0xb8, p); + ret = mach64_ext_readb(0x400 | 0xb8, priv); break; case 0x5aed: case 0x5aee: - ret = mach64_ext_readb(0x400 | 0xb9, p); + ret = mach64_ext_readb(0x400 | 0xb9, priv); break; case 0x5eec: @@ -3290,14 +3478,14 @@ mach64_ext_inb(uint16_t port, void *p) case 0x62ed: case 0x62ee: case 0x62ef: - ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), priv); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), priv); break; case 0x6aec: @@ -3312,14 +3500,14 @@ mach64_ext_inb(uint16_t port, void *p) case 0x6eed: case 0x6eee: case 0x6eef: - ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), priv); break; case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: - ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), priv); break; default: @@ -3330,33 +3518,33 @@ mach64_ext_inb(uint16_t port, void *p) return ret; } uint16_t -mach64_ext_inw(uint16_t port, void *p) +mach64_ext_inw(uint16_t port, void *priv) { uint16_t ret; switch (port) { default: - ret = mach64_ext_inb(port, p); - ret |= (mach64_ext_inb(port + 1, p) << 8); + ret = mach64_ext_inb(port, priv); + ret |= (mach64_ext_inb(port + 1, priv) << 8); break; } mach64_log("mach64_ext_inw : port %04X ret %04X\n", port, ret); return ret; } uint32_t -mach64_ext_inl(uint16_t port, void *p) +mach64_ext_inl(uint16_t port, void *priv) { uint32_t ret; switch (port) { case 0x56ec: - ret = mach64_ext_readl(0x400 | 0xb4, p); + ret = mach64_ext_readl(0x400 | 0xb4, priv); break; case 0x5aec: - ret = mach64_ext_readl(0x400 | 0xb8, p); + ret = mach64_ext_readl(0x400 | 0xb8, priv); break; default: - ret = mach64_ext_inw(port, p); - ret |= (mach64_ext_inw(port + 2, p) << 16); + ret = mach64_ext_inw(port, priv); + ret |= (mach64_ext_inw(port + 2, priv) << 16); break; } mach64_log("mach64_ext_inl : port %04X ret %08X\n", port, ret); @@ -3364,9 +3552,9 @@ mach64_ext_inl(uint16_t port, void *p) } void -mach64_ext_outb(uint16_t port, uint8_t val, void *p) +mach64_ext_outb(uint16_t port, uint8_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); switch (port) { @@ -3378,128 +3566,128 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x7eed: case 0x7eee: case 0x7eef: - mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, priv); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, priv); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, priv); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, priv); break; case 0x1aec: - mach64_ext_writeb(0x400 | 0x18, val, p); + mach64_ext_writeb(0x400 | 0x18, val, priv); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, priv); break; case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, priv); break; case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, priv); break; case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, priv); break; case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, priv); break; case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, priv); break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, priv); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, priv); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, priv); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, priv); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, priv); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, priv); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, priv); break; case 0x56ec: - mach64_ext_writeb(0x400 | 0xb4, val, p); + mach64_ext_writeb(0x400 | 0xb4, val, priv); break; case 0x56ed: case 0x56ee: - mach64_ext_writeb(0x400 | 0xb5, val, p); + mach64_ext_writeb(0x400 | 0xb5, val, priv); break; case 0x5aec: - mach64_ext_writeb(0x400 | 0xb8, val, p); + mach64_ext_writeb(0x400 | 0xb8, val, priv); break; case 0x5aed: case 0x5aee: - mach64_ext_writeb(0x400 | 0xb9, val, p); + mach64_ext_writeb(0x400 | 0xb9, val, priv); break; case 0x5eec: @@ -3516,14 +3704,14 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x62ed: case 0x62ee: case 0x62ef: - mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, priv); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, priv); break; case 0x6aec: @@ -3533,35 +3721,38 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *p) WRITE8(port, mach64->config_cntl, val); mach64_updatemapping(mach64); break; + + default: + break; } } void -mach64_ext_outw(uint16_t port, uint16_t val, void *p) +mach64_ext_outw(uint16_t port, uint16_t val, void *priv) { mach64_log("mach64_ext_outw : port %04X val %04X\n", port, val); switch (port) { default: - mach64_ext_outb(port, val, p); - mach64_ext_outb(port + 1, val >> 8, p); + mach64_ext_outb(port, val, priv); + mach64_ext_outb(port + 1, val >> 8, priv); break; } } void -mach64_ext_outl(uint16_t port, uint32_t val, void *p) +mach64_ext_outl(uint16_t port, uint32_t val, void *priv) { mach64_log("mach64_ext_outl : port %04X val %08X\n", port, val); switch (port) { default: - mach64_ext_outw(port, val, p); - mach64_ext_outw(port + 2, val >> 16, p); + mach64_ext_outw(port, val, priv); + mach64_ext_outw(port + 2, val >> 16, priv); break; } } static uint8_t -mach64_block_inb(uint16_t port, void *p) +mach64_block_inb(uint16_t port, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; uint8_t ret; ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); @@ -3569,9 +3760,9 @@ mach64_block_inb(uint16_t port, void *p) return ret; } static uint16_t -mach64_block_inw(uint16_t port, void *p) +mach64_block_inw(uint16_t port, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; uint16_t ret; ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); @@ -3579,9 +3770,9 @@ mach64_block_inw(uint16_t port, void *p) return ret; } static uint32_t -mach64_block_inl(uint16_t port, void *p) +mach64_block_inl(uint16_t port, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; uint32_t ret; ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); @@ -3590,51 +3781,51 @@ mach64_block_inl(uint16_t port, void *p) } static void -mach64_block_outb(uint16_t port, uint8_t val, void *p) +mach64_block_outb(uint16_t port, uint8_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; mach64_log("mach64_block_outb : port %04X val %02X\n ", port, val); mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); } static void -mach64_block_outw(uint16_t port, uint16_t val, void *p) +mach64_block_outw(uint16_t port, uint16_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; mach64_log("mach64_block_outw : port %04X val %04X\n ", port, val); mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); } static void -mach64_block_outl(uint16_t port, uint32_t val, void *p) +mach64_block_outl(uint16_t port, uint32_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; mach64_log("mach64_block_outl : port %04X val %08X\n ", port, val); mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); } void -mach64_write(uint32_t addr, uint8_t val, void *p) +mach64_write(uint32_t addr, uint8_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; svga_write_linear(addr, val, svga); } void -mach64_writew(uint32_t addr, uint16_t val, void *p) +mach64_writew(uint32_t addr, uint16_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; svga_writew_linear(addr, val, svga); } void -mach64_writel(uint32_t addr, uint32_t val, void *p) +mach64_writel(uint32_t addr, uint32_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; @@ -3642,9 +3833,9 @@ mach64_writel(uint32_t addr, uint32_t val, void *p) } uint8_t -mach64_read(uint32_t addr, void *p) +mach64_read(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; uint8_t ret; addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; @@ -3652,18 +3843,18 @@ mach64_read(uint32_t addr, void *p) return ret; } uint16_t -mach64_readw(uint32_t addr, void *p) +mach64_readw(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } uint32_t -mach64_readl(uint32_t addr, void *p) +mach64_readl(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_t *svga = &mach64->svga; addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; @@ -3797,7 +3988,7 @@ mach64_readl(uint32_t addr, void *p) void mach64_overlay_draw(svga_t *svga, int displine) { - mach64_t *mach64 = (mach64_t *) svga->p; + mach64_t *mach64 = (mach64_t *) svga->priv; int x; int h_acc = 0; int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; @@ -3853,9 +4044,9 @@ mach64_overlay_draw(svga_t *svga, int displine) } } else { for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { - int h = h_acc >> 12; - int gr_cmp = 0; - int vid_cmp = 0; + int h = h_acc >> 12; + int gr_cmp = 0; + int vid_cmp = 0; int use_video = 0; switch (video_key_fn) { @@ -3871,6 +4062,9 @@ mach64_overlay_draw(svga_t *svga, int displine) case 5: vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; + + default: + break; } switch (graphics_key_fn) { case 0: @@ -3885,6 +4079,9 @@ mach64_overlay_draw(svga_t *svga, int displine) case 5: gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; + + default: + break; } vid_cmp = vid_cmp ? -1 : 0; gr_cmp = gr_cmp ? -1 : 0; @@ -3938,6 +4135,9 @@ mach64_overlay_draw(svga_t *svga, int displine) case 0xf: use_video = ~gr_cmp & ~vid_cmp; break; + + default: + break; } if (use_video) @@ -3969,8 +4169,8 @@ mach64_io_remove(mach64_t *mach64) uint16_t io_base = 0x02ec; switch (mach64->io_base) { - case 0: default: + case 0: io_base = 0x02ec; break; case 1: @@ -4022,9 +4222,9 @@ mach64_io_set(mach64_t *mach64) } uint8_t -mach64_pci_read(int func, int addr, void *p) +mach64_pci_read(UNUSED(int func), int addr, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + const mach64_t *mach64 = (mach64_t *) priv; switch (addr) { case 0x00: @@ -4098,14 +4298,17 @@ mach64_pci_read(int func, int addr, void *p) case 0x40: return mach64->use_block_decoded_io | mach64->io_base; + + default: + break; } return 0; } void -mach64_pci_write(int func, int addr, uint8_t val, void *p) +mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; switch (addr) { case PCI_REG_COMMAND: @@ -4183,26 +4386,32 @@ mach64_pci_write(int func, int addr, uint8_t val, void *p) if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) mach64_io_set(mach64); break; + + default: + break; } } static void * mach64_common_init(const device_t *info) { + svga_t *svga; mach64_t *mach64 = malloc(sizeof(mach64_t)); memset(mach64, 0, sizeof(mach64_t)); + svga = &mach64->svga; + mach64->vram_size = device_get_config_int("memory"); mach64->vram_mask = (mach64->vram_size << 20) - 1; - svga_init(info, &mach64->svga, mach64, mach64->vram_size << 20, + svga_init(info, svga, mach64, mach64->vram_size << 20, mach64_recalctimings, mach64_in, mach64_out, NULL, mach64_overlay_draw); - mach64->svga.dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.cur_ysize = 64; - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &mach64->svga); + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); @@ -4210,30 +4419,24 @@ mach64_common_init(const device_t *info) mach64_io_set(mach64); - if (info->flags & DEVICE_PCI) { - mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); - } + if (info->flags & DEVICE_PCI) + pci_add_card(PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; mach64->pci_regs[0x32] = 0x0c; mach64->pci_regs[0x33] = 0x00; - mach64->svga.ramdac = device_add(&ati68860_ramdac_device); - mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw; + svga->ramdac = device_add(&ati68860_ramdac_device); + svga->dac_hwcursor_draw = ati68860_hwcursor_draw; - mach64->svga.clock_gen = device_add(&ics2595_device); + svga->clock_gen = device_add(&ics2595_device); mach64->dst_cntl = 3; mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); - mach64->wake_fifo_thread = thread_create_event(); - mach64->fifo_not_full_event = thread_create_event(); - mach64->thread_run = 1; - mach64->fifo_thread = thread_create(fifo_thread, mach64); - return mach64; } @@ -4251,8 +4454,8 @@ mach64gx_init(const device_t *info) mach64->type = MACH64_GX; mach64->pci = !!(info->flags & DEVICE_PCI); - mach64->pci_id = (int) 'X' | ((int) 'G' << 8); - mach64->config_chip_id = 0x020000d7; + mach64->pci_id = 'X' | ('G' << 8); + mach64->config_chip_id = 0x000000d7; mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ if (info->flags & DEVICE_PCI) @@ -4282,10 +4485,7 @@ mach64vt2_init(const device_t *info) mach64_t *mach64 = mach64_common_init(info); svga_t *svga = &mach64->svga; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); mach64->type = MACH64_VT2; mach64->pci = 1; @@ -4299,8 +4499,7 @@ mach64vt2_init(const device_t *info) rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); + mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; @@ -4329,15 +4528,9 @@ mach64vt2_available(void) } void -mach64_close(void *p) +mach64_close(void *priv) { - mach64_t *mach64 = (mach64_t *) p; - - mach64->thread_run = 0; - thread_set_event(mach64->wake_fifo_thread); - thread_wait(mach64->fifo_thread); - thread_destroy_event(mach64->fifo_not_full_event); - thread_destroy_event(mach64->wake_fifo_thread); + mach64_t *mach64 = (mach64_t *) priv; svga_close(&mach64->svga); @@ -4348,19 +4541,19 @@ mach64_close(void *p) } void -mach64_speed_changed(void *p) +mach64_speed_changed(void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; svga_recalctimings(&mach64->svga); } void -mach64_force_redraw(void *p) +mach64_force_redraw(void *priv) { - mach64_t *mach64 = (mach64_t *) p; + mach64_t *mach64 = (mach64_t *) priv; - mach64->svga.fullchange = changeframecount; + mach64->svga.fullchange = mach64->svga.monitor->mon_changeframecount; } // clang-format off diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c new file mode 100644 index 0000000000..3888e9c264 --- /dev/null +++ b/src/video/vid_ati_mach8.c @@ -0,0 +1,6330 @@ +/* + * 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. + * + * Emulation of the 8514/A-compatible Mach8 and Mach32 graphics + * chips from ATI for the ISA/VLB/MCA/PCI buses. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/mca.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/plat.h> +#include <86box/thread.h> +#include <86box/video.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> +#include <86box/vid_8514a.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/vid_ati_eeprom.h> +#include <86box/vid_ati_mach8.h> + +#define BIOS_MACH8_VGA_ROM_PATH "roms/video/mach8/BIOS.BIN" +#define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/ATi Mach32 Graphics Pro ISA.BIN" +#define BIOS_MACH32_VLB_ROM_PATH "roms/video/mach32/MACH32VLB.VBI" +#define BIOS_MACH32_MCA_ROM_PATH "roms/video/mach32/MACH32MCA_Olivetti.BIN" +#define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/intelopt_00000.rom" + +static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_mach32_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_mach32_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; + +static void mach_accel_outb(uint16_t port, uint8_t val, void *priv); +static void mach_accel_outw(uint16_t port, uint16_t val, void *priv); +static uint8_t mach_accel_inb(uint16_t port, void *priv); +static uint16_t mach_accel_inw(uint16_t port, void *priv); +static uint8_t mach_in(uint16_t addr, void *priv); + +#ifdef ATI_8514_ULTRA +static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); +static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); +static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); +static uint8_t ati8514_accel_inb(uint16_t port, void *priv); +static uint16_t ati8514_accel_inw(uint16_t port, void *priv); +static uint32_t ati8514_accel_inl(uint16_t port, void *priv); +#endif + + +static void mach32_updatemapping(mach_t *mach, svga_t *svga); + +#ifdef ENABLE_MACH_LOG +int mach_do_log = ENABLE_MACH_LOG; + +static void +mach_log(const char *fmt, ...) +{ + va_list ap; + + if (mach_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mach_log(fmt, ...) +#endif + +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ + } + +#define READ8(addr, var) \ + switch ((addr) & 1) { \ + case 0: \ + temp = (var) & 0xff; \ + break; \ + case 1: \ + temp = ((var) >> 8) & 0xff; \ + break; \ + } + +#define READ_PIXTRANS_BYTE_IO(cx, n) \ + if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if (dev->bpp) { \ + if (n == 0) \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] & 0xff; \ + else \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] >> 8; \ + } else { \ + mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + } \ + } + +#define READ_PIXTRANS_WORD(cx, n) \ + if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ + if (dev->bpp) \ + temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if (dev->bpp) \ + temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ + if (dev->bpp) \ + temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } + +#define READ(addr, dat) \ + if (dev->bpp) \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ + else \ + dat = dev->vram[(addr) & (dev->vram_mask)]; + +#define MIX(mixmode, dest_dat, src_dat) \ + { \ + switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x01: \ + dest_dat = 0; \ + break; \ + case 0x02: \ + dest_dat = ~0; \ + break; \ + case 0x03: \ + dest_dat = dest_dat; \ + break; \ + case 0x04: \ + dest_dat = ~src_dat; \ + break; \ + case 0x05: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x06: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x07: \ + dest_dat = src_dat; \ + break; \ + case 0x08: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x09: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0x0a: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0x0b: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0x0c: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0x0d: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0x0e: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0x0f: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x10: \ + dest_dat = MIN(src_dat, dest_dat); \ + break; \ + case 0x11: \ + dest_dat = dest_dat - src_dat; \ + break; \ + case 0x12: \ + dest_dat = src_dat - dest_dat; \ + break; \ + case 0x13: \ + dest_dat = src_dat + dest_dat; \ + break; \ + case 0x14: \ + dest_dat = MAX(src_dat, dest_dat); \ + break; \ + case 0x15: \ + dest_dat = (dest_dat - src_dat) / 2; \ + break; \ + case 0x16: \ + dest_dat = (src_dat - dest_dat) / 2; \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) / 2; \ + break; \ + case 0x18: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x19: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x1a: \ + dest_dat = MAX(0, (src_dat - dest_dat)); \ + break; \ + case 0x1b: \ + dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + break; \ + case 0x1c: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1d: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1e: \ + dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ + break; \ + case 0x1f: \ + dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + break; \ + } \ + } + + +#define WRITE(addr, dat) \ + if (dev->bpp) { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } + +static int +mach_pixel_write(mach_t *mach) +{ + if (mach->accel.dp_config & 1) + return 1; + + return 0; +} + +static int +mach_pixel_read(mach_t *mach) +{ + if (mach->accel.dp_config & 1) + return 0; + + return 1; +} + +static void +mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev) +{ + int compare_mode; + uint16_t poly_src = 0; + uint16_t rd_mask = dev->accel.rd_mask; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t dest_cmp_clr = dev->accel.color_cmp; + int frgd_sel; + int bkgd_sel; + int mono_src; + int compare = 0; + uint16_t src_dat = 0; + uint16_t dest_dat = 0; + uint16_t old_dest_dat; + uint16_t *vram_w = (uint16_t *) dev->vram; + uint16_t mix = 0; + int16_t clip_l = dev->accel.clip_left & 0x7ff; + int16_t clip_t = dev->accel.clip_top & 0x7ff; + int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + uint32_t mono_dat0 = 0; + uint32_t mono_dat1 = 0; + + if (!dev->bpp) { + rd_mask &= 0xff; + dest_cmp_clr &= 0xff; + } + + compare_mode = (mach->accel.dest_cmp_fn >> 3) & 7; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + mach->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + mach->force_busy = 1; + dev->force_busy = 1; + dev->force_busy2 = 1; + } + + if (cpu_input) { + if (dev->bpp) { + if ((mach->accel.dp_config & 0x200) && (count == 2)) { + count >>= 1; + } + } + } + + if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { + if (cpu_input && (cmd_type == 2)) + mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + } + + switch (cmd_type) { + case 1: /*Extended Raw Linedraw from bres_count register (0x96ee)*/ + if (!cpu_input) { + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + dev->accel.cx = dev->accel.destx_distp; + if (dev->accel.destx_distp >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.desty_axstp; + if (dev->accel.desty_axstp >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.width = mach->accel.bres_count; + dev->accel.sx = 0; + mach->accel.poly_fill = 0; + + mach->accel.color_pattern_idx = ((dev->accel.cx + (dev->accel.cy << 3)) & mach->accel.patt_len); + + mach->accel.stepx = (mach->accel.linedraw_opt & 0x20) ? 1 : -1; + mach->accel.stepy = (mach->accel.linedraw_opt & 0x80) ? 1 : -1; + + mach_log("Extended bresenham, CUR(%d,%d), DEST(%d,%d), width = %d, options = %04x, dpconfig = %04x, opt_ena = %03x.\n", dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.linedraw_opt, mach->accel.dp_config, mach->accel.max_waitstates & 0x100); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (frgd_sel == 5) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + + /*The destination coordinates should match the pattern index.*/ + if (mach->accel.color_pattern_idx != mach->accel.patt_idx) + mach->accel.color_pattern_idx = mach->accel.patt_idx; + } + + if (mono_src == 1) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + if (mach->accel.linedraw_opt & 0x08) { /*Vector Line*/ + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); + } + mix = (mix & rd_mask) == rd_mask; + break; + + default: + break; + } + + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (((mono_src != 1) && (dev->accel.sx < mach->accel.width)) || ((mono_src == 1) && count)) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } + } + } + + if ((mono_src == 1) && !count) + break; + else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + switch (mach->accel.linedraw_opt & 0xe0) { + case 0x00: + dev->accel.cx++; + dev->accel.dx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.dx++; + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x40: + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.dx--; + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x80: + dev->accel.cx--; + dev->accel.dx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.dx--; + dev->accel.cy++; + dev->accel.dy++; + break; + case 0xc0: + dev->accel.cy++; + dev->accel.dy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.dx++; + dev->accel.cy++; + dev->accel.dy++; + break; + + default: + break; + } + + dev->accel.sx++; + } + } else { /*Bresenham*/ + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); + } + mix = (mix & rd_mask) == rd_mask; + break; + + default: + break; + } + + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (((mono_src != 1) && (dev->accel.sx < mach->accel.width)) || ((mono_src == 1) && count)) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); + } + } + } + } + } + + if ((mono_src == 1) && !count) + break; + else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (mach->accel.linedraw_opt & 0x40) { + dev->accel.dy += mach->accel.stepy; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cy += mach->accel.stepy; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.dx += mach->accel.stepx; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cx += mach->accel.stepx; + } else { + dev->accel.err_term += dev->accel.desty_axstp; + } + } else { + dev->accel.dx += mach->accel.stepx; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cx += mach->accel.stepx; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.dy += mach->accel.stepy; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cy += mach->accel.stepy; + } else { + dev->accel.err_term += dev->accel.desty_axstp; + } + } + + dev->accel.sx++; + } + } + mach->accel.poly_fill = 0; + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + break; + + case 2: /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + if (!cpu_input) { + mach->accel.stepx = 0; + mach->accel.stepy = 0; + + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + if (mach->accel.dp_config == 0x5211) { + if (mach->accel.dest_x_end == 1024) { + goto skip_dx; + } + } + /*Destination Width*/ + if (mach->accel.dest_x_start != dev->accel.dx) + mach->accel.dest_x_start = dev->accel.dx; + +skip_dx: + mach->accel.dx_start = mach->accel.dest_x_start; + if (mach->accel.dest_x_start >= 0x600) + mach->accel.dx_start |= ~0x5ff; + + mach->accel.dx_end = mach->accel.dest_x_end; + if (mach->accel.dest_x_end >= 0x600) + mach->accel.dx_end |= ~0x5ff; + + if (mach->accel.dx_end > mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_end - mach->accel.dx_start); + mach->accel.stepx = 1; + } else if (mach->accel.dx_end < mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end); + mach->accel.stepx = -1; + if (dev->accel.dx > 0) + dev->accel.dx--; + mach_log("BitBLT: Dst Negative X, dxstart = %d, end = %d, width = %d, dx = %d, dpconfig = %04x.\n", mach->accel.dest_x_start, mach->accel.dest_x_end, mach->accel.width, dev->accel.dx, mach->accel.dp_config); + } else { + mach->accel.stepx = 1; + mach->accel.width = 0; + mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n", mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start); + } + + dev->accel.sx = 0; + mach->accel.poly_fill = 0; + mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); + if ((dev->accel_bpp == 24) && (mono_src != 1)) { + if (mach->accel.color_pattern_idx == mach->accel.patt_len) + mach->accel.color_pattern_idx = mach->accel.patt_data_idx; + } else if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) + mach->accel.color_pattern_idx = 0; + + /*Height*/ + mach->accel.dy_start = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + mach->accel.dy_start |= ~0x5ff; + mach->accel.dy_end = mach->accel.dest_y_end; + if (mach->accel.dest_y_end >= 0x600) + mach->accel.dy_end |= ~0x5ff; + + if (mach->accel.dy_end > mach->accel.dy_start) { + mach->accel.height = (mach->accel.dy_end - mach->accel.dy_start); + mach->accel.stepy = 1; + } else if (mach->accel.dy_end < mach->accel.dy_start) { + mach->accel.height = (mach->accel.dy_start - mach->accel.dy_end); + mach->accel.stepy = -1; + } else { + mach->accel.height = 0; + mach->accel.stepy = 1; + } + + dev->accel.sy = 0; + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + + mach->accel.src_stepx = 0; + + /*Source Width*/ + dev->accel.cx = mach->accel.src_x; + if (mach->accel.src_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + dev->accel.cy = mach->accel.src_y; + if (mach->accel.src_y >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.sx_start = mach->accel.src_x_start; + if (mach->accel.src_x_start >= 0x600) + mach->accel.sx_start |= ~0x5ff; + + mach->accel.sx_end = mach->accel.src_x_end; + if (mach->accel.src_x_end >= 0x600) + mach->accel.sx_end |= ~0x5ff; + + if (mach->accel.sx_end > mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_end - mach->accel.sx_start); + mach->accel.src_stepx = 1; + mach_log("BitBLT: Src Positive X: wh(%d,%d), srcwidth = %d, coordinates: %d,%d px, start: %d, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_start, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + } else if (mach->accel.sx_end < mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_start - mach->accel.sx_end); + mach->accel.src_stepx = -1; + 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 & 1); + } else { + mach->accel.src_stepx = 1; + mach->accel.src_width = 0; + mach_log("BitBLT: Src Indeterminate 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 & 1); + } + mach->accel.sx = 0; + if (dev->bpp) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + + if ((dev->accel_bpp == 24) && (frgd_sel == 5)) + mach_log("BitBLT=%04x, WH(%d,%d), SRCWidth=%d, c(%d,%d), s(%d,%d).\n", mach->accel.dp_config, mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy); + else if (mach->accel.dp_config & 0x02) + mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), D(%d,%d), SRCWidth=%d, SRCXStep=%d, WH(%d,%d), clipt=%d, clipb=%d, geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, mach->accel.src_x, mach->accel.src_y, dev->accel.cur_x, dev->accel.cur_y, mach->accel.src_width, mach->accel.src_stepx, mach->accel.width, mach->accel.height, clip_t, clip_b, (mach->accel.ge_offset << 2)); + + if (mono_src == 1) { + if ((mach->accel.mono_pattern_enable) && !(mach->accel.patt_len_reg & 0x4000)) { + mono_dat0 = mach->accel.patt_data[0x10]; + mono_dat0 |= (mach->accel.patt_data[0x11] << 8); + mono_dat0 |= (mach->accel.patt_data[0x12] << 16); + mono_dat0 |= (mach->accel.patt_data[0x13] << 24); + mono_dat1 = mach->accel.patt_data[0x14]; + mono_dat1 |= (mach->accel.patt_data[0x15] << 8); + mono_dat1 |= (mach->accel.patt_data[0x16] << 16); + mono_dat1 |= (mach->accel.patt_data[0x17] << 24); + + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mono_dat1 : mono_dat0; + mach->accel.mono_pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } + } + } + } + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (mono_src == 1) { + if (!mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10] ^ ((mach->accel.patt_idx & 1) ? 0xff : 0); + dev->accel.temp_cnt = 8; + } + } + + if (frgd_sel == 5) { + if (dev->bpp) { + for (int x = 0; x <= mach->accel.patt_len; x += 2) { + mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] = (mach->accel.patt_data[x & mach->accel.patt_len] & 0xff); + mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] |= (mach->accel.patt_data[(x + 1) & mach->accel.patt_len] << 8); + } + } else { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x]; + mach_log("BITBLT: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } else { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } + } + + /*The destination coordinates should match the pattern index.*/ + if (mach->accel.color_pattern_idx != mach->accel.patt_idx) + mach->accel.color_pattern_idx = mach->accel.patt_idx; + } + + if (mach->accel.dy_end == mach->accel.dy_start) { + mach_log("No DEST.\n"); + return; + } + + if ((mono_src == 3) || (bkgd_sel == 3) || (frgd_sel == 3)) { + if (mach->accel.sx_end == mach->accel.sx_start) { + mach_log("No SRC.\n"); + return; + } + } + + if (cpu_input) { + if (mach->accel.dp_config == 0x3251) { + if (dev->accel.sy == mach->accel.height) + return; + } + } + + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (mach->accel.mono_pattern_enable) + mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; + else { + if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) + mix = 1; + else { + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + READ(dev->accel.src + dev->accel.cx, mix); + mix = (mix & rd_mask) == rd_mask; + break; + + default: + break; + } + + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + if ((mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) { + READ(dev->accel.src + dev->accel.cx, poly_src); + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill ^= 1; + } + + if (mach->accel.poly_fill || !(mach->accel.dp_config & 0x02) || !(mach->accel.linedraw_opt & 0x02)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + READ(dev->accel.src + dev->accel.cx, src_dat); + if (mono_src == 3) + src_dat = (src_dat & rd_mask) == rd_mask; + } + break; + case 5: + if (mix) { + if (dev->bpp) + src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; + else + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + } else + src_dat = 0; + break; + + default: + break; + } + + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + } else { + READ(dev->accel.dest + dev->accel.dx, dest_dat); + } + } else { + READ(dev->accel.dest + dev->accel.dx, dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + } + } + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02)) { + dev->accel.cx += mach->accel.src_stepx; + mach->accel.sx++; + if (mach->accel.sx >= mach->accel.src_width) { + mach->accel.sx = 0; + if (mach->accel.src_stepx == -1) + dev->accel.cx += mach->accel.src_width; + else + dev->accel.cx -= mach->accel.src_width; + + dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); + if (dev->bpp) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + } + } + + dev->accel.dx += mach->accel.stepx; + + if ((dev->accel_bpp == 8) || ((dev->accel_bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + + if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { + mach->accel.color_pattern_idx = mach->accel.patt_data_idx; + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { + if (mach->accel.patt_len == 2) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } else + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } + + if (dev->bpp) { + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + } + + dev->accel.sx++; + if ((dev->accel.sx >= mach->accel.width) || (dev->accel.dx >= 0x600)) { + dev->accel.sx = 0; + if (mach->accel.stepx == -1) + dev->accel.dx += mach->accel.width; + else + dev->accel.dx -= mach->accel.width; + + dev->accel.dy += mach->accel.stepy; + dev->accel.sy++; + + mach->accel.poly_fill = 0; + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + + if ((mono_src == 1) && (dev->accel_bpp == 24) && (frgd_sel == 5)) + mach->accel.color_pattern_idx = 0; + else + mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); + + if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) + mach->accel.color_pattern_idx = 0; + if ((mono_src == 1) && !mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + return; + } + if (dev->accel.sy >= mach->accel.height) { + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) + return; + if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) + return; + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + return; + } + } + } + break; + + case 3: /*Direct Linedraw (Polyline) from linedraw indexes (0xfeee)*/ + case 4: + if (!cpu_input) { + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + mach_log("Linedraw XOver = %d.\n", dev->accel.cur_x); + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + mach_log("Linedraw YOver = %d.\n", dev->accel.cur_y); + dev->accel.cy |= ~0x5ff; + } + + dev->accel.dx = ABS(mach->accel.cx_end_line - dev->accel.cx) << 1; + dev->accel.dy = ABS(mach->accel.cy_end_line - dev->accel.cy) << 1; + + mach->accel.stepx = (mach->accel.cx_end_line < dev->accel.cx) ? -1 : 1; + mach->accel.stepy = (mach->accel.cy_end_line < dev->accel.cy) ? -1 : 1; + + dev->accel.sx = 0; + + mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d), bounds: l=%d, r=%d, t=%d, b=%d.\n", dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line, mach->accel.bleft, mach->accel.bright, mach->accel.btop, mach->accel.bbottom); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (frgd_sel == 5) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } + + if (mono_src == 1) { + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + count = (dev->accel.dx > dev->accel.dy) ? (dev->accel.dx >> 1) : (dev->accel.dy >> 1); + mach->accel.width = count; + + if (dev->accel.dx > dev->accel.dy) { + mach->accel.err = (dev->accel.dy - dev->accel.dx) >> 1; + if (mono_src == 1) { + while (count--) { + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else + src_dat = 0; + break; + case 5: + if (mix) + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + else + src_dat = 0; + break; + + default: + break; + } + + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + if (mach->accel.linedraw_opt & 0x04) { + if (count) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (!count) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (mach->accel.err >= 0) { + dev->accel.cy += mach->accel.stepy; + mach->accel.err -= dev->accel.dx; + } + dev->accel.cx += mach->accel.stepx; + mach->accel.err += dev->accel.dy; + } + } else { + while (count--) { + switch (mono_src) { + case 0: + case 3: + mix = 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + + default: + break; + } + + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + mach->accel.clip_overrun = 0; + if (mach->accel.linedraw_opt & 0x02) { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + if (mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + MIX(mix, dest_dat, src_dat); + } + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (dev->accel.sx >= mach->accel.width) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (mach->accel.err >= 0) { + dev->accel.cy += mach->accel.stepy; + mach->accel.err -= dev->accel.dx; + } + dev->accel.cx += mach->accel.stepx; + mach->accel.err += dev->accel.dy; + + dev->accel.sx++; + } + } + } else { + mach->accel.err = (dev->accel.dx - dev->accel.dy) >> 1; + if (mono_src == 1) { + while (count--) { + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (count) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (!count) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (mach->accel.err >= 0) { + dev->accel.cx += mach->accel.stepx; + mach->accel.err -= dev->accel.dy; + } + dev->accel.cy += mach->accel.stepy; + mach->accel.err += dev->accel.dx; + } + } else { + while (count--) { + switch (mono_src) { + case 0: + case 3: + mix = 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + + default: + break; + } + + if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + mach->accel.clip_overrun = 0; + + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (dev->accel.sx >= mach->accel.width) + break; + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (mach->accel.err >= 0) { + dev->accel.cx += mach->accel.stepx; + mach->accel.err -= dev->accel.dy; + } + dev->accel.cy += mach->accel.stepy; + mach->accel.err += dev->accel.dx; + + dev->accel.sx++; + } + } + } + mach->accel.poly_fill = 0; + mach->accel.line_array[(cmd_type == 4) ? 4 : 0] = dev->accel.cx; + mach->accel.line_array[(cmd_type == 4) ? 5 : 1] = dev->accel.cy; + dev->accel.cur_x = mach->accel.line_array[(cmd_type == 4) ? 4 : 0]; + dev->accel.cur_y = mach->accel.line_array[(cmd_type == 4) ? 5 : 1]; + break; + + case 5: /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + if (!cpu_input) { + mach->accel.stepx = 0; + mach->accel.stepy = 0; + + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + /*Destination Width*/ + mach->accel.dx_start = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + mach->accel.dx_start |= ~0x5ff; + mach->accel.dx_end = mach->accel.scan_to_x; + if (mach->accel.scan_to_x >= 0x600) + mach->accel.dx_end |= ~0x5ff; + + if (mach->accel.dx_end > mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_end - mach->accel.dx_start); + mach->accel.stepx = 1; + } else if (mach->accel.dx_end < mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end); + mach->accel.stepx = -1; + if (dev->accel.dx > 0) + dev->accel.dx--; + } else { + mach->accel.stepx = 1; + mach->accel.width = 0; + } + + dev->accel.sx = 0; + if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 0x17)) + mach->accel.color_pattern_idx = 0; + + /*Step Y*/ + mach->accel.dy_start = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + mach->accel.dy_start |= ~0x5ff; + mach->accel.dy_end = mach->accel.dest_y_end; + if (mach->accel.dest_y_end >= 0x600) + mach->accel.dy_end |= ~0x5ff; + + if (mach->accel.dy_end > mach->accel.dy_start) { + mach->accel.stepy = 1; + } else if (mach->accel.dy_end < mach->accel.dy_start) { + mach->accel.stepy = -1; + } else { + mach->accel.stepy = 0; + } + + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + + mach->accel.src_stepx = 0; + + /*Source Width*/ + dev->accel.cx = mach->accel.src_x; + if (mach->accel.src_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = mach->accel.src_y; + if (mach->accel.src_y >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.sx_start = mach->accel.src_x_start; + if (mach->accel.src_x_start >= 0x600) + mach->accel.sx_start |= ~0x5ff; + + mach->accel.sx_end = mach->accel.src_x_end; + if (mach->accel.src_x_end >= 0x600) + mach->accel.sx_end |= ~0x5ff; + + if (mach->accel.sx_end > mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_end - mach->accel.sx_start); + mach->accel.src_stepx = 1; + } else if (mach->accel.sx_end < mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_start - mach->accel.sx_end); + mach->accel.src_stepx = -1; + if (dev->accel.cx > 0) + dev->accel.cx--; + } else { + mach->accel.src_stepx = 1; + mach->accel.src_width = 0; + } + + mach->accel.sx = 0; + if (dev->bpp) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + + if ((dev->accel_bpp == 24) && (frgd_sel == 5)) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 0; + dev->accel.x1 = dev->accel.dx + mach->accel.width; + if (dev->accel.x1 == dev->pitch) { + dev->accel.x2 = mach->accel.width & 1; + } else if ((dev->accel.x1 == mach->accel.width) && (dev->accel.dy & 1) && !dev->accel.y1 && dev->accel.x2) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 3; + dev->accel.x3 = 1; + } else + dev->accel.x3 = 0; + } else + mach_log("ScanToX=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 1)); + + dev->accel.y1 = 0; + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (mono_src == 1) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + if (frgd_sel == 5) { + if (dev->accel_bpp != 24) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } else { + if (mach->accel.patt_len == 0x17) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern_full[x] = mach->accel.patt_data[x]; + mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern_full[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } else { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x]; + mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } + } + } + + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + READ(dev->accel.src + (dev->accel.cx), mix); + mix = (mix & rd_mask) == rd_mask; + break; + + default: + break; + } + + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + READ(dev->accel.src + dev->accel.cx, src_dat); + if (mono_src == 3) + src_dat = (src_dat & rd_mask) == rd_mask; + } + break; + case 5: + if (mix) { + if (dev->accel_bpp == 24) { + if (mach->accel.patt_len == 0x17) + src_dat = mach->accel.color_pattern_full[mach->accel.color_pattern_idx]; + else + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + } else + src_dat = mach->accel.color_pattern[(dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + + default: + break; + } + + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = (dest_dat < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = (dest_dat == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = (dest_dat <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = (dest_dat > dest_cmp_clr) ? 0 : 1; + break; + + default: + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + WRITE(dev->accel.dest + (dev->accel.dx), dest_dat); + } + } + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + dev->accel.cx += mach->accel.src_stepx; + mach->accel.sx++; + if (mach->accel.sx >= mach->accel.src_width) { + mach->accel.sx = 0; + if (mach->accel.src_stepx == -1) { + dev->accel.cx += mach->accel.src_width; + } else + dev->accel.cx -= mach->accel.src_width; + dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); + if (dev->bpp) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + } + + dev->accel.dx += mach->accel.stepx; + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17)) { + mach->accel.color_pattern_idx++; + if (dev->accel.x3) { + if (mach->accel.color_pattern_idx == 9) + mach->accel.color_pattern_idx = 3; + } else { + if (mach->accel.color_pattern_idx == 6) + mach->accel.color_pattern_idx = 0; + } + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } else + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + + dev->accel.sx++; + if (dev->accel.sx >= mach->accel.width) { + dev->accel.sx = 0; + dev->accel.dy += mach->accel.stepy; + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + if (mach->accel.line_idx == 2) { + mach->accel.line_array[0] = dev->accel.dx; + mach->accel.line_array[4] = dev->accel.dx; + } + return; + } + } + break; + + default: + break; + } +} + +static void +mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val) +{ + int frgd_sel; + int bkgd_sel; + int mono_src; + + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + if ((mach->accel.dp_config & 4) && (mach->accel.cmd_type != 5)) { + val = (val >> 8) | (val << 8); + } + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + val = (val >> 8) | (val << 8); + mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + val = (val >> 8) | (val << 8); + mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); + break; + + default: + break; + } +} + +static void +mach_out(uint16_t addr, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t old; + uint8_t rs2; + uint8_t rs3; + + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x1ce: + mach->index = val; + break; + case 0x1cf: + old = mach->regs[mach->index]; + mach->regs[mach->index] = val; + mach_log("ATI VGA write reg=0x%02X, val=0x%02X\n", mach->index, val); + switch (mach->index) { + case 0xa3: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xa7: + if ((old ^ val) & 0x80) + svga_recalctimings(svga); + break; + case 0xad: + if ((dev->local & 0xff) >= 0x02) { + if ((old ^ val) & 0x0c) + svga_recalctimings(svga); + } + break; + case 0xb0: + if ((old ^ val) & 0x60) + svga_recalctimings(svga); + break; + case 0xae: + case 0xb2: + case 0xbe: + mach_log("ATI VGA write reg=0x%02X, val=0x%02X\n", mach->index, val); + if (mach->regs[0xbe] & 0x08) { /* Read/write bank mode */ + mach->bank_r = (((mach->regs[0xb2] & 1) << 3) | ((mach->regs[0xb2] & 0xe0) >> 5)); + mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); + if ((dev->local & 0xff) >= 0x02) { + mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2); + mach->bank_w |= ((mach->regs[0xae] & 3) << 4); + } + if (dev->on[0] || dev->on[1]) + mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); + } else { /* Single bank mode */ + mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); + if ((dev->local & 0xff) >= 0x02) { + mach->bank_w |= ((mach->regs[0xae] & 3) << 4); + } + mach->bank_r = mach->bank_w; + if (dev->on[0] || dev->on[1]) + mach_log("Single B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); + } + svga->read_bank = mach->bank_r << 16; + svga->write_bank = mach->bank_w << 16; + + if (mach->index == 0xbe) { + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + } + break; + case 0xbd: + if ((old ^ val) & 4) { + mach32_updatemapping(mach, svga); + } + break; + case 0xb3: + ati_eeprom_write(&mach->eeprom, val & 8, val & 2, val & 1); + break; + case 0xb6: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xb8: + if ((dev->local & 0xff) >= 0x02) { + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + } else { + if ((old ^ val) & 0xc0) + svga_recalctimings(svga); + } + break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); + break; + + default: + break; + } + break; + + case 0x2ea: + case 0x2eb: + case 0x2ec: + case 0x2ed: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + rs3 = !!(mach->accel.ext_ge_config & 0x2000); + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus && !mach->ramdac_type) + ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + else + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + } else + svga_out(addr, val, svga); + return; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + rs2 = !!(mach->regs[0xa0] & 0x20); + rs3 = !!(mach->regs[0xa0] & 0x40); + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus && !mach->ramdac_type) + ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + else + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + } else + svga_out(addr, val, svga); + return; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(mach->regs[0xb4] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(mach->regs[0xb4] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + + default: + break; + } + svga_out(addr, val, svga); +} + +static uint8_t +mach_in(uint16_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp = 0xff; + uint8_t rs2; + uint8_t rs3; + + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x1ce: + temp = mach->index; + break; + case 0x1cf: + switch (mach->index) { + case 0xa0: + temp = mach->regs[0xa0] | 0x10; + break; + case 0xa8: + temp = (svga->vc >> 8) & 3; + break; + case 0xa9: + temp = svga->vc & 0xff; + break; + case 0xb0: + temp = mach->regs[0xb0] | 0x80; + temp &= ~0x18; + if ((dev->local & 0xff) >= 0x02) { /*Mach32 VGA 1MB memory*/ + temp |= 0x08; + } else { /*ATI 28800 VGA 512kB memory*/ + temp |= 0x10; + } + break; + case 0xb7: + temp = mach->regs[0xb7] & ~8; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 8; + break; + + case 0xbd: + temp = mach->regs[0xbd] | 0x10; + break; + + default: + temp = mach->regs[mach->index]; + break; + } + break; + + case 0x2ea: + case 0x2eb: + case 0x2ec: + case 0x2ed: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + rs3 = !!(mach->accel.ext_ge_config & 0x2000); + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus && !mach->ramdac_type) + temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); + else + temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else + temp = svga_in(addr, svga); + break; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + rs2 = !!(mach->regs[0xa0] & 0x20); + rs3 = !!(mach->regs[0xa0] & 0x40); + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus && !mach->ramdac_type) + temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); + else + temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else + temp = svga_in(addr, svga); + break; + + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + + +#ifdef ATI_8514_ULTRA +static void +ati8514_out(uint16_t addr, uint8_t val, void *priv) +{ + mach_log("ADDON OUT addr=%03x, val=%02x.\n", addr, val); + svga_out(addr, val, priv); +} + +static uint8_t +ati8514_in(uint16_t addr, void *priv) +{ + uint8_t temp = 0xff; + + temp = svga_in(addr, priv); + + mach_log("ADDON IN addr=%03x, temp=%02x.\n", addr, temp); + return temp; +} + +void +ati8514_recalctimings(svga_t *svga) +{ + const mach_t *mach = (mach_t *) svga->ext8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); + if (dev->on[0] || dev->on[1]) { + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; + dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->dispend = dev->vdisp; + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + if (dev->accel.advfunc_cntl & 4) { + if (dev->h_disp != 800) { + dev->h_disp = 1024; + dev->dispend = 768; + } + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } + + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } + + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; + } else { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) { /*40 column*/ + svga->render = svga_render_text_40; + } else { + svga->render = svga_render_text_80; + } + } + } +} +#endif + +static void +mach_recalctimings(svga_t *svga) +{ + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int clock_sel; + + if (mach->regs[0xad] & 0x08) + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2]; + + clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); + + if ((dev->local & 0xff) >= 0x02) { + if (mach->regs[0xad] & 0x04) + svga->ma_latch |= 0x40000; + + if (mach->regs[0xad] & 0x08) + svga->ma_latch |= 0x80000; + } + + if (mach->regs[0xa3] & 0x10) + svga->ma_latch |= 0x10000; + + if (mach->regs[0xb0] & 0x40) + svga->ma_latch |= 0x20000; + + if ((mach->regs[0xb6] & 0x18) >= 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->dots_per_clock <<= 1; + svga->rowoffset <<= 1; + svga->gdcreg[5] &= ~0x40; + } + + if (mach->regs[0xb0] & 0x20) { + svga->gdcreg[5] |= 0x40; + if ((mach->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((dev->local & 0xff) < 0x02) { + if ((mach->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->dots_per_clock <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + } + + svga->render8514 = ibm8514_render_blank; + mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); + if (dev->on[0] || dev->on[1]) { + mach_log("8514/A ON.\n"); + dev->h_disp = dev->hdisp; + dev->h_total = dev->htotal + 1; + dev->h_blankstart = dev->hblankstart; + dev->h_blank_end_val = dev->hblank_end_val; + dev->v_total = dev->vtotal; + dev->v_syncstart = dev->vsyncstart; + dev->dispend = dev->vdisp; + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + if (dev->dispend == 478) + dev->dispend += 2; + + if ((dev->local & 0xff) >= 0x02) { + if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } + + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } + + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { + if ((mach->accel.ext_ge_config & 0x30) == 0x20) { + if ((mach->accel.ext_ge_config & 0xc0) == 0x40) + dev->accel_bpp = 16; + else + dev->accel_bpp = 15; + } else if ((mach->accel.ext_ge_config & 0x30) == 0x30) { + if (mach->accel.ext_ge_config & 0x200) + dev->accel_bpp = 32; + else + dev->accel_bpp = 24; + } else + dev->accel_bpp = 8; + + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d, shadow=%x, vgahdisp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp, mach->shadow_set & 3, svga->hdisp); + switch (dev->accel_bpp) { + case 8: + svga->render8514 = ibm8514_render_8bpp; + break; + case 15: + svga->render8514 = ibm8514_render_15bpp; + break; + case 16: + svga->render8514 = ibm8514_render_16bpp; + break; + case 24: + mach_log("GEConfig24bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); + if (mach->accel.ext_ge_config & 0x400) + svga->render8514 = ibm8514_render_BGR; + else + svga->render8514 = ibm8514_render_24bpp; + break; + case 32: + mach_log("GEConfig32bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); + if (mach->accel.ext_ge_config & 0x400) + svga->render8514 = ibm8514_render_ABGR8888; + else + svga->render8514 = ibm8514_render_32bpp; + break; + + default: + break; + } + } + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock8514 *= 2; + break; + case 0x80: + svga->clock8514 *= 3; + break; + case 0xc0: + svga->clock8514 *= 4; + break; + + default: + break; + } + } else { + if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + if ((mach->shadow_set ^ mach->compat_mode) & 0x03) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + + if (((mach->shadow_set & 0x03) != 0x02) || !(dev->accel.advfunc_cntl & 0x04)) { /*Shadow set of 2 and bit 2 of port 0x4ae8 mean 1024x768+*/ + if (!(mach->accel.clock_sel & 0x01)) { + dev->h_disp = 640; + dev->dispend = 480; + } + } + } + + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } + + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; + if (mach->regs[0xb8] & 0x40) + svga->clock8514 *= 2; + } + } + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { + mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + if (mach->regs[0xa7] & 0x80) + svga->clock *= 3; + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + mach_log("Lowres=%x, seqreg[1]bit3=%x.\n", svga->lowres, svga->seqregs[1] & 8); + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + } + break; + } + break; + + default: + break; + } + } + } +} + +static void +mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, uint16_t val, int len) +{ + int frgd_sel; + int bkgd_sel; + int mono_src; + + mach_log("[%04X:%08X]: Port FIFO OUT=%04x, val=%04x, len=%d.\n", CS, cpu_state.pc, port, val, len); + + switch (port) { + case 0x82e8: + case 0xc2e8: + case 0xf6ee: + if (len == 1) + dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; + else + dev->accel.cur_y = val & 0x7ff; + break; + case 0x82e9: + case 0xc2e9: + case 0xf6ef: + if (len == 1) + dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); + break; + + case 0x86e8: + case 0xc6e8: + if (len == 1) + dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; + else + dev->accel.cur_x = val & 0x7ff; + break; + case 0x86e9: + case 0xc6e9: + if (len == 1) { + dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); + } + break; + + case 0x8ae8: + case 0xcae8: + if (len == 1) + dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; + else { + mach->accel.src_y = val; + dev->accel.desty = val & 0x07ff; + dev->accel.desty_axstp = val & 0x3fff; + if (val & 0x2000) + dev->accel.desty_axstp |= ~0x1fff; + } + break; + case 0x8ae9: + case 0xcae9: + if (len == 1) { + dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.desty_axstp |= ~0x1fff; + } + break; + + case 0x8ee8: + case 0xcee8: + if (len == 1) + dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; + else { + mach->accel.src_x = val; + dev->accel.destx = val & 0x07ff; + dev->accel.destx_distp = val & 0x3fff; + if (val & 0x2000) + dev->accel.destx_distp |= ~0x1fff; + } + break; + case 0x8ee9: + case 0xcee9: + if (len == 1) { + dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.destx_distp |= ~0x1fff; + } + break; + + case 0x92e8: + if (len != 1) + dev->test = val; + fallthrough; + + case 0xd2e8: + if (len == 1) + dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; + else { + dev->accel.err_term = val & 0x3fff; + if (val & 0x2000) + dev->accel.err_term |= ~0x1fff; + } + break; + case 0x92e9: + case 0xd2e9: + if (len == 1) { + dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.err_term |= ~0x1fff; + } + break; + + case 0x96e8: + case 0xd6e8: + if (len == 1) + dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val; + else { + mach->accel.test = val & 0x1fff; + dev->accel.maj_axis_pcnt = val & 0x07ff; + dev->accel.maj_axis_pcnt_no_limit = val; + } + break; + case 0x96e9: + case 0xd6e9: + if (len == 1) { + dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); + } + break; + + case 0x9ae8: + case 0xdae8: + dev->accel.ssv_state = 0; + if (len == 1) + dev->accel.cmd = (dev->accel.cmd & 0xff00) | val; + else { + dev->data_available = 0; + dev->data_available2 = 0; + dev->accel.cmd = val; + mach_log("CMD8514=%04x, len=%d, pixcntl=%02x.\n", val, len, dev->accel.multifunc[0x0a]); + mach->accel.cmd_type = -1; + if (port == 0xdae8) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } + ibm8514_accel_start(-1, 0, -1, 0, svga, len); + } + break; + case 0x9ae9: + case 0xdae9: + if (len == 1) { + dev->data_available = 0; + dev->data_available2 = 0; + dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); + mach->accel.cmd_type = -1; + if (port == 0xdae9) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } + ibm8514_accel_start(-1, 0, -1, 0, svga, len); + } + break; + + case 0x9ee8: + case 0xdee8: + dev->accel.ssv_state = 1; + if (len == 1) + dev->accel.short_stroke = (dev->accel.short_stroke & 0xff00) | val; + else { + dev->accel.short_stroke = val; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + dev->accel.cy |= ~0x5ff; + } + + if (dev->accel.cmd & 0x1000) { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + } else { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + } + } + break; + case 0x9ee9: + case 0xdee9: + if (len == 1) { + dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + dev->accel.cy |= ~0x5ff; + } + + if (dev->accel.cmd & 0x1000) { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + } else { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + } + } + break; + + case 0xa2e8: + case 0xe2e8: + if (port == 0xe2e8) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; + else + dev->accel.bkgd_color = val; + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; + } + } else { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach_accel_out_pixtrans(mach, dev, val); + } else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } + } + } + } else { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; + else + dev->accel.bkgd_color = val; + } + break; + case 0xa2e9: + case 0xe2e9: + if (port == 0xe2e9) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + + default: + break; + } + } + } + } + } else { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); + } + break; + + case 0xa6e8: + case 0xe6e8: + if (port == 0xe6e8) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; + else + dev->accel.frgd_color = val; + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; + } + } else { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach_accel_out_pixtrans(mach, dev, val); + } else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } + } + } + } else { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; + else + dev->accel.frgd_color = val; + } + break; + case 0xa6e9: + case 0xe6e9: + if (port == 0xe6e9) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + + default: + break; + } + } + } + } + } else { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); + } + break; + + case 0xaae8: + case 0xeae8: + if (len == 1) + dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; + else { + dev->accel.wrt_mask = val; + mach_log("WrtMask=%04x.\n", val); + } + break; + case 0xaae9: + case 0xeae9: + if (len == 1) + dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8); + break; + + case 0xaee8: + case 0xeee8: + if (len == 1) + dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; + else { + dev->accel.rd_mask = val; + mach_log("ReadMask=%04x.\n", val); + } + break; + case 0xaee9: + case 0xeee9: + if (len == 1) + dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8); + break; + + case 0xb2e8: + case 0xf2e8: + if (len == 1) + dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val; + else + dev->accel.color_cmp = val; + break; + case 0xb2e9: + case 0xf2e9: + if (len == 1) + dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8); + break; + + case 0xb6e8: + case 0xf6e8: + dev->accel.bkgd_mix = val & 0xff; + break; + + case 0xbae8: + case 0xfae8: + dev->accel.frgd_mix = val & 0xff; + break; + + case 0xbee8: + case 0xfee8: + if (len == 1) + dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff00) | val; + else { + dev->accel.multifunc_cntl = val; + dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) + dev->accel.clip_top = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 3) + dev->accel.multifunc[3] = val & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 4) + dev->accel.multifunc[4] = val & 0x7ff; + + mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); + if ((dev->accel.multifunc_cntl >> 12) == 5) { + if ((dev->local & 0xff) < 0x02) + dev->ext_crt_pitch = 128; + } + if (port == 0xfee8) + dev->accel.cmd_back = 1; + else + dev->accel.cmd_back = 0; + } + break; + case 0xbee9: + case 0xfee9: + if (len == 1) { + dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); + dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) + dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 2) + dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; + + if ((dev->accel.multifunc_cntl >> 12) == 5) { + if ((dev->local & 0xff) < 0x02) + dev->ext_crt_pitch = 128; + } + if (port == 0xfee9) + dev->accel.cmd_back = 1; + else + dev->accel.cmd_back = 0; + } + break; + + /*ATI Mach8/32 specific registers*/ + case 0x82ee: + mach->accel.patt_data_idx = val & 0x1f; + mach_log("Pattern Data Index = %d.\n", val & 0x1f); + break; + + case 0x8eee: + if (len == 1) { + mach->accel.patt_data[mach->accel.patt_data_idx] = val; + } else { + mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff; + mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; + if (mach->accel.mono_pattern_enable) + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 0x17; + else { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + mono_src = (mach->accel.dp_config >> 5) & 3; + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + mach->accel.patt_data_idx += 2; + dev->accel.y1 = 1; + } else { + if (dev->accel_bpp == 24) + mach->accel.patt_data_idx += 2; + else + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; + } + mach_log("ExtCONFIG = %04x, Pattern Mono = %04x, selidx = %d, dataidx = %d, bit 0 = %02x len = %d.\n", mach->accel.ext_ge_config, val, mach->accel.patt_idx, mach->accel.patt_data_idx, val & 1, mach->accel.patt_len); + } + } + break; + case 0x8eef: + if (len == 1) { + mach->accel.patt_data[mach->accel.patt_data_idx + 1] = val; + if (mach->accel.mono_pattern_enable) + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 7; + else { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + mach->accel.patt_data_idx += 2; + dev->accel.y1 = 1; + } else + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; + } + } + break; + + case 0x96ee: + if (len == 1) + mach->accel.bres_count = (mach->accel.bres_count & 0x700) | val; + else { + mach->accel.bres_count = val & 0x7ff; + mach_log("BresenhamDraw = %04x.\n", mach->accel.dp_config); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 1; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + case 0x96ef: + if (len == 1) { + mach->accel.bres_count = (mach->accel.bres_count & 0xff) | ((val & 0x07) << 8); + mach_log("96EE (2) line draw.\n"); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 1; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + + case 0x9aee: + mach->accel.line_idx = val & 0x07; + break; + + case 0xa2ee: + mach_log("Line OPT = %04x\n", val); + if (len == 1) + mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0xff00) | val; + else { + mach->accel.linedraw_opt = val; + mach->accel.bbottom = dev->accel.multifunc[3] & 0x7ff; + mach->accel.btop = dev->accel.clip_top & 0x7ff; + mach->accel.bleft = dev->accel.clip_left & 0x7ff; + mach->accel.bright = dev->accel.multifunc[4] & 0x7ff; + if (mach->accel.linedraw_opt & 0x100) { + mach->accel.bbottom = 2047; + mach->accel.btop = 0; + mach->accel.bleft = 0; + mach->accel.bright = 2047; + } + } + break; + case 0xa2ef: + if (len == 1) { + mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8); + } + break; + + case 0xa6ee: + if (len == 1) + mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x700) | val; + else + mach->accel.dest_x_start = val & 0x7ff; + break; + case 0xa6ef: + if (len == 1) + mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xaaee: + if (len == 1) + mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val; + else { + mach->accel.dest_x_end = val & 0x7ff; + } + break; + case 0xaaef: + if (len == 1) + mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xaeee: + if (len == 1) + mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x700) | val; + else { + mach->accel.dest_y_end = val & 0x7ff; + if ((val + 1) == 0x10000) { + mach_log("Dest_Y_end overflow val = %04x\n", val); + mach->accel.dest_y_end = 0; + } + dev->data_available = 0; + dev->data_available2 = 0; + mach_log("BitBLT = %04x.\n", mach->accel.dp_config); + mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + case 0xaeef: + if (len == 1) { + mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x0ff) | ((val & 0x07) << 8); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + + case 0xb2ee: + if (len == 1) + mach->accel.src_x_start = (mach->accel.src_x_start & 0x700) | val; + else + mach->accel.src_x_start = val & 0x7ff; + break; + case 0xb2ef: + if (len == 1) + mach->accel.src_x_start = (mach->accel.src_x_start & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xb6ee: + dev->accel.bkgd_mix = val & 0xff; + break; + + case 0xbaee: + dev->accel.frgd_mix = val & 0xff; + break; + + case 0xbeee: + if (len == 1) + mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val; + else { + mach->accel.src_x_end = val & 0x7ff; + } + break; + case 0xbeef: + if (len == 1) + mach->accel.src_x_end = (mach->accel.src_x_end & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xc2ee: + mach->accel.src_y_dir = val & 1; + break; + + case 0xc6ee: + mach->accel.cmd_type = 0; + mach_log("TODO: Short Stroke.\n"); + break; + + case 0xcaee: + if (len == 1) + mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x700) | val; + else { + mach->accel.scan_to_x = (val & 0x7ff); + if ((val + 1) == 0x10000) { + mach_log("Scan_to_X overflow val = %04x\n", val); + mach->accel.scan_to_x = 0; + } + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + mach_log("ScanToX = %04x.\n", mach->accel.dp_config); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + case 0xcaef: + if (len == 1) { + mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x0ff) | ((val & 0x07) << 8); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + } + break; + + case 0xceee: + mach_log("CEEE write val = %04x.\n", val); + if (len == 1) + mach->accel.dp_config = (mach->accel.dp_config & 0xff00) | val; + else { + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.dp_config = val; + } + break; + case 0xceef: + if (len == 1) { + mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8); + } + break; + + case 0xd2ee: + mach->accel.patt_len = val & 0x1f; + mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val); + mach->accel.mono_pattern_enable = !!(val & 0x80); + if (len != 1) { + mach->accel.patt_len_reg = val; + } else { + mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val; + } + break; + case 0xd2ef: + if (len == 1) + mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0x00ff) | (val << 8); + break; + + case 0xd6ee: + mach->accel.patt_idx = val & 0x1f; + mach_log("Pattern Index = %d, val = %02x.\n", val & 0x1f, val); + break; + + case 0xdaee: + mach_log("DAEE (extclipl) write val = %d\n", val); + if (len == 1) + dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val; + else { + dev->accel.clip_left = val & 0x7ff; + } + break; + case 0xdaef: + if (len == 1) + dev->accel.clip_left = (dev->accel.clip_left & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xdeee: + mach_log("DEEE (extclipt) write val = %d\n", val); + if (len == 1) + dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val; + else { + dev->accel.clip_top = val & 0x7ff; + } + break; + case 0xdeef: + if (len == 1) + dev->accel.clip_top = (dev->accel.clip_top & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xe2ee: + mach_log("E2EE (extclipr) write val = %d\n", val); + if (len == 1) + dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val; + else { + dev->accel.multifunc[4] = val & 0x7ff; + } + break; + case 0xe2ef: + if (len == 1) + dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xe6ee: + mach_log("E6EE (extclipb) write val = %d\n", val); + if (len == 1) + dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val; + else { + dev->accel.multifunc[3] = val & 0x7ff; + } + break; + case 0xe6ef: + if (len == 1) + dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xeeee: + if (len == 1) + mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0xff00) | val; + else + mach->accel.dest_cmp_fn = val; + break; + case 0xeeef: + if (len == 1) + mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0x00ff) | (val << 8); + break; + + case 0xf2ee: + mach_log("F2EE.\n"); + if (len == 1) + mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0xff00) | val; + else + mach->accel.dst_clr_cmp_mask = val; + break; + case 0xf2ef: + if (len == 1) + mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0x00ff) | (val << 8); + break; + + case 0xfeee: + mach_log("LineDraw = %04x.\n", mach->accel.dp_config); + if (len != 1) { + mach->accel.line_array[mach->accel.line_idx] = val; + dev->accel.cur_x = mach->accel.line_array[(mach->accel.line_idx == 4) ? 4 : 0]; + dev->accel.cur_y = mach->accel.line_array[(mach->accel.line_idx == 5) ? 5 : 1]; + mach->accel.cx_end_line = mach->accel.line_array[2]; + mach->accel.cy_end_line = mach->accel.line_array[3]; + if ((mach->accel.line_idx == 3) || (mach->accel.line_idx == 5)) { + mach->accel.cmd_type = (mach->accel.line_idx == 5) ? 4 : 3; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + mach->accel.line_idx = (mach->accel.line_idx == 5) ? 4 : 2; + break; + } + mach->accel.line_idx++; + } + break; + + default: + break; + } +} + +static void +mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev) +{ + uint8_t old = 0; + + if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9) + mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); + + switch (port) { + case 0x2e8: + case 0x2e9: + WRITE8(port, dev->htotal, val); + break; + + case 0x6e8: + case 0x6e9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; + } + } + mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc=%x, dispcntl=%02x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 4, dev->disp_cntl & 0x60); + break; + + case 0xae8: + case 0xae9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_start = val; + dev->hblankstart = (dev->hsync_start & 0x07); + } + } + mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + break; + + case 0xee8: + case 0xee9: + if (!(port & 1)) { + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + dev->hsync_width = val; + dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; + } + } + mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + break; + + case 0x12e8: + case 0x12e9: + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->vtotal = dev->v_total_reg; + dev->vtotal++; + } + break; + + case 0x16e8: + case 0x16e9: + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = dev->v_disp; + dev->vdisp >>= 1; + dev->vdisp++; + } + dev->modechange = dev->accel.advfunc_cntl & 0x04; + mach->compat_mode = mach->shadow_set & 0x03; + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + break; + + case 0x1ae8: + case 0x1ae9: + if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04)) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->vsyncstart = dev->v_sync_start; + dev->vsyncstart++; + } + break; + + case 0x1ee8: + case 0x1ee9: + mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + break; + + case 0x22e8: + dev->disp_cntl = val; + dev->interlace = !!(val & 0x10); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); + break; + + case 0x42e8: + old = dev->subsys_stat; + if (val & 1) + dev->subsys_stat &= ~1; + if (val & 2) + dev->subsys_stat &= ~2; + if (val & 4) + dev->subsys_stat &= ~4; + if (val & 8) + dev->subsys_stat &= ~8; + break; + case 0x42e9: + old = dev->subsys_cntl; + dev->subsys_cntl = val; + if ((old ^ val) & 1) + dev->subsys_stat |= 1; + if ((old ^ val) & 2) + dev->subsys_stat |= 2; + if ((old ^ val) & 4) + dev->subsys_stat |= 4; + if ((old ^ val) & 8) + dev->subsys_stat |= 8; + break; + + case 0x4ae8: + case 0x4ae9: + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; + if ((dev->local & 0xff) < 0x02) + dev->ext_crt_pitch = 128; + + vga_on = !dev->on[port & 1]; + mach->ext_on[port & 1] = dev->on[port & 1]; + mach32_updatemapping(mach, svga); + dev->vendor_mode[port & 1] = 0; + mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); + svga_recalctimings(svga); + break; + + /*ATI Mach8/32 specific registers*/ + case 0x2ee: + mach_log("2EE write val = %02x.\n", val); + break; + case 0x2ef: + mach_log("2EF write val = %02x.\n", val); + break; + + case 0x6ee: + mach_log("6EE write val = %02x.\n", val); + break; + case 0x6ef: + mach_log("6EF write val = %02x.\n", val); + break; + + case 0xaee: + case 0xaef: + WRITE8(port, mach->cursor_offset_lo_reg, val); + mach->cursor_offset_lo = mach->cursor_offset_lo_reg; + break; + + case 0xeee: + case 0xeef: + WRITE8(port, mach->cursor_offset_hi_reg, val); + mach->cursor_offset_hi = mach->cursor_offset_hi_reg & 0x0f; + dev->hwcursor.addr = (mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2; + dev->hwcursor.ena = !!(mach->cursor_offset_hi_reg & 0x8000); + break; + + case 0x12ee: + case 0x12ef: + WRITE8(port, mach->cursor_x, val); + dev->hwcursor.x = mach->cursor_x & 0x7ff; + break; + + case 0x16ee: + case 0x16ef: + WRITE8(port, mach->cursor_y, val); + dev->hwcursor.y = mach->cursor_y & 0xfff; + break; + + case 0x1aee: + case 0x1aef: + WRITE8(port, mach->cursor_col_b, val); + mach->cursor_col_0 = mach->cursor_col_b & 0xff; + mach->cursor_col_1 = (mach->cursor_col_b >> 8) & 0xff; + break; + + case 0x1eee: + case 0x1eef: + WRITE8(port, mach->cursor_vh_offset, val); + dev->hwcursor.xoff = mach->cursor_vh_offset & 0x3f; + dev->hwcursor.yoff = (mach->cursor_vh_offset >> 8) & 0x3f; + break; + + case 0x22ee: + if (mach->pci_bus) { + mach->pci_cntl_reg = val; + mach32_updatemapping(mach, svga); + } + break; + + case 0x26ee: + case 0x26ef: + WRITE8(port, mach->accel.crt_pitch, val); + dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff; + if (dev->accel_bpp > 8) { + if (dev->accel_bpp == 24) + dev->ext_crt_pitch *= 3; + else if (dev->accel_bpp == 32) + dev->ext_crt_pitch <<= 2; + else + dev->ext_crt_pitch <<= 1; + } + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + svga_recalctimings(svga); + break; + + case 0x32ee: + case 0x32ef: + WRITE8(port, mach->local_cntl, val); + mach32_updatemapping(mach, svga); + break; + + case 0x36ee: + case 0x36ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->misc, val); + mach->misc &= 0xfff0; + break; + + case 0x3aee: + case 0x3aef: + WRITE8(port, mach->cursor_col_0_rg, val); + mach->ext_cur_col_0_g = mach->cursor_col_0_rg & 0xff; + mach->ext_cur_col_0_r = (mach->cursor_col_0_rg >> 8) & 0xff; + break; + + case 0x3eee: + case 0x3eef: + WRITE8(port, mach->cursor_col_1_rg, val); + mach->ext_cur_col_1_g = mach->cursor_col_1_rg & 0xff; + mach->ext_cur_col_1_r = (mach->cursor_col_1_rg >> 8) & 0xff; + break; + + case 0x42ee: + case 0x42ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->accel.test2, val); + break; + + case 0x46ee: + case 0x46ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->shadow_cntl, val); + break; + + case 0x4aee: + case 0x4aef: + WRITE8(port, mach->accel.clock_sel, val); + dev->on[port & 1] = mach->accel.clock_sel & 0x01; + mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]); + mach->ext_on[port & 1] = dev->on[port & 1]; + vga_on = !dev->on[port & 1]; + dev->vendor_mode[port & 1] = 1; + svga_recalctimings(svga); + break; + + case 0x52ee: + case 0x52ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->accel.scratch0, val); + break; + + case 0x56ee: + case 0x56ef: + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + WRITE8(port, mach->accel.scratch1, val); + break; + + case 0x5aee: + case 0x5aef: + if (!(mach->shadow_cntl & 0x3f)) { + WRITE8(port, mach->shadow_set, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + } + break; + + case 0x5eee: + case 0x5eef: + WRITE8(port, mach->memory_aperture, val); + mach_log("Memory Aperture = %04x.\n", mach->memory_aperture); + if (!mach->pci_bus) + mach->linear_base = (mach->memory_aperture & 0xff00) << 12; + + mach32_updatemapping(mach, svga); + break; + + case 0x62ee: + mach_log("62EE write val = %04x, len = %d.\n", val, len); + break; + + case 0x66ee: + mach_log("66EE write val = %04x, len = %d.\n", val, len); + break; + + case 0x6aee: + case 0x6aef: + WRITE8(port, mach->accel.max_waitstates, val); + break; + + case 0x6eee: + case 0x6eef: + WRITE8(port, mach->accel.ge_offset_lo, val); + dev->accel.ge_offset = mach->accel.ge_offset_lo; + break; + + case 0x72ee: + case 0x72ef: + WRITE8(port, mach->accel.ge_offset_hi, val); + dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + break; + + case 0x76ee: + case 0x76ef: + WRITE8(port, mach->accel.ge_pitch, val); + dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach_log("ATI 8514/A: (0x%04x) val = %04x, extpitch = %d.\n", port, val, dev->ext_pitch); + svga_recalctimings(svga); + break; + + case 0x7aee: + case 0x7aef: + WRITE8(port, mach->accel.ext_ge_config, val); + if ((dev->local & 0xff) >= 0x02) { + if (mach->accel.crt_pitch & 0xff) + dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff; + switch (mach->accel.ext_ge_config & 0x30) { + case 0: + case 0x10: + dev->bpp = 0; + break; + case 0x20: + dev->bpp = 1; + dev->ext_crt_pitch <<= 1; + break; + case 0x30: + dev->bpp = 0; + if (mach->accel.ext_ge_config & 0x200) + dev->ext_crt_pitch <<= 2; + else + dev->ext_crt_pitch *= 3; + break; + + default: + break; + } + svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); + dev->vendor_mode[port & 1] = 1; + mach32_updatemapping(mach, svga); + mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); + svga_recalctimings(svga); + } else { + if (mach->accel.ext_ge_config & 0x8080) + ati_eeprom_write(&mach->eeprom, mach->accel.ext_ge_config & 0x4040, mach->accel.ext_ge_config & 0x2020, mach->accel.ext_ge_config & 0x1010); + } + break; + + case 0x7eee: + case 0x7eef: + WRITE8(port, mach->accel.eeprom_control, val); + ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 8, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + break; + + default: + break; + } +} + +static void +mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) +{ + svga_t *svga = &mach->svga; + + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + + mach_accel_out_call(port, val, mach, svga, (ibm8514_t *) svga->dev8514); +} + +static uint16_t +mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, int len) +{ + const uint16_t *vram_w = (uint16_t *) dev->vram; + uint16_t temp = 0; + int cmd; + int frgd_sel; + int bkgd_sel; + int mono_src; + + switch (port) { + case 0x82e8: + case 0xc2e8: + if (len != 1) + temp = dev->accel.cur_y; + break; + + case 0x86e8: + case 0xc6e8: + if (len != 1) + temp = dev->accel.cur_x; + break; + + case 0x92e8: + if (len != 1) + temp = dev->test; + break; + + case 0x96e8: + if (len != 1) + temp = dev->accel.maj_axis_pcnt; + break; + + case 0x9ae8: + case 0xdae8: + if (len != 1) { + if (dev->force_busy) + temp |= 0x200; /*Hardware busy*/ + dev->force_busy = 0; + if (dev->data_available) { + temp |= 0x100; /*Read Data available*/ + if (mach->accel.cmd_type >= 0) { + switch (mach->accel.cmd_type) { + case 2: + if (dev->accel.sy >= mach->accel.height) + dev->data_available = 0; + break; + case 5: + if (dev->accel.sx >= mach->accel.width) + dev->data_available = 0; + break; + default: + if (dev->accel.sy < 0) + dev->data_available = 0; + break; + } + } else { + if (dev->accel.sy < 0) + dev->data_available = 0; + } + } + } + mach_log("[%04X:%08X]: 9AE8: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + case 0x9ae9: + case 0xdae9: + if (len == 1) { + if (dev->force_busy2) + temp |= 2; /*Hardware busy*/ + dev->force_busy2 = 0; + if (dev->data_available2) { + temp |= 1; /*Read Data available*/ + if (mach->accel.cmd_type >= 0) { + switch (mach->accel.cmd_type) { + case 2: + if (dev->accel.sy >= mach->accel.height) + dev->data_available2 = 0; + break; + case 5: + if (dev->accel.sx >= mach->accel.width) + dev->data_available2 = 0; + break; + default: + if (dev->accel.sy < 0) + dev->data_available2 = 0; + break; + } + } else { + if (dev->accel.sy < 0) + dev->data_available2 = 0; + } + } + } + mach_log("[%04X:%08X]: 9AE9: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + + case 0xe2e8: + case 0xe6e8: + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) { + cmd = -1; + if (len == 1) { + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 1) + temp = mach->accel.pix_trans[1]; + } else { + if (mach->accel.cmd_type == 3) { + READ_PIXTRANS_WORD(dev->accel.cx, 0) + } else { + READ_PIXTRANS_WORD(dev->accel.dx, 0) + } + mach_accel_out_pixtrans(mach, dev, temp); + } + } + } else { + if (ibm8514_cpu_dest(svga)) { + cmd = (dev->accel.cmd >> 13); + if (len != 1) { + READ_PIXTRANS_WORD(dev->accel.cx, 0) + if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { + temp &= ~0xff00; + temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); + } + if (dev->subsys_stat & 1) { + dev->force_busy = 1; + dev->data_available = 1; + } + } + ibm8514_accel_out_pixtrans(svga, port, temp, len); + } + } + break; + case 0xe2e9: + case 0xe6e9: + if (mach->accel.cmd_type >= 0) { + mach_log("%04x pixtrans read, len=%d.\n", port, len); + if (mach_pixel_read(mach)) { + if (len == 1) { + cmd = -1; + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0) + + temp = mach->accel.pix_trans[0]; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + break; + + default: + break; + } + } + } + } + break; + + case 0xbee8: + case 0xfee8: + if (len != 1) { + mach_log("Multifunc_cntl = %d.\n", dev->accel.multifunc_cntl >> 12); + switch ((dev->accel.multifunc_cntl >> 12) & 0x0f) { + case 0: + temp = dev->accel.multifunc[0]; + break; + case 1: + temp = dev->accel.clip_top; + break; + case 2: + temp = dev->accel.clip_left; + break; + case 3: + temp = dev->accel.multifunc[3]; + break; + case 4: + temp = dev->accel.multifunc[4]; + break; + case 5: + temp = dev->accel.multifunc[5]; + break; + case 8: + temp = dev->accel.multifunc[8]; + break; + case 9: + temp = dev->accel.multifunc[9]; + break; + case 0x0a: + temp = dev->accel.multifunc[0x0a]; + break; + + default: + break; + } + } + break; + + case 0x82ee: + temp = mach->accel.patt_data_idx; + break; + + case 0x86ee: + case 0x86ef: + temp = 0x0000; + break; + + case 0x8eee: + if (len == 1) + temp = mach->accel.ext_ge_config & 0xff; + else + temp = mach->accel.ext_ge_config; + + mach_log("ExtGE Read = %04x, len=%d.\n", temp, len); + break; + case 0x8eef: + if (len == 1) + temp = mach->accel.ext_ge_config >> 8; + break; + + case 0x92ee: + if (len == 1) + temp = mach->accel.eeprom_control & 0xff; + else + temp = mach->accel.eeprom_control; + + mach_log("EEPROM cntl read=%04x, len=%d.\n", temp, len); + break; + case 0x92ef: + if (len == 1) + temp = mach->accel.eeprom_control >> 8; + + mach_log("EEPROM cntl read+1=%02x, len=%d.\n", temp, len); + break; + + case 0x96ee: + if (len == 1) + temp = dev->accel.maj_axis_pcnt & 0xff; + else { + temp = dev->accel.maj_axis_pcnt; + if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa)) + temp = mach->accel.test; + } + break; + case 0x96ef: + if (len == 1) + temp = dev->accel.maj_axis_pcnt >> 8; + break; + + case 0xa2ee: + if (len == 1) + temp = mach->accel.linedraw_opt & 0xff; + else + temp = mach->accel.linedraw_opt; + break; + case 0xa2ef: + if (len == 1) + temp = mach->accel.linedraw_opt >> 8; + break; + + case 0xb2ee: + if (len == 1) + temp = dev->hdisped; + else { + temp = dev->hdisped & 0xff; + temp |= (dev->htotal << 8); + } + break; + case 0xb2ef: + if (len == 1) + temp = dev->htotal; + break; + + case 0xb6ee: + temp = dev->hsync_start; + break; + + case 0xbaee: + temp = dev->hsync_width; + break; + + case 0xc2ee: + if (len == 1) + temp = dev->vtotal & 0xff; + else { + temp = dev->vtotal; + mach_log("VTOTAL read=%d.\n", temp); + } + break; + case 0xc2ef: + if (len == 1) + temp = dev->vtotal >> 8; + break; + + case 0xc6ee: + if (len == 1) + temp = dev->v_disp & 0xff; + else { + temp = dev->v_disp; + mach_log("VDISP read=%d.\n", temp); + } + break; + case 0xc6ef: + if (len == 1) + temp = dev->v_disp >> 8; + break; + + case 0xcaee: + if (len == 1) + temp = dev->v_sync_start & 0xff; + else + temp = dev->v_sync_start; + break; + case 0xcaef: + if (len == 1) + temp = dev->v_sync_start >> 8; + break; + + case 0xceee: + if (len == 1) + temp = dev->vc & 0xff; + else + temp = dev->vc & 0x7ff; + break; + case 0xceef: + if (len == 1) + temp = (dev->vc >> 8) & 7; + break; + + case 0xdaee: + if (len != 1) { + temp = mach->accel.src_x; + if ((dev->local & 0xff) >= 0x02) + temp &= 0x7ff; + } else + temp = mach->accel.src_x & 0xff; + break; + case 0xdaef: + if (len == 1) + temp = mach->accel.src_x >> 8; + break; + + case 0xdeee: + if (len != 1) { + temp = mach->accel.src_y; + if ((dev->local & 0xff) >= 0x02) + temp &= 0x7ff; + } else + temp = mach->accel.src_y & 0xff; + break; + case 0xdeef: + if (len == 1) + temp = mach->accel.src_y >> 8; + break; + + case 0xfaee: + if (len != 1) { + if (mach->pci_bus) + temp = 0x0017; + else + temp = 0x22f7; + } else { + if (mach->pci_bus) + temp = 0x17; + else + temp = 0xf7; + } + break; + case 0xfaef: + if (len == 1) { + if (mach->pci_bus) + temp = 0x00; + else + temp = 0x22; + } + break; + + default: + break; + } + + mach_log("[%04X:%08X]: Port FIFO IN=%04x, temp=%04x, len=%d.\n", CS, cpu_state.pc, port, temp, len); + + return temp; +} + +static uint8_t +mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) +{ + uint8_t temp = 0; + uint16_t vpos = 0; + uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; + + switch (port) { + case 0x2e8: + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) + temp |= 2; + } else { + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) + temp |= 2; + } + break; + + case 0x6e8: + temp = dev->hdisped; + break; + + case 0x22e8: + temp = dev->disp_cntl; + break; + + case 0x26e8: + case 0x26e9: + READ8(port, dev->htotal); + break; + + case 0x2ee8: + temp = dev->subsys_cntl; + break; + case 0x2ee9: + temp = 0xff; + break; + + case 0x42e8: + case 0x42e9: + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) + dev->subsys_stat |= 1; + } else { + if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) + dev->subsys_stat |= 1; + } + + if (port & 1) + temp = 0x80; + else { + temp = dev->subsys_stat | 0x80; + if (mach->accel.ext_ge_config & 0x08) + temp |= ((mach->accel.ext_ge_config & 0x07) << 4); + else + temp |= 0x20; + } + mach_log("Subsystem Status=%04x, 4ae8 shadow set=%02x.\n", temp, dev->accel.advfunc_cntl & 4); + break; + + /*ATI Mach8/32 specific registers*/ + case 0x12ee: + case 0x12ef: + READ8(port, mach->config1); + break; + + case 0x16ee: + case 0x16ef: + READ8(port, mach->config2); + break; + + case 0x22ee: + if (mach->pci_bus) + temp = mach->pci_cntl_reg; + break; + + case 0x32ee: + case 0x32ef: + READ8(port, mach->local_cntl); + break; + + case 0x36ee: + case 0x36ef: + READ8(port, mach->misc); + + if (!(port & 1)) { + temp &= ~0x0c; + switch (mach->memory) { + case 1024: + temp |= 0x04; + break; + case 2048: + temp |= 0x08; + break; + case 4096: + temp |= 0x0c; + break; + + default: + if ((dev->local & 0xff) < 0x02) + temp |= 0x04; + break; + } + } + break; + + case 0x42ee: + case 0x42ef: + READ8(port, mach->accel.test2); + break; + + case 0x46ee: + case 0x46ef: + READ8(port, mach->shadow_cntl); + break; + + case 0x4aee: + case 0x4aef: + READ8(port, mach->accel.clock_sel); + break; + + case 0x52ee: + case 0x52ef: + READ8(port, mach->accel.scratch0); +#ifdef ATI_8514_ULTRA + if (mach->mca_bus) { + if (!(port & 1)) { + if (svga->ext8514 != NULL) + temp = dev->pos_regs[4]; + } else { + if (svga->ext8514 != NULL) + temp = dev->pos_regs[5]; + } + } else { + if (!(port & 1)) { + if (svga->ext8514 != NULL) { + temp = 0x20 | 0x80; + } + } + } +#endif + break; + + case 0x56ee: + case 0x56ef: + READ8(port, mach->accel.scratch1); + break; + + case 0x5eee: + case 0x5eef: + if (mach->pci_bus) + mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); + + READ8(port, mach->memory_aperture); + break; + + case 0x62ee: + temp = mach->accel.clip_overrun; + mach_log("ClipOverrun = %02x.\n", temp); + break; + case 0x62ef: + if (mach->force_busy) + temp |= 0x20; + + mach->force_busy = 0; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 0x40; + mach_log("Mach busy temp=%02x.\n", temp); + break; + + case 0x6aee: + case 0x6aef: + READ8(port, mach->accel.max_waitstates); + break; + + case 0x72ee: + case 0x72ef: + READ8(port, (mach->accel.bleft)); + break; + + case 0x76ee: + case 0x76ef: + READ8(port, (mach->accel.btop)); + break; + + case 0x7aee: + case 0x7aef: + READ8(port, (mach->accel.bright)); + break; + + case 0x7eee: + case 0x7eef: + READ8(port, (mach->accel.bbottom)); + break; + + default: + break; + } + if (port != 0x62ee && port != 0x62ef && port != 0x42e8 && port != 0x42e9) + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); + + return temp; +} + +#ifdef ATI_8514_ULTRA +static void +ati8514_accel_out(uint16_t port, uint8_t val, svga_t *svga) +{ + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + + mach_accel_out_call(port, val, (mach_t *)svga->ext8514, svga, (ibm8514_t *) svga->dev8514); +} + +static void +ati8514_accel_outb(uint16_t port, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 1); + else + ati8514_accel_out(port, val, svga); +} + +static void +ati8514_accel_outw(uint16_t port, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 2); + else { + ati8514_accel_out(port, val, svga); + ati8514_accel_out(port + 1, (val >> 8), svga); + } +} + +static void +ati8514_accel_outl(uint16_t port, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + + if (port & 0x8000) { + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val & 0xffff, 2); + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, val >> 16, 2); + } else { + ati8514_accel_out(port, val, svga); + ati8514_accel_out(port + 1, (val >> 8), svga); + ati8514_accel_out(port + 2, (val >> 16), svga); + ati8514_accel_out(port + 3, (val >> 24), svga); + } +} +#endif + +static void +mach_accel_outb(uint16_t port, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 1); + else + mach_accel_out(port, val, mach); +} + +static void +mach_accel_outw(uint16_t port, uint16_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val, 2); + else { + mach_accel_out(port, val, mach); + mach_accel_out(port + 1, (val >> 8), mach); + } +} + +static void +mach_accel_outl(uint16_t port, uint32_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + if (port & 0x8000) { + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, val & 0xffff, 2); + mach_accel_out_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, val >> 16, 2); + } else { + mach_accel_out(port, val, mach); + mach_accel_out(port + 1, (val >> 8), mach); + mach_accel_out(port + 2, (val >> 16), mach); + mach_accel_out(port + 3, (val >> 24), mach); + } +} + +#ifdef ATI_8514_ULTRA +static uint8_t +ati8514_accel_in(uint16_t port, svga_t *svga) +{ + return mach_accel_in_call(port, (mach_t *) svga->ext8514, svga, (ibm8514_t *) svga->dev8514); +} + +static uint8_t +ati8514_accel_inb(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint8_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 1); + else + temp = ati8514_accel_in(port, svga); + + return temp; +} + +static uint16_t +ati8514_accel_inw(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint16_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + else { + temp = ati8514_accel_in(port, svga); + temp |= (ati8514_accel_in(port + 1, svga) << 8); + } + return temp; +} + +static uint32_t +ati8514_accel_inl(uint16_t port, void *priv) +{ + svga_t *svga = (svga_t *)priv; + mach_t *mach = (mach_t *)svga->ext8514; + uint32_t temp; + + if (port & 0x8000) { + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + temp = (mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, 2) << 16); + } else { + temp = ati8514_accel_in(port, svga); + temp |= (ati8514_accel_in(port + 1, svga) << 8); + temp |= (ati8514_accel_in(port + 2, svga) << 16); + temp |= (ati8514_accel_in(port + 3, svga) << 24); + } + return temp; +} +#endif + +static uint8_t +mach_accel_in(uint16_t port, mach_t *mach) +{ + svga_t *svga = &mach->svga; + return mach_accel_in_call(port, mach, svga, (ibm8514_t *) svga->dev8514); +} + +static uint8_t +mach_accel_inb(uint16_t port, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + uint8_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 1); + else + temp = mach_accel_in(port, mach); + + return temp; +} + +static uint16_t +mach_accel_inw(uint16_t port, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + uint16_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + else { + temp = mach_accel_in(port, mach); + temp |= (mach_accel_in(port + 1, mach) << 8); + } + return temp; +} + +static uint32_t +mach_accel_inl(uint16_t port, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + uint32_t temp; + + if (port & 0x8000) { + temp = mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port, 2); + temp = (mach_accel_in_fifo(mach, svga, (ibm8514_t *) svga->dev8514, port + 2, 2) << 16); + } else { + temp = mach_accel_in(port, mach); + temp |= (mach_accel_in(port + 1, mach) << 8); + temp |= (mach_accel_in(port + 2, mach) << 16); + temp |= (mach_accel_in(port + 3, mach) << 24); + } + return temp; +} + +static uint32_t +mach32_decode_addr(svga_t *svga, uint32_t addr, int write) +{ + int memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + + addr &= 0x1ffff; + + switch (memory_map_mode) { + case 0: + break; + case 1: + if (addr >= 0x10000) + return 0xffffffff; + break; + case 2: + addr -= 0x10000; + if (addr >= 0x8000) + return 0xffffffff; + break; + default: + case 3: + addr -= 0x18000; + if (addr >= 0x8000) + return 0xffffffff; + break; + } + + if (memory_map_mode <= 1) { + if (write) + addr = (addr & svga->banked_mask) + svga->write_bank; + else + addr = (addr & svga->banked_mask) + svga->read_bank; + } + + return addr; +} + +static __inline void +mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int writemask2 = svga->writemask; + int reset_wm = 0; + latch_t vall; + uint8_t wm = svga->writemask; + uint8_t count; + uint8_t i; + + cycles -= svga->monitor->mon_video_timing_write_b; + + if (!linear) { + addr = mach32_decode_addr(svga, addr, 1); + if (addr == 0xffffffff) + return; + } + + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + + mach_log("WriteCommon chain4 = %x.\n", svga->chain4); + if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4 && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + if (!linear) + addr &= ~3; + + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr &= dev->vram_mask; + } else { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr &= dev->vram_mask; + } + addr &= svga->decode_mask; + + if (addr >= dev->vram_size) + return; + + addr &= dev->vram_mask; + + dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + + count = 4; + + switch (svga->writemode) { + case 0: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = val; + } + return; + } else { + for (i = 0; i < count; i++) { + if (svga->gdcreg[1] & (1 << i)) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + else + vall.b[i] = val; + } + } + break; + case 1: + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = svga->latch.b[i]; + } + return; + case 2: + for (i = 0; i < count; i++) + vall.b[i] = !!(val & (1 << i)) * 0xff; + + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + return; + } + break; + case 3: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; + + for (i = 0; i < count; i++) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + + reset_wm = 1; + break; + default: + break; + } + + switch (svga->gdcreg[3] & 0x18) { + case 0x00: /* Set */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + break; + case 0x08: /* AND */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } + break; + case 0x10: /* OR */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } + break; + case 0x18: /* XOR */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } + break; + + default: + break; + } + + if (reset_wm) + svga->gdcreg[8] = wm; +} + +static void +mach32_write(uint32_t addr, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + mach32_write_common(addr, val, 0, mach); +} + +static void +mach32_writew(uint32_t addr, uint16_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + mach32_write_common(addr, val & 0xff, 0, mach); + mach32_write_common(addr + 1, val >> 8, 0, mach); +} + +static void +mach32_writel(uint32_t addr, uint32_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + mach32_write_common(addr, val & 0xff, 0, mach); + mach32_write_common(addr + 1, val >> 8, 0, mach); + mach32_write_common(addr + 2, val >> 16, 0, mach); + mach32_write_common(addr + 3, val >> 24, 0, mach); +} + +static __inline uint8_t +mach32_read_common(uint32_t addr, int linear, mach_t *mach) +{ + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t latch_addr = 0; + int readplane = svga->readplane; + uint8_t count; + uint8_t temp; + uint8_t ret; + + cycles -= svga->monitor->mon_video_timing_read_b; + + if (!linear) { + addr = mach32_decode_addr(svga, addr, 0); + if (addr == 0xffffffff) + return 0xff; + } + + count = 2; + + latch_addr = (addr << count) & svga->decode_mask; + count = (1 << count); + + mach_log("ReadCommon chain4 = %x.\n", svga->chain4); + if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xff; + latch_addr = (addr & dev->vram_mask) & ~3; + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + return dev->vram[addr & dev->vram_mask]; + } else if (svga->chain4 && !svga->force_old_addr) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr &= dev->vram_mask; + } else { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xff; + latch_addr = (addr & dev->vram_mask) & ~3; + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + return dev->vram[addr & dev->vram_mask]; + } + + addr &= svga->decode_mask; + + /* standard VGA latched access */ + if (latch_addr >= dev->vram_size) { + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = 0xff; + } else { + latch_addr &= dev->vram_mask; + + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + } + + if (addr >= dev->vram_size) + return 0xff; + + addr &= dev->vram_mask; + + if (svga->readmode) { + temp = 0xff; + + for (uint8_t pixel = 0; pixel < 8; pixel++) { + for (uint8_t plane = 0; plane < count; plane++) { + if (svga->colournocare & (1 << plane)) { + /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ + if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) + temp &= ~(1 << pixel); + } + } + } + + ret = temp; + } else + ret = dev->vram[addr | readplane]; + + return ret; +} + +static uint8_t +mach32_read(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + uint8_t ret; + + ret = mach32_read_common(addr, 0, mach); + return ret; +} + +static uint16_t +mach32_readw(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + uint16_t ret; + + ret = mach32_read_common(addr, 0, mach); + ret |= (mach32_read_common(addr + 1, 0, mach) << 8); + return ret; +} + +static uint32_t +mach32_readl(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + uint32_t ret; + + ret = mach32_read_common(addr, 0, mach); + ret |= (mach32_read_common(addr + 1, 0, mach) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach) << 24); + return ret; +} + +static void +mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDB Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outb(0x02ee + (addr & 1) + (port_dword << 8), val, mach); + } else { + mach_log("Port WORDB Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outb(0x02e8 + (addr & 1) + (port_dword << 8), val, mach); + } + } else { + mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val); + if (dev->on[0] || dev->on[1]) + mach32_write_common(addr, val, 1, mach); + else + svga_write_linear(addr, val, svga); + } +} + +static void +mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDW Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outw(0x02ee + (port_dword << 8), val, mach); + } else { + mach_log("Port WORDW Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outw(0x02e8 + (port_dword << 8), val, mach); + } + } else { + mach_log("Linear WORDW Write=%08x, val=%04x.\n", addr, val); + if (dev->on[0] || dev->on[1]) { + mach32_write_common(addr, val & 0xff, 1, mach); + mach32_write_common(addr + 1, val >> 8, 1, mach); + } else + svga_writew_linear(addr, val, svga); + } +} + +static void +mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDL Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outw(0x02ee + (port_dword << 8), val & 0xffff, mach); + mach_accel_outw(0x02ee + (port_dword << 8) + 4, val >> 16, mach); + } else { + mach_log("Port WORDL Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outw(0x02e8 + (port_dword << 8), val & 0xffff, mach); + mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach); + } + } else { + mach_log("Linear WORDL Write=%08x, val=%08x.\n", addr, val); + if (dev->on[0] || dev->on[1]) { + mach32_write_common(addr, val & 0xff, 1, mach); + mach32_write_common(addr + 1, val >> 8, 1, mach); + mach32_write_common(addr + 2, val >> 16, 1, mach); + mach32_write_common(addr + 3, val >> 24, 1, mach); + } else + svga_writel_linear(addr, val, svga); + } +} + +static uint8_t +mach32_ap_readb(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) + temp = mach_accel_inb(0x02ee + (addr & 1) + (port_dword << 8), mach); + else + temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); + } else { + if (dev->on[0] || dev->on[1]) + temp = mach32_read_common(addr, 1, mach); + else + temp = svga_read_linear(addr, svga); + + mach_log("Linear WORDB Read=%08x, ret=%02x, fast=%d.\n", addr, temp, svga->fast); + } + + return temp; +} + +static uint16_t +mach32_ap_readw(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) + temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); + else + temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); + } else { + if (dev->on[0] || dev->on[1]) { + temp = mach32_read_common(addr, 1, mach); + temp |= (mach32_read_common(addr + 1, 1, mach) << 8); + } else + temp = svga_readw_linear(addr, svga); + + mach_log("Linear WORDW Read=%08x, ret=%04x.\n", addr, temp); + } + + return temp; +} + +static uint32_t +mach32_ap_readl(uint32_t addr, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); + temp |= (mach_accel_inw(0x02ee + (port_dword << 8) + 4, mach) << 8); + } else { + temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); + temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8); + } + } else { + if (dev->on[0] || dev->on[1]) { + temp = mach32_read_common(addr, 1, mach); + temp |= (mach32_read_common(addr + 1, 1, mach) << 8); + temp |= (mach32_read_common(addr + 2, 1, mach) << 16); + temp |= (mach32_read_common(addr + 3, 1, mach) << 24); + } else + temp = svga_readl_linear(addr, svga); + + mach_log("Linear WORDL Read=%08x, ret=%08x, ON0=%d, ON1=%d.\n", addr, temp, dev->on[0], dev->on[1]); + } + + return temp; +} + +static void +mach32_updatemapping(mach_t *mach, svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if (mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach->mmio_linear_mapping); + return; + } + + if (mach->regs[0xbd] & 4) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + } else { + switch (svga->gdcreg[6] & 0x0c) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + + default: + break; + } + } + + mach_log("Linear base = %08x, aperture = %04x, localcntl = %02x svgagdc = %x.\n", mach->linear_base, mach->memory_aperture, mach->local_cntl, svga->gdcreg[6] & 0x0c); + if (mach->linear_base) { + if (((mach->memory_aperture & 3) == 1) && !mach->pci_bus) { + /*1 MB aperture*/ + mach->ap_size = 1; + mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); + } else { + /*4 MB aperture*/ + mach->ap_size = 4; + mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); + } + } else { + mach->ap_size = 4; + mem_mapping_disable(&mach->mmio_linear_mapping); + } + if (((dev->local & 0xff) >= 0x02) && (dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) { + mach_log("ExtON.\n"); + mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); + mem_mapping_set_p(&svga->mapping, mach); + } else { + mach_log("ExtOFF.\n"); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); + } +} + +static void +mach32_hwcursor_draw(svga_t *svga, int displine) +{ + const mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t dat; + int comb; + int offset = dev->hwcursor_latch.x - dev->hwcursor_latch.xoff; + uint32_t color0; + uint32_t color1; + uint32_t *p; + int x_pos; + int y_pos; + + mach_log("BPP=%d.\n", dev->accel_bpp); + switch (dev->accel_bpp) { + default: + case 8: + color0 = dev->pallook[mach->cursor_col_0]; + color1 = dev->pallook[mach->cursor_col_1]; + break; + case 15: + color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; + color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; + break; + case 16: + color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; + color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; + break; + case 24: + case 32: + color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); + color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); + break; + } + + if (dev->interlace && dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; + + for (int x = 0; x < 64; x += 8) { + dat = dev->vram[dev->hwcursor_latch.addr & dev->vram_mask] | (dev->vram[(dev->hwcursor_latch.addr + 1) & dev->vram_mask] << 8); + for (int xx = 0; xx < 8; xx++) { + comb = (dat >> (xx << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; + + if (offset >= dev->hwcursor_latch.x) { + mach_log("COMB=%d.\n", comb); + switch (comb) { + case 0: + p[x_pos] = color0; + break; + case 1: + p[x_pos] = color1; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + + default: + break; + } + } + offset++; + } + dev->hwcursor_latch.addr += 2; + } + if (dev->interlace && !dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; +} + +#ifdef ATI_8514_ULTRA +static void +ati8514_io_set(svga_t *svga) +{ + io_sethandler(0x2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x12e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x16e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x22e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x82e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x86e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x92e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x96e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + + io_sethandler(0xc2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf2e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf6e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + + io_sethandler(0x02ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x06ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x0aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x0eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x12ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x16ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x1eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x22ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x26ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x2eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x32ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x36ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x3aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x3eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x42ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x46ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x4aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x52ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x56ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x5eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x62ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x66ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x6eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x72ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x76ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x7aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x7eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x82ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x86ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x8eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x92ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x96ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x9aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xa6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xaeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xb6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xbeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xc6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xcaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xceee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xd6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xdeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xe6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); +} +#endif + +static void +mach_io_set(mach_t *mach) +{ + io_sethandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + + io_sethandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + + io_sethandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x86ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); +} + +static uint8_t +mach_mca_read(int port, void *priv) +{ + const mach_t *mach = (mach_t *) priv; + + mach_log("[%04X]: MCA read port = %x, val = %02x.\n", CS, port & 7, mach->pos_regs[port & 7]); + return mach->pos_regs[port & 7]; +} + +static void +mach_mca_write(int port, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + + if (port < 0x102) + return; + + mach->pos_regs[port & 7] = val; + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, mach->pos_regs[port & 7], (((mach->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mem_mapping_disable(&mach->bios_rom.mapping); + mem_mapping_disable(&mach->bios_rom2.mapping); + if (mach->pos_regs[2] & 0x01) { + mem_mapping_enable(&mach->bios_rom.mapping); + mem_mapping_enable(&mach->bios_rom2.mapping); + } +} + +static uint8_t +mach_mca_feedb(void *priv) +{ + const mach_t *mach = (mach_t *) priv; + + mach_log("FeedB = %x.\n", mach->pos_regs[2] & 0x01); + return mach->pos_regs[2] & 0x01; +} + +static void +mach_mca_reset(void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + mem_mapping_disable(&mach->bios_rom.mapping); + mem_mapping_disable(&mach->bios_rom2.mapping); + mach_log("MCA reset.\n"); + dev->on[0] = 0; + dev->on[1] = 0; + vga_on = 1; + mach_mca_write(0x102, 0, mach); +} + +#ifdef ATI_8514_ULTRA +uint8_t +ati8514_mca_read(int port, void *priv) +{ + const svga_t *svga = (svga_t *) priv; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + return (dev->pos_regs[port & 7]); +} + +void +ati8514_mca_write(int port, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if (port < 0x102) + return; + + dev->pos_regs[port & 7] = val; + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, dev->pos_regs[port & 7], (((dev->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mem_mapping_disable(&dev->bios_rom.mapping); + + if (dev->pos_regs[2] & 0x01) + mem_mapping_enable(&dev->bios_rom.mapping); +} +#endif + +static uint8_t +mach32_pci_read(UNUSED(int func), int addr, void *priv) +{ + const mach_t *mach = (mach_t *) priv; + uint8_t ret = 0x00; + + if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) + return ret; + + switch (addr) { + case 0x00: + ret = 0x02; /*ATI*/ + break; + case 0x01: + ret = 0x10; + break; + + case 0x02: + ret = 0x58; + break; + case 0x03: + ret = 0x41; + break; + + case PCI_REG_COMMAND: + ret = mach->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ + break; + + case 0x07: + ret = 0x01; /*Medium DEVSEL timing*/ + break; + + case 0x0a: + ret = 0x00; /*Supports VGA interface*/ + break; + case 0x0b: + ret = 0x03; + break; + + case 0x10: + ret = 0x00; /*Linear frame buffer address*/ + break; + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = mach->linear_base >> 16; + break; + case 0x13: + ret = mach->linear_base >> 24; + break; + + case 0x30: + ret = (mach->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = mach->pci_regs[0x32]; + break; + case 0x33: + ret = mach->pci_regs[0x33]; + break; + + case 0x3c: + ret = mach->int_line; + break; + case 0x3d: + ret = PCI_INTA; + break; + + default: + break; + } + + return ret; +} + +static void +mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) + return; + + switch (addr) { + case PCI_REG_COMMAND: + mach->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) { + io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + } else { + io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + } + mach32_updatemapping(mach, &mach->svga); + break; + + case 0x12: + mach->linear_base = (mach->linear_base & 0xff000000) | ((val & 0xc0) << 16); + mach32_updatemapping(mach, &mach->svga); + break; + case 0x13: + mach->linear_base = (mach->linear_base & 0xc00000) | (val << 24); + mach32_updatemapping(mach, &mach->svga); + break; + + case 0x30: + case 0x32: + case 0x33: + mach->pci_regs[addr] = val; + if (mach->pci_regs[0x30] & 0x01) { + uint32_t bios_addr = (mach->pci_regs[0x32] << 16) | (mach->pci_regs[0x33] << 24); + mach_log("Mach32 bios_rom enabled at %08x\n", bios_addr); + mem_mapping_set_addr(&mach->bios_rom.mapping, bios_addr, 0x8000); + } else { + mach_log("Mach32 bios_rom disabled\n"); + mem_mapping_disable(&mach->bios_rom.mapping); + } + return; + + case 0x3c: + mach->int_line = val; + break; + + default: + break; + } +} + +static void * +mach8_init(const device_t *info) +{ + mach_t *mach; + svga_t *svga; + ibm8514_t *dev; + + mach = calloc(1, sizeof(mach_t)); + + svga = &mach->svga; + dev = (ibm8514_t *) calloc(1, sizeof(ibm8514_t)); + + svga->dev8514 = dev; + + mach->pci_bus = !!(info->flags & DEVICE_PCI); + mach->vlb_bus = !!(info->flags & DEVICE_VLB); + mach->mca_bus = !!(info->flags & DEVICE_MCA); + dev->type = info->flags; + dev->local = info->local & 0xff; + mach->has_bios = !(info->local & 0xff00); + mach->memory = device_get_config_int("memory"); + mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1; + + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) { + if (mach->has_bios) { + rom_init(&mach->bios_rom, + BIOS_MACH32_PCI_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + } + } + else if (mach->vlb_bus) + rom_init(&mach->bios_rom, + BIOS_MACH32_VLB_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + else if (mach->mca_bus) { + rom_init(&mach->bios_rom, + BIOS_MACH32_MCA_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach->bios_rom2, + BIOS_MACH32_MCA_ROM_PATH, + 0xc8000, 0x1000, 0x0fff, + 0x8000, MEM_MAPPING_EXTERNAL); + } else { + rom_init(&mach->bios_rom, + BIOS_MACH32_ISA_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + } + } else + rom_init(&mach->bios_rom, + BIOS_MACH8_VGA_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + + if ((dev->local & 0xff) >= 0x02) { + svga_init(info, svga, mach, mach->memory << 10, /*default: 2MB for Mach32*/ + mach_recalctimings, + mach_in, mach_out, + mach32_hwcursor_draw, + NULL); + dev->vram_size = mach->memory << 10; + dev->vram = calloc(dev->vram_size, 1); + dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->vram_mask = dev->vram_size - 1; + dev->hwcursor.cur_ysize = 64; + mach->config1 = 0x20; + if (mach->pci_bus && !mach->ramdac_type) + svga->ramdac = device_add(&ati68860_ramdac_device); + else + svga->ramdac = device_add(&ati68875_ramdac_device); + if (mach->vlb_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_vlb); + if (!is486) + mach->config1 |= 0x0a; + else + mach->config1 |= 0x0c; + mach->config1 |= 0x0400; + svga->clock_gen = device_add(&ati18811_0_device); + } else if (mach->mca_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_mca); + if (is286 && !is386) + mach->config1 |= 0x04; + else + mach->config1 |= 0x06; + mach->config1 |= 0x0400; + svga->clock_gen = device_add(&ati18811_1_device); + } else if (mach->pci_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); + mach->config1 |= 0x0e; + if (mach->ramdac_type) + mach->config1 |= 0x0400; + else + mach->config1 |= 0x0a00; + mach->config2 |= 0x2000; + svga->clock_gen = device_add(&ati18811_0_device); + } else { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); + mach->config1 |= 0x0400; + svga->clock_gen = device_add(&ati18811_0_device); + } + mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); + mem_mapping_disable(&mach->mmio_linear_mapping); + } else { + svga_init(info, svga, mach, (512 << 10), /*default: 512kB VGA for 28800-6 + 1MB for Mach8*/ + mach_recalctimings, + mach_in, mach_out, + NULL, + NULL); + dev->vram_size = (1024 << 10); + dev->vram = calloc(dev->vram_size, 1); + dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->vram_mask = dev->vram_size - 1; + video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); + mach->config1 = 0x01 | 0x02 | 0x20 | 0x08 | 0x80; + mach->config2 = 0x02; + svga->clock_gen = device_add(&ati18810_device); + } + dev->bpp = 0; + svga->getclock = ics2494_getclock; + + dev->on[0] = 0; + dev->on[1] = 0; + dev->ext_pitch = 1024; + dev->ext_crt_pitch = 0x80; + dev->accel_bpp = 8; + svga->force_old_addr = 1; + svga->miscout = 1; + svga->bpp = 8; + svga->packed_chain4 = 1; + dev->rowoffset = 0x80; + io_sethandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mach_io_set(mach); + + if ((dev->local & 0xff) >= 0x02) { + svga->decode_mask = (4 << 20) - 1; + mach->cursor_col_1 = 0xff; + mach->ext_cur_col_1_r = 0xff; + mach->ext_cur_col_1_g = 0xff; + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + if (mach->vlb_bus) + ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); + else if (mach->mca_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_mca.nvr", 1); + mem_mapping_disable(&mach->bios_rom.mapping); + mem_mapping_disable(&mach->bios_rom2.mapping); + mach->pos_regs[0] = 0x89; + mach->pos_regs[1] = 0x80; + mca_add(mach_mca_read, mach_mca_write, mach_mca_feedb, mach_mca_reset, mach); + } else if (mach->pci_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1); + if (mach->has_bios) { + mem_mapping_disable(&mach->bios_rom.mapping); + pci_add_card(PCI_ADD_NORMAL, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); + } else + pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); + + mach->pci_regs[PCI_REG_COMMAND] = 0x83; + mach->pci_regs[0x30] = 0x00; + mach->pci_regs[0x32] = 0x0c; + mach->pci_regs[0x33] = 0x00; + } else + ati_eeprom_load(&mach->eeprom, "mach32.nvr", 1); + } else + ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); + + timer_add(&svga->timer8514, ibm8514_poll, svga, 1); + + return mach; +} + +#ifdef ATI_8514_ULTRA +void +ati8514_init(svga_t *svga, void *ext8514, void *dev8514) +{ + mach_t *mach = (mach_t *)ext8514; + ibm8514_t *dev = (ibm8514_t *)dev8514; + + dev->on[0] = 0; + dev->on[1] = 0; + dev->ext_pitch = 1024; + dev->ext_crt_pitch = 0x80; + dev->accel_bpp = 8; + dev->rowoffset = 0x80; + dev->hdisp = 1024; + dev->vdisp = 768; + + io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga); + ati8514_io_set(svga); + mach->mca_bus = !!(dev->type & DEVICE_MCA); + + if (mach->mca_bus) + mach->config1 = 0x02 | 0x04 | 0x08 | 0x20 | 0x80; + else + mach->config1 = 0x02 | 0x08 | 0x20 | 0x80; + + mach->config2 = 0x01 | 0x02; +} +#endif + +static int +mach8_vga_available(void) +{ + return rom_present(BIOS_MACH8_VGA_ROM_PATH); +} + +static int +mach32_isa_available(void) +{ + return rom_present(BIOS_MACH32_ISA_ROM_PATH); +} + +static int +mach32_vlb_available(void) +{ + return rom_present(BIOS_MACH32_VLB_ROM_PATH); +} + +static int +mach32_mca_available(void) +{ + return rom_present(BIOS_MACH32_MCA_ROM_PATH); +} + +static int +mach32_pci_available(void) +{ + return rom_present(BIOS_MACH32_PCI_ROM_PATH); +} + +static void +mach_close(void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + if (dev) { + free(dev->vram); + free(dev->changedvram); + + free(dev); + } + + svga_close(svga); + free(mach); +} + +static void +mach_speed_changed(void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + svga_recalctimings(svga); +} + +static void +mach_force_redraw(void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + svga->fullchange = svga->monitor->mon_changeframecount; +} + +// clang-format off +static const device_config_t mach32_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2048, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "4 MB", + .value = 4096 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + +// clang-format off +static const device_config_t mach32_pci_config[] = { + { + .name = "ramdac", + .description = "RAMDAC type", + .type = CONFIG_SELECTION, + .default_int = 0, + .selection = { + { + .description = "ATI 68860", + .value = 0 + }, + { + .description = "ATI 68875", + .value = 1 + }, + { + .description = "" + } + } + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2048, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "4 MB", + .value = 4096 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + +const device_t mach8_vga_isa_device = { + .name = "ATI Mach8 (ATI Graphics Ultra) (ISA)", + .internal_name = "mach8_vga_isa", + .flags = DEVICE_ISA, + .local = 1, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach8_vga_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = NULL +}; + +const device_t mach32_isa_device = { + .name = "ATI Mach32 (ISA)", + .internal_name = "mach32_isa", + .flags = DEVICE_ISA, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_isa_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + +const device_t mach32_vlb_device = { + .name = "ATI Mach32 (VLB)", + .internal_name = "mach32_vlb", + .flags = DEVICE_VLB, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_vlb_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + +const device_t mach32_mca_device = { + .name = "ATI Mach32 (MCA)", + .internal_name = "mach32_mca", + .flags = DEVICE_MCA, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_mca_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + +const device_t mach32_pci_device = { + .name = "ATI Mach32 (PCI)", + .internal_name = "mach32_pci", + .flags = DEVICE_PCI, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_pci_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_pci_config +}; + +const device_t mach32_onboard_pci_device = { + .name = "ATI Mach32 (PCI) On-Board", + .internal_name = "mach32_pci_onboard", + .flags = DEVICE_PCI, + .local = 2 | 0x100, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_pci_config +}; + diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index 1874afce9b..f13740d34d 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -10,10 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. */ #include @@ -28,8 +26,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct att49x_ramdac_t { int type; int state; uint8_t ctrl; @@ -42,9 +39,9 @@ enum { }; static void -att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) +att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; ramdac->ctrl = val; switch ((ramdac->ctrl >> 5) & 7) { case 0: @@ -63,6 +60,9 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) case 7: svga->bpp = 24; break; + + default: + break; } if (ramdac->type == ATT_490 || ramdac->type == ATT_491) svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); @@ -70,9 +70,9 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) } void -att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -100,13 +100,16 @@ att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) att49x_ramdac_control(val, ramdac, svga); ramdac->state = 0; break; + + default: + break; } } uint8_t -att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -143,6 +146,9 @@ att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) temp = ramdac->ctrl; ramdac->state = 0; break; + + default: + break; } return temp; diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c index 2dab4b9034..47eebccae8 100644 --- a/src/video/vid_att2xc498_ramdac.c +++ b/src/video/vid_att2xc498_ramdac.c @@ -10,10 +10,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. */ #include @@ -28,8 +26,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct att498_ramdac_t { int type; int state; int loop; @@ -37,9 +34,9 @@ typedef struct } att498_ramdac_t; static void -att498_ramdac_control(uint8_t val, void *p, svga_t *svga) +att498_ramdac_control(uint8_t val, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; ramdac->ctrl = val; if (val == 0xff) @@ -73,9 +70,9 @@ att498_ramdac_control(uint8_t val, void *p, svga_t *svga) } void -att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -102,13 +99,16 @@ att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) case 0x06: att498_ramdac_control(val, ramdac, svga); break; + + default: + break; } } uint8_t -att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -147,6 +147,9 @@ att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) temp = ramdac->ctrl; ramdac->state = 0; break; + + default: + break; } return temp; diff --git a/src/video/vid_av9194.c b/src/video/vid_av9194.c index f8ebc89de7..e7cf75deee 100644 --- a/src/video/vid_av9194.c +++ b/src/video/vid_av9194.c @@ -27,9 +27,10 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> float -av9194_getclock(int clock, void *p) +av9194_getclock(int clock, UNUSED(void *priv)) { float ret = 0.0; @@ -79,13 +80,16 @@ av9194_getclock(int clock, void *p) case 0xf: ret = 94500000.0; break; + + default: + break; } return ret; } static void * -av9194_init(const device_t *info) +av9194_init(UNUSED(const device_t *info)) { /* Return something non-NULL. */ return (void *) &av9194_device; diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 9ef75b09ed..91ddce9563 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -29,13 +29,13 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct bt48x_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t cursor32_data[256]; uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; + int hwc_y; + int hwc_x; uint8_t cmd_r0; uint8_t cmd_r1; uint8_t cmd_r2; @@ -77,14 +77,17 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) case 0x60: svga->bpp = 4; break; + + default: + break; } svga_recalctimings(svga); } void -bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; uint32_t o32; uint8_t *cd; uint16_t index; @@ -104,7 +107,7 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * svga->dac_status = addr & 0x03; svga->dac_addr = val; if (ramdac->type >= BT485) - svga->dac_addr |= ((int) (ramdac->cmd_r3 & 0x03) << 8); + svga->dac_addr |= ((ramdac->cmd_r3 & 0x03) << 8); if (svga->dac_status) svga->dac_addr = (svga->dac_addr + 1) & da_mask; break; @@ -143,6 +146,9 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * svga->dac_addr = (svga->dac_addr + 1) & 0xff; svga->dac_pos = 0; break; + + default: + break; } break; case 0x06: /* Command Register 0 (RS value = 0110) */ @@ -183,6 +189,9 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * break; } break; + + default: + break; } } break; @@ -215,17 +224,20 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; + + default: + break; } return; } uint8_t -bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; uint8_t temp = 0xff; - uint8_t *cd; + const uint8_t *cd; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -271,6 +283,9 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) else temp = ramdac->extpal[index].b & 0x3f; break; + + default: + break; } break; case 0x06: /* Command Register 0 (RS value = 0110) */ @@ -285,8 +300,8 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x0a: if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) { switch (svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f)) { - case 0x00: default: + case 0x00: temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); break; case 0x01: @@ -307,7 +322,6 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) temp = 0xff; break; } - break; } } else temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); @@ -337,15 +351,18 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x0f: /* Cursor Y High Register (RS value = 1111) */ temp = (ramdac->hwc_y >> 8) & 0xff; break; + + default: + break; } return temp; } void -bt48x_recalctimings(void *p, svga_t *svga) +bt48x_recalctimings(void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + const bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; svga->interlace = ramdac->cmd_r2 & 0x08; if (ramdac->cmd_r3 & 0x08) @@ -369,7 +386,7 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) uint32_t clr2; uint32_t clr3; uint32_t *p; - uint8_t *cd; + const uint8_t *cd; bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; @@ -419,6 +436,9 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr3; break; + + default: + break; } break; case 2: /* PM/Windows */ @@ -432,6 +452,9 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 3: /* X-Windows */ @@ -442,8 +465,14 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr2; break; + + default: + break; } break; + + default: + break; } } offset++; @@ -484,6 +513,9 @@ bt48x_ramdac_init(const device_t *info) case BT485A: ramdac->status = 0x20; break; + + default: + break; } return ramdac; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 7239790dcc..2ea07c3467 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -12,9 +12,11 @@ * * Authors: Sarah Walker, * Miran Grca, + * W. M. Martinez, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. + * Copyright 2023 W. M. Martinez */ #include #include @@ -33,6 +35,7 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> #define CGA_RGB 0 #define CGA_COMPOSITE 1 @@ -40,19 +43,37 @@ #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 +#define DOUBLE_NONE 0 +#define DOUBLE_SIMPLE 1 +#define DOUBLE_INTERPOLATE_SRGB 2 +#define DOUBLE_INTERPOLATE_LINEAR 3 + +typedef union +{ + uint32_t color; + struct { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; + }; +} color_t; + static uint8_t crtcmask[32] = { 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t interp_lut[2][256][256]; + static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void cga_recalctimings(cga_t *cga); void -cga_out(uint16_t addr, uint8_t val, void *p) +cga_out(uint16_t addr, uint8_t val, void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; uint8_t old; if ((addr >= 0x3d0) && (addr <= 0x3d7)) @@ -77,7 +98,7 @@ cga_out(uint16_t addr, uint8_t val, void *p) cga->cgamode = val; if (old ^ val) { - if ((old ^ val) & 0x05) + if ((old ^ val) & 0x07) update_cga16_color(val); cga_recalctimings(cga); @@ -89,13 +110,16 @@ cga_out(uint16_t addr, uint8_t val, void *p) if (old ^ val) cga_recalctimings(cga); return; + + default: + break; } } uint8_t -cga_in(uint16_t addr, void *p) +cga_in(uint16_t addr, void *priv) { - cga_t *cga = (cga_t *) p; + const cga_t *cga = (cga_t *) priv; uint8_t ret = 0xff; @@ -112,29 +136,32 @@ cga_in(uint16_t addr, void *p) case 0x3DA: ret = cga->cgastat; break; + + default: + break; } return ret; } void -cga_pravetz_out(uint16_t addr, uint8_t val, void *p) +cga_pravetz_out(UNUSED(uint16_t addr), uint8_t val, void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; cga->fontbase = (((unsigned int) val) << 8); } uint8_t -cga_pravetz_in(uint16_t addr, void *p) +cga_pravetz_in(UNUSED(uint16_t addr), void *priv) { - cga_t *cga = (cga_t *) p; + const cga_t *cga = (cga_t *) priv; return (cga->fontbase >> 8); } void -cga_waitstates(void *p) +cga_waitstates(UNUSED(void *priv)) { int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; @@ -144,9 +171,9 @@ cga_waitstates(void *p) } void -cga_write(uint32_t addr, uint8_t val, void *p) +cga_write(uint32_t addr, uint8_t val, void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { @@ -158,9 +185,9 @@ cga_write(uint32_t addr, uint8_t val, void *p) } uint8_t -cga_read(uint32_t addr, void *p) +cga_read(uint32_t addr, void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; cga_waitstates(cga); if (cga->snow_enabled) { @@ -192,24 +219,275 @@ cga_recalctimings(cga_t *cga) cga->dispofftime = (uint64_t) (_dispofftime); } -void -cga_poll(void *p) +static void +cga_render(cga_t *cga, int line) { - cga_t *cga = (cga_t *) p; uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; int drawcursor; int x; int c; - int xs_temp; - int ys_temp; - int oldvc; uint8_t chr; uint8_t attr; - uint8_t border; uint16_t dat; int cols[4]; int col; + + if ((cga->cgamode & 0x12) == 0x12) { + for (c = 0; c < 8; ++c) { + buffer32->line[line][c] = 0; + if (cga->cgamode & 1) + buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = 0; + else + buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0; + } + } else { + for (c = 0; c < 8; ++c) { + buffer32->line[line][c] = (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) + buffer32->line[line][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; + else + buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; + } + } + if (cga->cgamode & 1) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 3) + c + 8] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 3) + c + 8] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + cga->ma++; + } + } else if (!(cga->cgamode & 2)) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->vram[(cga->ma << 1) & 0x3fff]; + attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80)) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + cga->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } else if (!(cga->cgamode & 16)) { + cols[0] = (cga->cgacol & 15) | 16; + col = (cga->cgacol & 16) ? 24 : 16; + if (cga->cgamode & 4) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 7; /* White */ + } else if (cga->cgacol & 32) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 5; /* Magenta */ + cols[3] = col | 7; /* White */ + } else { + cols[1] = col | 2; /* Green */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 6; /* Yellow */ + } + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 8; c++) { + buffer32->line[line][(x << 4) + (c << 1) + 8] + = buffer32->line[line][(x << 4) + (c << 1) + 9] + = cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = (cga->cgacol & 15) + 16; + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 16; c++) { + buffer32->line[line][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } +} + +static void +cga_render_blank(cga_t *cga, int line) +{ + int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; + + if (cga->cgamode & 1) + hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col); + else + hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col); +} + +static void +cga_render_process(cga_t *cga, int line) +{ + int x; + uint8_t border; + + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; + + if (cga->composite) { + border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + + Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]); + } else + video_process_8(x, line); +} + +static uint8_t +cga_interpolate_srgb(uint8_t co1, uint8_t co2, double fraction) +{ + uint8_t ret = ((co2 - co1) * fraction + co1); + + return ret; +} + +static uint8_t +cga_interpolate_linear(uint8_t co1, uint8_t co2, double fraction) +{ + double c1, c2; + double r1, r2; + uint8_t ret; + + c1 = ((double) co1) / 255.0; + c1 = pow((co1 >= 0) ? c1 : -c1, 2.19921875); + if (co1 <= 0) + c1 = -c1; + c2 = ((double) co2) / 255.0; + c2 = pow((co2 >= 0) ? c2 : -c2, 2.19921875); + if (co2 <= 0) + c2 = -c2; + r1 = ((c2 - c1) * fraction + c1); + r2 = pow((r1 >= 0.0) ? r1 : -r1, 1.0 / 2.19921875); + if (r1 <= 0.0) + r2 = -r2; + ret = (uint8_t) (r2 * 255.0); + + return ret; +} + +static color_t +cga_interpolate_lookup(cga_t *cga, color_t color1, color_t color2, double fraction) +{ + color_t ret; + uint8_t dt = cga->double_type - DOUBLE_INTERPOLATE_SRGB; + + ret.a = 0x00; + ret.r = interp_lut[dt][color1.r][color2.r]; + ret.g = interp_lut[dt][color1.g][color2.g]; + ret.b = interp_lut[dt][color1.b][color2.b]; + + return ret; +} + +static void +cga_interpolate(cga_t *cga, int x, int y, int w, int h) +{ + double quotient = 0.5; + + for (int i = y; i < (y + h); i++) { + if (i & 1) for (int j = x; j < (x + w); j++) { + int prev = i - 1; + int next = i + 1; + color_t prev_color, next_color; + color_t black; + color_t interim_1, interim_2; + color_t final; + + if (i < 0) + continue; + + black.color = 0x00000000; + + if ((prev >= 0) && (prev < (y + h))) + prev_color.color = buffer32->line[prev][j]; + else + prev_color.color = 0x00000000; + + if ((next >= 0) && (next < (y + h))) + next_color.color = buffer32->line[next][j]; + else + next_color.color = 0x00000000; + + interim_1 = cga_interpolate_lookup(cga, prev_color, black, quotient); + interim_2 = cga_interpolate_lookup(cga, black, next_color, quotient); + final = cga_interpolate_lookup(cga, interim_1, interim_2, quotient); + + buffer32->line[i][j] = final.color; + } + } +} + +static void +cga_blit_memtoscreen(cga_t *cga, int x, int y, int w, int h) +{ + if (cga->double_type > DOUBLE_SIMPLE) + cga_interpolate(cga, x, y, w, h); + + video_blit_memtoscreen(x, y, w, h); +} + +void +cga_poll(void *priv) +{ + cga_t *cga = (cga_t *) priv; + int x; int oldsc; + int oldvc; + int xs_temp; + int ys_temp; + int old_ma; if (!cga->linepos) { timer_advance_u64(&cga->timer, cga->dispofftime); @@ -224,144 +502,44 @@ cga_poll(void *p) video_wait_for_buffer(); } cga->lastline = cga->displine; - for (c = 0; c < 8; c++) { - if ((cga->cgamode & 0x12) == 0x12) { - buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0; - if (cga->cgamode & 1) { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0; - } else { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0; - } - } else { - buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - } else { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } - } - } - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - cga->ma++; - } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->vram[(cga->ma << 1) & 0x3fff]; - attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80)) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - cga->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else if (!(cga->cgamode & 16)) { - cols[0] = (cga->cgacol & 15) | 16; - col = (cga->cgacol & 16) ? 24 : 16; - if (cga->cgamode & 4) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 7; /* White */ - } else if (cga->cgacol & 32) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 5; /* Magenta */ - cols[3] = col | 7; /* White */ - } else { - cols[1] = col | 2; /* Green */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 6; /* Yellow */ - } - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = (cga->cgacol & 15) + 16; - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[cga->displine << 1][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } + switch (cga->double_type) { + default: + cga_render(cga, cga->displine << 1); + cga_render_blank(cga, (cga->displine << 1) + 1); + break; + case DOUBLE_NONE: + cga_render(cga, cga->displine); + break; + case DOUBLE_SIMPLE: + old_ma = cga->ma; + cga_render(cga, cga->displine << 1); + cga->ma = old_ma; + cga_render(cga, (cga->displine << 1) + 1); + break; } } else { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]); - } else { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]); + switch (cga->double_type) { + default: + cga_render_blank(cga, cga->displine << 1); + break; + case DOUBLE_NONE: + cga_render_blank(cga, cga->displine); + break; + case DOUBLE_SIMPLE: + cga_render_blank(cga, cga->displine << 1); + cga_render_blank(cga, (cga->displine << 1) + 1); + break; } } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; - - if (cga->composite) { - if (cga->cgamode & 0x10) - border = 0x00; - else - border = cga->cgacol & 0x0f; - - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine << 1]); - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]); - } else { - video_process_8(x, cga->displine << 1); - video_process_8(x, (cga->displine << 1) + 1); + switch (cga->double_type) { + default: + cga_render_process(cga, cga->displine << 1); + cga_render_process(cga, (cga->displine << 1) + 1); + break; + case DOUBLE_NONE: + cga_render_process(cga, cga->displine); + break; } cga->sc = oldsc; @@ -378,7 +556,8 @@ cga_poll(void *p) if (!cga->vsynctime) cga->cgastat &= ~8; } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && + cga->sc == ((cga->crtc[11] & 31) >> 1))) { cga->con = 0; cga->coff = 1; } @@ -436,31 +615,45 @@ cga_poll(void *p) cga->lastline++; xs_temp = x; - ys_temp = (cga->lastline - cga->firstline) << 1; + ys_temp = cga->lastline - cga->firstline; + if (cga->double_type > DOUBLE_NONE) + ys_temp <<= 1; if ((xs_temp > 0) && (ys_temp > 0)) { if (xs_temp < 64) xs_temp = 656; if (ys_temp < 32) - ys_temp = 400; + ys_temp = 200; if (!enable_overscan) xs_temp -= 16; - if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((cga->cgamode & 8) && ((xs_temp != xsize) || + (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + if (cga->double_type > DOUBLE_NONE) + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + else + set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0)); if (video_force_resize_get()) video_force_resize_set(0); } - if (enable_overscan) { - video_blit_memtoscreen(0, (cga->firstline - 4) << 1, - xsize, ((cga->lastline - cga->firstline) + 8) << 1); + if (cga->double_type > DOUBLE_NONE) { + if (enable_overscan) + cga_blit_memtoscreen(cga, 0, (cga->firstline - 4) << 1, + xsize, ((cga->lastline - cga->firstline) << 1) + 16); + else + cga_blit_memtoscreen(cga, 8, cga->firstline << 1, + xsize, (cga->lastline - cga->firstline) << 1); } else { - video_blit_memtoscreen(8, cga->firstline << 1, - xsize, (cga->lastline - cga->firstline) << 1); + if (enable_overscan) + video_blit_memtoscreen(0, cga->firstline - 4, + xsize, (cga->lastline - cga->firstline) + 8); + else + video_blit_memtoscreen(8, cga->firstline, + xsize, cga->lastline - cga->firstline); } } @@ -494,7 +687,8 @@ cga_poll(void *p) } if (cga->cgadispon) cga->cgastat &= ~1; - if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))) + if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && + cga->sc == ((cga->crtc[10] & 31) >> 1))) cga->con = 1; if (cga->cgadispon && (cga->cgamode & 1)) { for (x = 0; x < (cga->crtc[1] << 1); x++) @@ -511,7 +705,7 @@ cga_init(cga_t *cga) } void * -cga_standalone_init(const device_t *info) +cga_standalone_init(UNUSED(const device_t *info)) { int display_type; cga_t *cga = malloc(sizeof(cga_t)); @@ -536,6 +730,16 @@ cga_standalone_init(const device_t *info) cga->rgb_type = device_get_config_int("rgb_type"); cga_palette = (cga->rgb_type << 1); cgapal_rebuild(); + update_cga16_color(cga->cgamode); + + cga->double_type = device_get_config_int("double_type"); + + for (uint16_t i = 0; i < 256; i++) { + for (uint16_t j = 0; j < 256; j++) { + interp_lut[0][i][j] = cga_interpolate_srgb(i, j, 0.5); + interp_lut[1][i][j] = cga_interpolate_linear(i, j, 0.5); + } + } return cga; } @@ -556,18 +760,18 @@ cga_pravetz_init(const device_t *info) } void -cga_close(void *p) +cga_close(void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; free(cga->vram); free(cga); } void -cga_speed_changed(void *p) +cga_speed_changed(void *priv) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) priv; cga_recalctimings(cga); } @@ -616,10 +820,10 @@ const device_config_t cga_config[] = { .name = "rgb_type", .description = "RGB type", .type = CONFIG_SELECTION, - .default_int = 0, + .default_int = 5, .selection = { { - .description = "Color", + .description = "Color (generic)", .value = 0 }, { @@ -638,6 +842,37 @@ const device_config_t cga_config[] = { .description = "Color (no brown)", .value = 4 }, + { + .description = "Color (IBM 5153)", + .value = 5 + }, + { + .description = "" + } + } + }, + { + .name = "double_type", + .description = "Line doubling type", + .type = CONFIG_SELECTION, + .default_int = DOUBLE_NONE, + .selection = { + { + .description = "None", + .value = DOUBLE_NONE + }, + { + .description = "Simple doubling", + .value = DOUBLE_SIMPLE + }, + { + .description = "sRGB interpolation", + .value = DOUBLE_INTERPOLATE_SRGB + }, + { + .description = "Linear interpolation", + .value = DOUBLE_INTERPOLATE_LINEAR + }, { .description = "" } @@ -656,7 +891,7 @@ const device_config_t cga_config[] = { // clang-format on const device_t cga_device = { - .name = "CGA", + .name = "IBM CGA", .internal_name = "cga", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index 6ffc5cbcdf..d580f0c06d 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -44,22 +44,22 @@ static const double tau = 6.28318531; /* == 2*pi */ static unsigned char chroma_multiplexer[256] = { // clang-format off - 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, - 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, - 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, - 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, - 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, - 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, - 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, - 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, - 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, - 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, - 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, - 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, - 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, - 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, - 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 + 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, + 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, + 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, + 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, + 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, + 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, + 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, + 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, + 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, + 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, + 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, + 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, + 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, + 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, + 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, + 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 // clang-format on }; @@ -172,7 +172,7 @@ update_cga16_color(uint8_t cgamode) video_sharpness = (int) (sharpness * 256 / 100); } -static Bit8u +static uint8_t byte_clamp(int v) { v >>= 13; @@ -186,21 +186,20 @@ static int temp[SCALER_MAXWIDTH + 10] = { 0 }; static int atemp[SCALER_MAXWIDTH + 2] = { 0 }; static int btemp[SCALER_MAXWIDTH + 2] = { 0 }; -Bit32u * -Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit32u *TempLine) +uint32_t * +Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doublewidth*/, uint32_t *TempLine) { - int x; - Bit32u x2; + uint32_t x2; int w = blocks * 4; - int *o; - Bit32u *rgbi; - int *b; - int *i; - Bit32u *srgb; - int *ap; - int *bp; + int *o; + const uint32_t *rgbi; + const int *b; + int *i; + uint32_t *srgb; + int *ap; + int *bp; #define COMPOSITE_CONVERT(I, Q) \ do { \ @@ -230,21 +229,21 @@ Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewi o = temp; rgbi = TempLine; b = &CGA_Composite_Table[border * 68]; - for (x = 0; x < 4; ++x) + for (uint8_t x = 0; x < 4; ++x) OUT(b[(x + 3) & 3]); OUT(CGA_Composite_Table[(border << 6) | ((*rgbi & 0x0f) << 2) | 3]); - for (x = 0; x < w - 1; ++x) { + for (int x = 0; x < w - 1; ++x) { OUT(CGA_Composite_Table[((rgbi[0] & 0x0f) << 6) | ((rgbi[1] & 0x0f) << 2) | (x & 3)]); ++rgbi; } OUT(CGA_Composite_Table[((*rgbi & 0x0f) << 6) | (border << 2) | 3]); - for (x = 0; x < 5; ++x) + for (uint8_t x = 0; x < 5; ++x) OUT(b[x & 3]); if ((cgamode & 4) != 0) { /* Decode */ i = temp + 5; - srgb = (Bit32u *) TempLine; + srgb = TempLine; for (x2 = 0; x2 < blocks * 4; ++x2) { int c = (i[0] + i[0]) << 3; int d = (i[-1] + i[1]) << 3; @@ -258,7 +257,7 @@ Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewi i = temp + 4; ap = atemp + 1; bp = btemp + 1; - for (x = -1; x < w + 1; ++x) { + for (int x = -1; x < w + 1; ++x) { ap[x] = i[-4] - ((i[-2] - i[0] + i[2]) << 1) + i[4]; bp[x] = (i[-3] - i[-1] + i[1] - i[3]) << 1; ++i; @@ -268,7 +267,7 @@ Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewi i = temp + 5; i[-1] = (i[-1] << 3) - ap[-1]; i[0] = (i[0] << 3) - ap[0]; - srgb = (Bit32u *) TempLine; + srgb = TempLine; for (x2 = 0; x2 < blocks; ++x2) { int y; int a; diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c new file mode 100644 index 0000000000..d91ab1a8b7 --- /dev/null +++ b/src/video/vid_chips_69000.c @@ -0,0 +1,2551 @@ +/* + * 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. + * + * C&T 69000 emulation. + * + * + * + * Authors: Cacodemon345 + * + * Copyright 2023-2024 Cacodemon345 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/pci.h> +#include <86box/thread.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> +#include <86box/plat_unused.h> +#include <86box/bswap.h> +#include + +#pragma pack(push, 1) +typedef struct chips_69000_bitblt_t +{ + /* BR00 - Source and Destination Span Register. */ + uint16_t source_span; + uint16_t destination_span; + + /* BR01 - Pattern/Source Expansion Background Color & Transparency Key Register. */ + uint32_t pattern_source_key_bg; + + /* BR02 - Pattern/Source Expansion Foreground Color Register. */ + uint32_t pattern_source_key_fg; + + /* BR03 - Monochrome Source Control Register. */ + uint8_t monochrome_source_left_clip; + uint8_t monochrome_source_right_clip; + uint8_t monochrome_source_initial_discard; + uint8_t monochrome_source_alignment : 3; + uint8_t monochrome_source_expansion_color_reg_select : 1; + uint8_t dummy_8 : 4; + + /* BR04 - BitBLT Control Register. */ + uint32_t bitblt_control; + + /* BR05 - Pattern Address Register. */ + uint32_t pat_addr; + + /* BR06 - Source Address Register. */ + uint32_t source_addr; + + /* BR07 - Destination Address Register. */ + uint32_t destination_addr; + + /* BR08 - Destination Width & Height Register. */ + uint16_t destination_width; + uint16_t destination_height; + + /* BR09 - Source Expansion Background Color & Transparency Key Register. */ + uint32_t source_key_bg; + + /* BR0A - Source Expansion Foreground Color Register. */ + uint32_t source_key_fg; +} chips_69000_bitblt_t; +#pragma pack(pop) + +typedef struct chips_69000_t { + svga_t svga; + uint8_t pci_conf_status; + uint8_t slot, irq_state; + uint8_t pci_line_interrupt; + uint8_t pci_rom_enable; + uint8_t read_write_bank; + bool engine_active; + bool quit; + thread_t *accel_thread; + event_t *fifo_event, *fifo_data_event; + pc_timer_t decrement_timer; + uint16_t rom_addr; + mem_mapping_t linear_mapping; + uint8_t on_board; + + rgb_t cursor_palette[8]; + uint32_t cursor_pallook[8]; + + uint8_t mm_regs[256], mm_index; + uint8_t flat_panel_regs[256], flat_panel_index; + uint8_t ext_regs[256], ext_index; + + union { + uint32_t mem_regs[4]; + uint16_t mem_regs_w[4 * 2]; + uint8_t mem_regs_b[4 * 4]; + }; + union { + uint32_t bitblt_regs[11]; + uint16_t bitblt_regs_w[11 * 2]; + uint8_t bitblt_regs_b[11 * 4]; + struct chips_69000_bitblt_t bitblt; + }; + + struct + { + struct chips_69000_bitblt_t bitblt; + + uint32_t actual_source_height; + uint32_t actual_destination_height; + + uint32_t actual_destination_width; + + uint32_t count_x, count_y; + int x, y; + int x_dir, y_dir; + + uint8_t bytes_per_pixel; + + /* Byte counter for BitBLT port writes. */ + uint8_t bytes_written; + uint8_t bytes_skip; + uint32_t mono_bytes_pitch; + uint8_t mono_bits_skip_left; + uint32_t bytes_counter; + uint32_t bytes_in_line_written; + uint8_t bytes_port[256]; + } bitblt_running; + + union { + uint16_t subsys_vid; + uint8_t subsys_vid_b[2]; + }; + + union { + uint16_t subsys_pid; + uint8_t subsys_pid_b[2]; + }; + + rom_t bios_rom; + + void* i2c_ddc, *ddc; + + uint8_t st01; +} chips_69000_t; + +/* TODO: Probe timings on real hardware. */ +static video_timings_t timing_chips = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; + +uint8_t chips_69000_readb_linear(uint32_t addr, void *p); +uint16_t chips_69000_readw_linear(uint32_t addr, void *p); +uint32_t chips_69000_readl_linear(uint32_t addr, void *p); +void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p); +void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p); +void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p); + +/* Multimedia handling. */ +uint8_t +chips_69000_read_multimedia(chips_69000_t* chips) +{ + switch (chips->mm_index) { + case 0: + /* Report no playback/capture capability. */ + return 0; + default: + return chips->mm_regs[chips->mm_index]; + } + return chips->mm_regs[chips->mm_index]; +} + +/* Multimedia (write) handling. */ +void +chips_69000_write_multimedia(chips_69000_t* chips, uint8_t val) +{ + switch (chips->mm_index) { + case 0: + return; + default: + chips->mm_regs[chips->mm_index] = val; + break; + } + chips->mm_regs[chips->mm_index] = val; +} + +/* Flat panel handling. */ +uint8_t +chips_69000_read_flat_panel(chips_69000_t* chips) +{ + switch (chips->flat_panel_index) { + case 0: + return 1; + default: + return chips->flat_panel_regs[chips->flat_panel_index]; + } + return chips->flat_panel_regs[chips->flat_panel_index]; +} + +/* Flat panel (write) handling. */ +void +chips_69000_write_flat_panel(chips_69000_t* chips, uint8_t val) +{ + switch (chips->flat_panel_index) { + case 0: + return; + case 1: + case 0x20 ... 0x33: + case 0x35: + case 0x36: + chips->flat_panel_regs[chips->flat_panel_index] = val; + svga_recalctimings(&chips->svga); + return; + default: + chips->flat_panel_regs[chips->flat_panel_index] = val; + break; + } + chips->flat_panel_regs[chips->flat_panel_index] = val; +} + +void +chips_69000_interrupt(chips_69000_t* chips) +{ + pci_irq(chips->slot, PCI_INTA, 0, !!((chips->mem_regs[0] & chips->mem_regs[1]) & 0x80004040), &chips->irq_state); +} + +void +chips_69000_bitblt_interrupt(chips_69000_t* chips) +{ + chips->engine_active = 0; + chips->mem_regs[1] |= 1 << 31; + + chips_69000_interrupt(chips); +} + +void +chips_69000_do_rop_8bpp(uint8_t *dst, uint8_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_16bpp(uint16_t *dst, uint16_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFFFF; + break; + } +} + +void +chips_69000_do_rop_24bpp(uint32_t *dst, uint32_t src, uint8_t rop) +{ + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x11: + *dst = ~(*dst) & ~src; + break; + case 0x22: + *dst &= ~src; + break; + case 0x33: + *dst = ~src; + break; + case 0x44: + *dst = src & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x66: + *dst ^= src; + break; + case 0x77: + *dst = ~src | ~(*dst); + break; + case 0x88: + *dst &= src; + break; + case 0x99: + *dst ^= ~src; + break; + case 0xAA: + break; /* No-op. */ + case 0xBB: + *dst |= ~src; + break; + case 0xCC: + *dst = src; + break; + case 0xDD: + *dst = src | ~(*dst); + break; + case 0xEE: + *dst |= src; + break; + case 0xFF: + *dst = 0xFFFFFF; + break; + } +} + +void +chips_69000_do_rop_8bpp_patterned(uint8_t *dst, uint8_t pattern, uint8_t src, uint8_t rop) +{ + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_8bpp(dst, src, rop); + } + + switch (rop) { + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~pattern; + break; + case 0x0A: + *dst &= ~pattern; + break; + case 0x0F: + *dst = ~pattern; + break; + case 0x1A: + *dst = pattern ^ (*dst | (pattern & src)); + break; + case 0x2A: + *dst = *dst & (~(src & pattern)); + break; + case 0x3A: + *dst = src ^ (pattern | (*dst ^ src)); + break; + case 0x4A: + *dst = *dst ^ (pattern & (src | *dst)); + break; + case 0x50: + *dst = pattern & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= pattern; + break; + case 0x5F: + *dst = ~pattern | ~(*dst); + break; + case 0x6A: + *dst = *dst ^ (pattern & src); + break; + case 0x7A: + *dst = *dst ^ (pattern & (src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (src | (~pattern)); + break; + case 0x9A: + *dst = *dst ^ (pattern & (~src)); + break; + case 0xB8: + *dst = (((pattern ^ *dst) & src) ^ pattern); + break; + case 0xA0: + *dst &= pattern; + break; + case 0xA5: + *dst ^= ~pattern; + break; + case 0xAA: + break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; + case 0xAF: + *dst |= ~pattern; + break; + case 0xBA: + *dst |= (pattern & ~src); + break; + case 0xCA: + *dst ^= (pattern & (src ^ *dst)); + break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; + case 0xDA: + *dst ^= pattern & (~(src & *dst)); + break; + case 0xEA: + *dst |= pattern & src; + break; + case 0xF0: + *dst = pattern; + break; + case 0xF5: + *dst = pattern | ~(*dst); + break; + case 0xFA: + *dst |= pattern; + break; + case 0xFF: + *dst = 0xFF; + break; + default: + pclog("Unknown ROP 0x%X\n", rop); + break; + } +} + +void +chips_69000_do_rop_16bpp_patterned(uint16_t *dst, uint16_t pattern, uint16_t src, uint8_t rop) +{ + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_16bpp(dst, src, rop); + } + + switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~pattern; + break; + case 0x0A: + *dst &= ~pattern; + break; + case 0x0F: + *dst = ~pattern; + break; + case 0x1A: + *dst = pattern ^ (*dst | (pattern & src)); + break; + case 0x2A: + *dst = *dst & (~(src & pattern)); + break; + case 0x3A: + *dst = src ^ (pattern | (*dst ^ src)); + break; + case 0x4A: + *dst = *dst ^ (pattern & (src | *dst)); + break; + case 0x50: + *dst = pattern & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= pattern; + break; + case 0x5F: + *dst = ~pattern | ~(*dst); + break; + case 0x6A: + *dst = *dst ^ (pattern & src); + break; + case 0x7A: + *dst = *dst ^ (pattern & (src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (src | (~pattern)); + break; + case 0x9A: + *dst = *dst ^ (pattern & (~src)); + break; + case 0xB8: + *dst = (((pattern ^ *dst) & src) ^ pattern); + break; + case 0xA0: + *dst &= pattern; + break; + case 0xA5: + *dst ^= ~pattern; + break; + case 0xAA: + break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; + case 0xAF: + *dst |= ~pattern; + break; + case 0xBA: + *dst |= (pattern & ~src); + break; + case 0xCA: + *dst ^= (pattern & (src ^ *dst)); + break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; + case 0xDA: + *dst ^= pattern & (~(src & *dst)); + break; + case 0xEA: + *dst |= pattern & src; + break; + case 0xF0: + *dst = pattern; + break; + case 0xF5: + *dst = pattern | ~(*dst); + break; + case 0xFA: + *dst |= pattern; + break; + case 0xFF: + *dst = 0xFF; + break; + } +} + +void +chips_69000_do_rop_24bpp_patterned(uint32_t *dst, uint32_t pattern, uint32_t src, uint8_t rop) +{ + uint32_t orig_dst = *dst & 0xFF000000; + + if ((rop & 0xF) == ((rop >> 4) & 0xF)) { + return chips_69000_do_rop_24bpp(dst, src, rop); + } + + switch (rop) { + default: + pclog("Unknown ROP 0x%X\n", rop); + break; + case 0x00: + *dst = 0; + break; + case 0x05: + *dst = ~(*dst) & ~pattern; + break; + case 0x0A: + *dst &= ~pattern; + break; + case 0x0F: + *dst = ~pattern; + break; + case 0x1A: + *dst = pattern ^ (*dst | (pattern & src)); + break; + case 0x2A: + *dst = *dst & (~(src & pattern)); + break; + case 0x3A: + *dst = src ^ (pattern | (*dst ^ src)); + break; + case 0x4A: + *dst = *dst ^ (pattern & (src | *dst)); + break; + case 0x50: + *dst = pattern & ~(*dst); + break; + case 0x55: + *dst = ~*dst; + break; + case 0x5A: + *dst ^= pattern; + break; + case 0x5F: + *dst = ~pattern | ~(*dst); + break; + case 0x6A: + *dst = *dst ^ (pattern & src); + break; + case 0x7A: + *dst = *dst ^ (pattern & (src | (~*dst))); + break; + case 0x8A: + *dst = *dst & (src | (~pattern)); + break; + case 0x9A: + *dst = *dst ^ (pattern & (~src)); + break; + case 0xB8: + *dst = (((pattern ^ *dst) & src) ^ pattern); + break; + case 0xA0: + *dst &= pattern; + break; + case 0xA5: + *dst ^= ~pattern; + break; + case 0xAA: + break; /* No-op. */ + case 0xAC: + *dst = src ^ (pattern & (*dst ^ src)); + break; + case 0xAF: + *dst |= ~pattern; + break; + case 0xBA: + *dst |= (pattern & ~src); + break; + case 0xCA: + *dst ^= (pattern & (src ^ *dst)); + break; + case 0xDA: + *dst ^= pattern & (~(src & *dst)); + break; + case 0xE2: + *dst ^= (src & (pattern ^ *dst)); + break; + case 0xEA: + *dst |= pattern & src; + break; + case 0xF0: + *dst = pattern; + break; + case 0xF5: + *dst = pattern | ~(*dst); + break; + case 0xFA: + *dst |= pattern; + break; + case 0xFF: + *dst = 0xFF; + break; + } + *dst &= 0xFFFFFF; + *dst |= orig_dst; +} + +void +chips_69000_recalctimings(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->priv); + + if (chips->ext_regs[0x81] & 0x10) { + svga->htotal -= 5; + } + + if (((chips->ext_regs[0x61] & 0x8) && !(chips->ext_regs[0x61] & 0x4)) + || ((chips->ext_regs[0x61] & 0x2) && !(chips->ext_regs[0x61] & 0x1))) { + svga->dpms = 1; + } else + svga->dpms = 0; + + if (chips->ext_regs[0x09] & 0x1) { + svga->vtotal -= 2; + svga->vtotal &= 0xFF; + svga->vtotal |= (svga->crtc[0x30] & 0xF) << 8; + svga->vtotal += 2; + + svga->dispend--; + svga->dispend &= 0xFF; + svga->dispend |= (svga->crtc[0x31] & 0xF) << 8; + svga->dispend++; + + svga->vsyncstart--; + svga->vsyncstart &= 0xFF; + svga->vsyncstart |= (svga->crtc[0x32] & 0xF) << 8; + svga->vsyncstart++; + + svga->vblankstart--; + svga->vblankstart &= 0xFF; + svga->vblankstart |= (svga->crtc[0x33] & 0xF) << 8; + svga->vblankstart++; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal -= 5; + + svga->htotal |= (svga->crtc[0x38] & 0x1) << 8; + + if (!(chips->ext_regs[0x81] & 0x10)) + svga->htotal += 5; + + svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); + svga->hblank_end_mask = 0xff; + + svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; + svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; + + svga->interlace = !!(svga->crtc[0x70] & 0x80); + + if (svga->hdisp == 1280 && svga->dispend == 1024) { + svga->interlace = 0; + } + + switch (chips->ext_regs[0x81] & 0xF) { + default: + svga->bpp = 8; + break; + case 0b0010: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; + + case 0b0100: + svga->bpp = 15; + svga->render = svga_render_15bpp_highres; + break; + case 0b0101: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + case 0b0110: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + case 0b0111: + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + break; + } +#if 1 + if (chips->flat_panel_regs[0x01] & 0x2) { + /* TODO: Fix horizontal parameter calculations. */ + if (svga->hdisp > (((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3)) { + svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + svga->hoverride = 1; + } else + svga->hoverride = 0; + + if (svga->dispend > (((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1))) { + svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + } + //svga->hdisp = ((chips->flat_panel_regs[0x20] | ((chips->flat_panel_regs[0x25] & 0xF) << 8)) + 1) << 3; + //svga->htotal = ((chips->flat_panel_regs[0x23] | ((chips->flat_panel_regs[0x26] & 0xF) << 8)) + 5) << 3; + //svga->hblank_end_val = svga->htotal - 1; + //svga->dispend = svga->vsyncstart = svga->vblankstart = ((chips->flat_panel_regs[0x30] | ((chips->flat_panel_regs[0x35] & 0xF) << 8)) + 1); + //svga->vsyncstart = ((chips->flat_panel_regs[0x31] | ((chips->flat_panel_regs[0x35] & 0xF0) << 4)) + 1); + //svga->vtotal = ((chips->flat_panel_regs[0x33] | ((chips->flat_panel_regs[0x36] & 0xF) << 8)) + 2); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((chips->flat_panel_regs[0x03] >> 2) & 3, svga->priv); + } else { + svga->hoverride = 0; + } +#endif + } else { + svga->bpp = 8; + svga->hoverride = 0; + } +} + +void +chips_69000_decrement_timer(void* p) +{ + chips_69000_t *chips = (chips_69000_t*)p; + + chips->ext_regs[0xD2]--; + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); +} + +void +chips_69000_recalc_banking(chips_69000_t *chips) +{ + svga_t* svga = &chips->svga; + chips->svga.read_bank = chips->svga.write_bank = 0; + + svga->chain2_write = !(svga->seqregs[0x4] & 4); + svga->chain4 = (svga->seqregs[0x4] & 8) || (chips->ext_regs[0xA] & 0x4); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + + if (chips->ext_regs[0xA] & 1) { + chips->svga.read_bank = chips->svga.write_bank = 0x10000 * (chips->ext_regs[0xE] & 0x7f); + } + + /*if (chips->ext_regs[0x40] & 2) { + svga->decode_mask = (1 << 18) - 1; + } else { + svga->decode_mask = (1 << 21) - 1; + }*/ +} + +void +chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) +{ + uint32_t pattern_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t pattern_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + uint8_t pattern_data = 0; + uint32_t pattern_pixel = 0; + uint32_t dest_pixel = 0; + uint32_t dest_addr = chips->bitblt_running.bitblt.destination_addr + (chips->bitblt_running.y * chips->bitblt_running.bitblt.destination_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + uint8_t vert_pat_alignment = (chips->bitblt_running.bitblt.bitblt_control >> 20) & 7; + uint8_t orig_dest_addr_bit = chips->bitblt_running.bitblt.destination_addr & 1; + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + dest_pixel = chips_69000_readb_linear(dest_addr, chips); + dest_pixel |= chips_69000_readb_linear(dest_addr + 1, chips) << 8; + dest_pixel |= chips_69000_readb_linear(dest_addr + 2, chips) << 16; + break; + } + } + + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr >>= 1; + } + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) { + uint8_t is_true = 0; + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 19)) + pattern_data = 0; + else + pattern_data = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + ((vert_pat_alignment + (chips->bitblt_running.y & 7)) & 7), chips); + + is_true = !!(pattern_data & (1 << (7 - ((chips->bitblt_running.bitblt.destination_addr + chips->bitblt_running.x) & 7)))); + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 17))) { + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } + return; + } + + pattern_pixel = is_true ? pattern_fg : pattern_bg; + + pattern_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + } else { + if (chips->bitblt_running.bytes_per_pixel == 1) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7) + + (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7), chips); + } + if (chips->bitblt_running.bytes_per_pixel == 2) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (2 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (2 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; + } + if (chips->bitblt_running.bytes_per_pixel == 3) { + pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; + + pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) + + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; + } + } + if (chips->bitblt_running.bytes_per_pixel == 2) { + chips->bitblt_running.bitblt.destination_addr <<= 1; + chips->bitblt_running.bitblt.destination_addr |= orig_dest_addr_bit; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 1: + case 3: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_do_rop_8bpp_patterned((uint8_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_do_rop_16bpp_patterned((uint16_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_do_rop_24bpp_patterned((uint32_t*)&dest_pixel, pattern_pixel, pixel, chips->bitblt_running.bitblt.bitblt_control & 0xFF); + break; + } + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 14)) { + switch ((chips->bitblt_running.bitblt.bitblt_control >> 15) & 3) { + case 0: + case 2: + { + uint32_t color_key = (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) + ? chips->bitblt_running.bitblt.source_key_bg + : chips->bitblt_running.bitblt.pattern_source_key_bg; + color_key &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + dest_pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + if (!!(color_key == dest_pixel) == !!(chips->bitblt_running.bitblt.bitblt_control & (1 << 16))) { + return; + } + + break; + } + } + } + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + break; + } + case 3: /* 24 bits-per-pixel. */ + { + chips_69000_writeb_linear(dest_addr, dest_pixel & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 1, (dest_pixel >> 8) & 0xFF, chips); + chips_69000_writeb_linear(dest_addr + 2, (dest_pixel >> 16) & 0xFF, chips); + break; + } + } +} + +void +chips_69000_process_mono_bit(chips_69000_t* chips, uint8_t val) +{ + uint32_t pixel = 0x0; + uint8_t is_true = !!val; + uint32_t source_fg = chips->bitblt_running.bitblt.pattern_source_key_fg; + uint32_t source_bg = chips->bitblt_running.bitblt.pattern_source_key_bg; + + if (!chips->engine_active) + return; + + if (chips->bitblt_running.bitblt.monochrome_source_expansion_color_reg_select) { + source_fg = chips->bitblt_running.bitblt.source_key_fg; + source_bg = chips->bitblt_running.bitblt.source_key_bg; + } + + if (chips->bitblt_running.bitblt.monochrome_source_initial_discard) { + chips->bitblt_running.bitblt.monochrome_source_initial_discard--; + return; + } + + if (chips->bitblt_running.mono_bits_skip_left) { + chips->bitblt_running.mono_bits_skip_left--; + return; + } + + if (!is_true && (chips->bitblt_running.bitblt.bitblt_control & (1 << 13))) { + goto advance; + } + pixel = is_true ? source_fg : source_bg; + pixel &= (1 << (8 * (chips->bitblt_running.bytes_per_pixel))) - 1; + + chips_69000_process_pixel(chips, pixel); + +advance: + chips->bitblt_running.x += chips->bitblt_running.x_dir; + chips->bitblt_running.count_x += 1; + if (chips->bitblt_running.count_x >= chips->bitblt_running.actual_destination_width) { + chips->bitblt_running.count_y += 1; + chips->bitblt_running.y += chips->bitblt_running.y_dir * 1; + chips->bitblt_running.count_x = 0; + chips->bitblt_running.x = 0; + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + if (chips->bitblt_running.count_y >= (chips->bitblt_running.actual_destination_height)) + chips_69000_bitblt_interrupt(chips); + } +} + +void chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data); + +void +chips_69000_setup_bitblt(chips_69000_t* chips) +{ + chips->engine_active = 1; + + memset(&chips->bitblt_running, 0, sizeof(chips->bitblt_running)); + chips->bitblt_running.bitblt = chips->bitblt; + chips->bitblt_running.actual_source_height = chips->bitblt.destination_height; + chips->bitblt_running.actual_destination_height = chips->bitblt.destination_height; + chips->bitblt_running.count_x = chips->bitblt_running.count_y = 0; + chips->bitblt_running.bytes_written = 0; + chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.bytes_in_line_written = 0; + chips->bitblt_running.bytes_skip = 0; + chips->bitblt_running.mono_bytes_pitch = 0; + chips->bitblt_running.mono_bits_skip_left = 0; + int orig_cycles = cycles; + + if (chips->bitblt.bitblt_control & (1 << 23)) { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->bitblt.bitblt_control >> 24) & 3); + } else { + chips->bitblt_running.bytes_per_pixel = 1 + ((chips->ext_regs[0x20] >> 4) & 3); + } + + chips->bitblt_running.actual_destination_width = chips->bitblt_running.bitblt.destination_width / chips->bitblt_running.bytes_per_pixel; + + chips->bitblt_running.x = 0; + chips->bitblt_running.y = 0; + + switch ((chips->bitblt_running.bitblt.bitblt_control >> 8) & 3) { + case 0: + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = 1; + break; + case 1: + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = 1; + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + break; + case 2: + chips->bitblt_running.x_dir = 1; + chips->bitblt_running.y_dir = -1; + break; + case 3: + chips->bitblt_running.x_dir = -1; + chips->bitblt_running.y_dir = -1; + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 10))) + chips->bitblt_running.bitblt.source_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + chips->bitblt_running.bitblt.destination_addr -= (chips->bitblt_running.bytes_per_pixel - 1); + break; + } + + /* Drawing is pointless if monochrome pattern is enabled, monochrome write-masking is enabled and solid pattern is enabled. */ + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 17)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 18)) + && (chips->bitblt_running.bitblt.bitblt_control & (1 << 19))) { + chips_69000_bitblt_interrupt(chips); + return; + } + +#if 0 + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + pclog("C&T: Monochrome blit (monochrome_source_alignment = %d, " + "monochrome left clip = %d, " + "monochrome right clip = %d, " + "monochrome initial discard = %d, " + "destination_width = %d, destination_height = %d)\n", chips->bitblt_running.bitblt.monochrome_source_alignment, + chips->bitblt_running.bitblt.monochrome_source_left_clip, + chips->bitblt_running.bitblt.monochrome_source_right_clip, + chips->bitblt_running.bitblt.monochrome_source_initial_discard, + chips->bitblt_running.bitblt.destination_width, + chips->bitblt_running.bitblt.destination_height); + } +#endif + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 10)) { + chips->bitblt_running.bitblt.source_addr &= 7; + if (!(chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + /* Yes, the NT 4.0 and Linux drivers will send this many amount of bytes to the video adapter on quadword-boundary-crossing image blits. + This weird calculation is intended and deliberate. + */ + if ((chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.bitblt.destination_width)) > ((chips->bitblt_running.bitblt.destination_width + 7) & ~7)) + chips->bitblt_running.bytes_skip = 8 + (((chips->bitblt_running.bitblt.destination_width + 7) & ~7) - chips->bitblt_running.bitblt.destination_width); + } else { + chips->bitblt_running.mono_bits_skip_left = chips->bitblt_running.bitblt.monochrome_source_left_clip; + + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5) + chips->bitblt_running.bitblt.monochrome_source_alignment = 0; + + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0) { + chips->bitblt_running.mono_bytes_pitch = ((chips->bitblt_running.actual_destination_width + chips->bitblt_running.bitblt.monochrome_source_left_clip + 63) & ~63) / 8; + } + } + + return; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr; + + while (chips->engine_active) { + switch (chips->bitblt_running.bitblt.monochrome_source_alignment) { + case 0: /* Source-span aligned. */ + { + /* Note: This value means quadword-alignment when BitBLT port is the source. */ + /* TODO: This is handled purely on a best case basis. */ + uint32_t orig_count_y = chips->bitblt_running.count_y; + uint32_t orig_source_addr = chips->bitblt_running.bitblt.source_addr; + while (orig_count_y == chips->bitblt_running.count_y) { + int i = 0; + uint8_t data = chips_69000_readb_linear(orig_source_addr, chips); + orig_source_addr++; + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(data & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + break; + } + } + if ((source_addr + chips->bitblt_running.bitblt.source_span) == orig_source_addr) + break; + } + + source_addr = chips->bitblt_running.bitblt.source_addr + chips->bitblt_running.bitblt.source_span; + chips->bitblt_running.bitblt.source_addr = source_addr; + break; + } + case 1: /* Bit-aligned */ + case 2: /* Byte-aligned */ + { + uint32_t data = chips_69000_readb_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + source_addr += 1; + break; + } + case 3: /* Word-aligned*/ + { + uint32_t data = chips_69000_readw_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + source_addr += 2; + break; + } + case 4: /* Doubleword-aligned*/ + { + uint32_t data = chips_69000_readl_linear(source_addr, chips); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + source_addr += 4; + break; + } + case 5: /* Quadword-aligned*/ + { + uint64_t data = (uint64_t)chips_69000_readl_linear(source_addr, chips) | ((uint64_t)chips_69000_readl_linear(source_addr + 4, chips) << 32ull); + chips_69000_bitblt_write(chips, data & 0xFF); + chips_69000_bitblt_write(chips, (data >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 24) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 32ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 40ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 48ull) & 0xFF); + chips_69000_bitblt_write(chips, (data >> 56ull) & 0xFF); + source_addr += 8; + break; + } + } + } + return; + } + + do { + do { + uint32_t pixel = 0; + uint32_t source_addr = chips->bitblt_running.bitblt.source_addr + (chips->bitblt_running.y * chips->bitblt.source_span) + (chips->bitblt_running.x * chips->bitblt_running.bytes_per_pixel); + + switch (chips->bitblt_running.bytes_per_pixel) { + case 1: /* 8 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + break; + } + case 2: /* 16 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + break; + } + case 3: /* 24 bits-per-pixel. */ + { + pixel = chips_69000_readb_linear(source_addr, chips); + pixel |= chips_69000_readb_linear(source_addr + 1, chips) << 8; + pixel |= chips_69000_readb_linear(source_addr + 2, chips) << 16; + break; + } + } + + chips_69000_process_pixel(chips, pixel); + + chips->bitblt_running.x += chips->bitblt_running.x_dir; + } while ((++chips->bitblt_running.count_x) < chips->bitblt_running.actual_destination_width); + + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_x = 0; + chips->bitblt_running.x = 0; + } while ((++chips->bitblt_running.count_y) < chips->bitblt_running.actual_destination_height); + cycles = orig_cycles; + chips_69000_bitblt_interrupt(chips); +} + +void +chips_69000_bitblt_write(chips_69000_t* chips, uint8_t data) { + + if (!chips->engine_active) { + return; + } + + if (chips->bitblt_running.bitblt.bitblt_control & (1 << 12)) { + int orig_cycles = cycles; + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bitblt.monochrome_source_alignment == 1) { + uint8_t val = chips->bitblt_running.bytes_port[0]; + int i = 0; + chips->bitblt_running.bytes_written = 0; + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && chips->bitblt_running.mono_bytes_pitch && chips->bitblt_running.mono_bytes_pitch == chips->bitblt_running.bytes_written) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0, j = 0; + chips->bitblt_running.bytes_written = 0; + + for (j = 0; j < chips->bitblt_running.mono_bytes_pitch; j++) { + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(chips->bitblt_running.bytes_port[j] & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } + } + else if ((chips->bitblt_running.bitblt.monochrome_source_alignment == 0 && !chips->bitblt_running.mono_bytes_pitch) + || chips->bitblt_running.bitblt.monochrome_source_alignment == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint8_t val = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 8; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (7 - i)))); + if (orig_count_y != chips->bitblt_running.count_y && chips->bitblt_running.bitblt.monochrome_source_alignment != 1) { + cycles = orig_cycles; + return; + } + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 3 + && chips->bitblt_running.bytes_written == 2) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint16_t val = (chips->bitblt_running.bytes_port[1]) | (chips->bitblt_running.bytes_port[0] << 8); + chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 16; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (15 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 4 + && chips->bitblt_running.bytes_written == 4) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint32_t val = chips->bitblt_running.bytes_port[3] | (chips->bitblt_running.bytes_port[2] << 8) | (chips->bitblt_running.bytes_port[1] << 16) | (chips->bitblt_running.bytes_port[0] << 24); + chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 32; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (31 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } else if (chips->bitblt_running.bitblt.monochrome_source_alignment == 5 && chips->bitblt_running.bytes_written == 8) { + int orig_count_y = chips->bitblt_running.count_y; + int i = 0; + uint64_t val = 0; + + val |= chips->bitblt_running.bytes_port[7]; + val |= chips->bitblt_running.bytes_port[6] << 8; + val |= chips->bitblt_running.bytes_port[5] << 16; + val |= chips->bitblt_running.bytes_port[4] << 24; + val |= (uint64_t)chips->bitblt_running.bytes_port[3] << 32ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[2] << 40ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[1] << 48ULL; + val |= (uint64_t)chips->bitblt_running.bytes_port[0] << 56ULL; + + chips->bitblt_running.bytes_written = 0; + + for (i = 0; i < 64; i++) { + chips_69000_process_mono_bit(chips, !!(val & (1 << (63 - i)))); + if (orig_count_y != chips->bitblt_running.count_y) { + cycles = orig_cycles; + return; + } + } + } + cycles = orig_cycles; + return; + } + + chips->bitblt_running.bytes_counter++; + if (chips->bitblt_running.bytes_counter <= (chips->bitblt_running.bitblt.source_addr)) { + return; + } + chips->bitblt_running.bytes_port[chips->bitblt_running.bytes_written++] = data; + if (chips->bitblt_running.bytes_written == chips->bitblt_running.bytes_per_pixel) { + int orig_cycles = cycles; + uint32_t source_pixel = chips->bitblt_running.bytes_port[0]; + chips->bitblt_running.bytes_written = 0; + if (chips->bitblt_running.bytes_per_pixel >= 2) + source_pixel |= (chips->bitblt_running.bytes_port[1] << 8); + if (chips->bitblt_running.bytes_per_pixel >= 3) + source_pixel |= (chips->bitblt_running.bytes_port[2] << 16); + + chips->bitblt_running.bytes_in_line_written += chips->bitblt_running.bytes_per_pixel; + + chips_69000_process_pixel(chips, source_pixel); + cycles = orig_cycles; + chips->bitblt_running.x += chips->bitblt_running.x_dir; + + if (chips->bitblt_running.bytes_in_line_written >= chips->bitblt_running.bitblt.destination_width) { + if (chips->bitblt_running.bytes_skip) { + chips->bitblt_running.bitblt.source_addr = chips->bitblt_running.bytes_skip; + } + else if (chips->bitblt_running.bitblt.destination_width & 7) + chips->bitblt_running.bitblt.source_addr = 8 - ((chips->bitblt_running.bitblt.destination_width) & 7); + else + chips->bitblt_running.bitblt.source_addr = 0; + + chips->bitblt_running.y += chips->bitblt_running.y_dir; + chips->bitblt_running.count_y++; + chips->bitblt_running.bytes_counter = 0; + chips->bitblt_running.bytes_in_line_written = 0; + + chips->bitblt_running.count_x = 0; + chips->bitblt_running.x = 0; + + if (chips->bitblt_running.count_y >= chips->bitblt_running.actual_destination_height) { + chips_69000_bitblt_interrupt(chips); + return; + } + } + } +} + +uint8_t +chips_69000_read_ext_reg(chips_69000_t* chips) +{ + uint8_t index = chips->ext_index; + uint8_t val = chips->ext_regs[index]; + switch (index) { + case 0x00: + val = 0x2C; + break; + case 0x01: + val = 0x10; + break; + case 0x02: + val = 0xC0; + break; + case 0x03: + val = 0x00; + break; + case 0x04: + val = 0x62; + break; + case 0x05: + val = 0x00; + break; + case 0x06: + val = chips->linear_mapping.base >> 24; + break; + case 0x08: + val = 0x02; + break; + case 0x0A: + val = chips->ext_regs[index] & 0x37; + break; + case 0x20: + val &= ~1; + val |= !!chips->engine_active; + /* TODO: Handle BitBLT reset, if required. */ + break; + case 0x63: + { + val = chips->ext_regs[index]; + if (!(chips->ext_regs[0x62] & 0x8)) + val = (val & ~8) | (i2c_gpio_get_scl(chips->i2c_ddc) << 3); + + if (!(chips->ext_regs[0x62] & 0x4)) + val = (val & ~4) | (i2c_gpio_get_sda(chips->i2c_ddc) << 2); + + break; + } + case 0x70: + val = 0x3; + break; + case 0x71: + val = 0b01101000; + break; + case 0xD0: + val |= 1; + break; + } + return val; +} + +void +chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) +{ + switch (chips->ext_index) { + case 0xA: + chips->ext_regs[chips->ext_index] = val & 0x37; + chips_69000_recalc_banking(chips); + break; + case 0xB: + chips->ext_regs[chips->ext_index] = val & 0xD; + break; + case 0xE: + chips->ext_regs[chips->ext_index] = val & 0x7f; + chips_69000_recalc_banking(chips); + break; + case 0x9: + chips->ext_regs[chips->ext_index] = val & 0x3; + svga_recalctimings(&chips->svga); + break; + case 0x40: + chips->ext_regs[chips->ext_index] = val & 0x3; + chips_69000_recalc_banking(chips); + svga_recalctimings(&chips->svga); + break; + case 0x60: + chips->ext_regs[chips->ext_index] = val & 0x43; + break; + case 0x20: + chips->ext_regs[chips->ext_index] = val & 0x3f; + break; + case 0x61: + chips->ext_regs[chips->ext_index] = val & 0x7f; + svga_recalctimings(&chips->svga); + break; + case 0x62: + chips->ext_regs[chips->ext_index] = val & 0x9C; + break; + case 0x63: + { + uint8_t scl = 0, sda = 0; + if (chips->ext_regs[0x62] & 0x8) + scl = !!(val & 8); + else + scl = i2c_gpio_get_scl(chips->i2c_ddc); + + if (chips->ext_regs[0x62] & 0x4) + sda = !!(val & 4); + else + scl = i2c_gpio_get_sda(chips->i2c_ddc); + + i2c_gpio_set(chips->i2c_ddc, scl, sda); + + chips->ext_regs[chips->ext_index] = val & 0x9F; + break; + } + case 0x67: + chips->ext_regs[chips->ext_index] = val & 0x2; + break; + case 0x80: + chips->ext_regs[chips->ext_index] = val & 0xBF; + svga_set_ramdac_type(&chips->svga, (val & 0x80) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; + case 0x81: + chips->ext_regs[chips->ext_index] = val & 0x1f; + svga_recalctimings(&chips->svga); + break; + case 0x82: + chips->ext_regs[chips->ext_index] = val & 0xf; + chips->svga.lut_map = !!(val & 0x8); + break; + case 0xA0: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.ena = ((val & 7) == 0b101) || ((val & 7) == 0b1); + chips->svga.hwcursor.cur_xsize = chips->svga.hwcursor.cur_ysize = ((val & 7) == 0b1) ? 32 : 64; + break; + case 0xA2: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = (val << 8) | ((chips->ext_regs[0xA3] & 0x3F) << 16); + break; + case 0xA3: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.addr = ((chips->ext_regs[0xA2]) << 8) | ((val & 0x3F) << 16); + break; + case 0xA4: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = val | (chips->ext_regs[0xA5] & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; + break; + case 0xA5: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.x = chips->ext_regs[0xA4] | (val & 7) << 8; + if (chips->ext_regs[0xA5] & 0x80) + chips->svga.hwcursor.x = -chips->svga.hwcursor.x; + break; + case 0xA6: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = val | (chips->ext_regs[0xA7] & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + } + break; + case 0xA7: + chips->ext_regs[chips->ext_index] = val; + chips->svga.hwcursor.y = chips->ext_regs[0xA6] | (val & 7) << 8; + if (chips->ext_regs[0xA7] & 0x80) { + chips->svga.hwcursor.y = -chips->svga.hwcursor.y; + } + break; + case 0xC8: + case 0xC9: + case 0xCB: + chips->ext_regs[chips->ext_index] = val; + svga_recalctimings(&chips->svga); + break; + case 0xD2: + break; + default: + chips->ext_regs[chips->ext_index] = val; + break; + } +} + +void +chips_69000_out(uint16_t addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t old, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c0: + if (!(chips->ext_regs[0x09] & 0x02)) + break; + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + return; + case 0x3c1: + if ((chips->ext_regs[0x09] & 0x02)) + { + svga->attrff = 1; + svga_out(addr, val, svga); + svga->attrff = 0; + return; + } + break; + case 0x3c9: + if (!(chips->ext_regs[0x80] & 0x01)) + break; + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = svga->monitor->mon_changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 7; + chips->cursor_palette[index].r = svga->dac_r; + chips->cursor_palette[index].g = svga->dac_g; + chips->cursor_palette[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + chips->cursor_pallook[index] = makecol32(chips->cursor_palette[index].r, chips->cursor_palette[index].g, chips->cursor_palette[index].b); + else + chips->cursor_pallook[index] = makecol32(video_6to8[chips->cursor_palette[index].r & 0x3f], video_6to8[chips->cursor_palette[index].g & 0x3f], video_6to8[chips->cursor_palette[index].b & 0x3f]); + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + } + return; + case 0x3c5: + svga_out(addr, val, svga); + chips_69000_recalc_banking(chips); + return; + case 0x3D0: + chips->flat_panel_index = val; + return; + case 0x3D1: + return chips_69000_write_flat_panel(chips, val); + case 0x3D2: + chips->mm_index = val; + return; + case 0x3D3: + return chips_69000_write_multimedia(chips, val); + case 0x3D4: + svga->crtcreg = val & 0xff; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + case 0x3B6: + case 0x3D6: + chips->ext_index = val; + return; + case 0x3B7: + case 0x3D7: + return chips_69000_write_ext_reg(chips, val); + + } + svga_out(addr, val, svga); +} + +uint8_t +chips_69000_in(uint16_t addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + svga_t *svga = &chips->svga; + uint8_t temp = 0, index; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3C5: + return svga->seqregs[svga->seqaddr]; + case 0x3c9: + if (!(chips->ext_regs[0x80] & 0x01)) { + temp = svga_in(addr, svga); + break; + } + index = (svga->dac_addr - 1) & 7; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].r; + else + temp = chips->cursor_palette[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].g; + else + temp = chips->cursor_palette[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = chips->cursor_palette[index].b; + else + temp = chips->cursor_palette[index].b & 0x3f; + break; + } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + temp >>= 2; + break; + case 0x3D0: + return chips->flat_panel_index; + case 0x3D1: + return chips_69000_read_flat_panel(chips); + case 0x3D2: + return chips->mm_index; + case 0x3D3: + return chips_69000_read_multimedia(chips); + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + case 0x3B6: + case 0x3D6: + temp = chips->ext_index; + break; + case 0x3B7: + case 0x3D7: + temp = chips_69000_read_ext_reg(chips); + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + +static uint8_t +chips_69000_pci_read(int func, int addr, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x00: + return 0x2C; + case 0x01: + return 0x10; + case 0x02: + return 0xC0; + case 0x03: + return 0x00; + case 0x04: + return (chips->pci_conf_status & 0b11100011) | 0x80; + case 0x06: + return 0x80; + case 0x07: + return 0x02; + case 0x08: + case 0x09: + case 0x0a: + return 0x00; + case 0x0b: + return 0x03; + case 0x13: + return chips->linear_mapping.base >> 24; + case 0x30: + return chips->pci_rom_enable & 0x1; + case 0x31: + return 0x0; + case 0x32: + return chips->rom_addr & 0xFF; + case 0x33: + return (chips->rom_addr & 0xFF00) >> 8; + case 0x3c: + return chips->pci_line_interrupt; + case 0x3d: + return 0x01; + case 0x2C: + case 0x2D: + case 0x6C: + case 0x6D: + return (chips->subsys_vid >> ((addr & 1) * 8)) & 0xFF; + case 0x2E: + case 0x2F: + case 0x6E: + case 0x6F: + return (chips->subsys_pid >> ((addr & 1) * 8)) & 0xFF; + default: + return 0x00; + } + } +} + +static void +chips_69000_pci_write(int func, int addr, uint8_t val, void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + { + switch (addr) { + case 0x04: + { + chips->pci_conf_status = val; + io_removehandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + mem_mapping_disable(&chips->linear_mapping); + mem_mapping_disable(&chips->svga.mapping); + if (chips->pci_conf_status & PCI_COMMAND_IO) { + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + } + if (chips->pci_conf_status & PCI_COMMAND_MEM) { + mem_mapping_enable(&chips->svga.mapping); + if (chips->linear_mapping.base) + mem_mapping_enable(&chips->linear_mapping); + } + break; + } + case 0x13: + { + if (!chips->linear_mapping.enable) { + chips->linear_mapping.base = val << 24; + break; + } + mem_mapping_set_addr(&chips->linear_mapping, val << 24, (1 << 24)); + break; + } + case 0x3c: + chips->pci_line_interrupt = val; + break; + case 0x30: + if (chips->on_board) break; + chips->pci_rom_enable = val & 0x1; + mem_mapping_disable(&chips->bios_rom.mapping); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); + } + break; + case 0x32: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF; + chips->rom_addr |= val & 0xFC; + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); + } + break; + case 0x33: + if (chips->on_board) break; + chips->rom_addr &= ~0xFF00; + chips->rom_addr |= (val << 8); + if (chips->pci_rom_enable & 1) { + mem_mapping_set_addr(&chips->bios_rom.mapping, chips->rom_addr << 16, 0x10000); + } + break; + case 0x6C: + case 0x6D: + chips->subsys_vid_b[addr & 1] = val; + break; + case 0x6E: + case 0x6F: + chips->subsys_pid_b[addr & 1] = val; + break; + } + } +} + +uint8_t +chips_69000_readb_mmio(uint32_t addr, chips_69000_t* chips) +{ + addr &= 0xFFF; + switch (addr & 0xFFF) { + case 0x00 ... 0x2B: + if (addr == 0x13) { + return (chips->bitblt_regs_b[addr & 0xFF] & 0x7F) | (chips->engine_active ? 0x80 : 0x00); + } + return chips->bitblt_regs_b[addr & 0xFF]; + case 0x3b: + return (chips->engine_active ? 0x80 : 0x00); + case 0x38: + return 0x7F; + case 0x600 ... 0x60F: + return chips->mem_regs_b[addr & 0xF]; + case 0x768: + return chips_69000_in(0x3b4, chips); + case 0x769: + return chips_69000_in(0x3b5, chips); + case 0x774: + return chips_69000_in(0x3ba, chips); + case 0x780: + return chips_69000_in(0x3c0, chips); + case 0x781: + return chips_69000_in(0x3c1, chips); + case 0x784: + return chips_69000_in(0x3c2, chips); + case 0x788: + return chips_69000_in(0x3c4, chips); + case 0x789: + return chips_69000_in(0x3c5, chips); + case 0x78C: + return chips_69000_in(0x3c6, chips); + case 0x78D: + return chips_69000_in(0x3c7, chips); + case 0x790: + return chips_69000_in(0x3c8, chips); + case 0x791: + return chips_69000_in(0x3c9, chips); + case 0x794: + return chips_69000_in(0x3ca, chips); + case 0x798: + return chips_69000_in(0x3cc, chips); + case 0x79C: + return chips_69000_in(0x3ce, chips); + case 0x79D: + return chips_69000_in(0x3cf, chips); + case 0x7A0: + return chips_69000_in(0x3d0, chips); + case 0x7A1: + return chips_69000_in(0x3d1, chips); + case 0x7A4: + return chips_69000_in(0x3d2, chips); + case 0x7A5: + return chips_69000_in(0x3d3, chips); + case 0x7A8: + return chips_69000_in(0x3d4, chips); + case 0x7A9: + return chips_69000_in(0x3d5, chips); + case 0x7AC: + return chips_69000_in(0x3d6, chips); + case 0x7AD: + return chips_69000_in(0x3d7, chips); + case 0x7B4: + return chips_69000_in(0x3da, chips); + } + return 0x00; +} + +uint16_t +chips_69000_readw_mmio(uint32_t addr, chips_69000_t* chips) +{ + addr &= 0xFFF; + switch (addr & 0xFFF) { + default: + return chips_69000_readb_mmio(addr, chips) | (chips_69000_readb_mmio(addr + 1, chips) << 8); + } + return 0xFFFF; +} + +uint32_t +chips_69000_readl_mmio(uint32_t addr, chips_69000_t* chips) +{ + addr &= 0xFFF; + switch (addr & 0xFFF) { + default: + return chips_69000_readw_mmio(addr, chips) | (chips_69000_readw_mmio(addr + 2, chips) << 16); + } + return 0xFFFFFFFF; +} + +void +chips_69000_writeb_mmio(uint32_t addr, uint8_t val, chips_69000_t* chips) +{ + //pclog("C&T Write 0x%X, val = 0x%02X\n", addr, val); + if (addr & 0x10000) { + chips_69000_bitblt_write(chips, val); + return; + } + addr &= 0xFFF; + switch (addr & 0xFFF) { + case 0x00 ... 0x2B: + if (addr <= 0x3) { + //pclog("[%04X:%08X] C&T Write span 0x%X, val = 0x%02X\n", CS, cpu_state.pc, addr, val); + } + chips->bitblt_regs_b[addr & 0xFF] = val; + if ((addr & 0xFFF) == 0x023 && chips->bitblt_regs[0x8] != 0) { + chips_69000_setup_bitblt(chips); + } + break; + default: + pclog("C&T Write (unknown) 0x%X, val = 0x%02X\n", addr, val); + break; + case 0x600 ... 0x60F: + switch (addr & 0xFFF) + { + case 0x600 ... 0x603: + { + chips->mem_regs_b[addr & 0xF] = val; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x604 ... 0x607: + { + chips->mem_regs_b[addr & 0xF] &= ~val; + chips->mem_regs[(addr >> 2) & 0x3] &= 0x80004040; + if (addr == 0x605 || addr == 0x607) + chips_69000_interrupt(chips); + break; + } + + case 0x60c ... 0x60f: + { + chips->mem_regs_b[addr & 0xF] = val; + break; + } + + } + chips->mem_regs_b[addr & 0xF] = val; + break; + case 0x768: + chips_69000_out(0x3b4, val, chips); break; + case 0x769: + chips_69000_out(0x3b5, val, chips); break; + case 0x774: + chips_69000_out(0x3ba, val, chips); break; + case 0x780: + chips_69000_out(0x3c0, val, chips); break; + case 0x781: + chips_69000_out(0x3c1, val, chips); break; + case 0x784: + chips_69000_out(0x3c2, val, chips); break; + case 0x788: + chips_69000_out(0x3c4, val, chips); break; + case 0x789: + chips_69000_out(0x3c5, val, chips); break; + case 0x78C: + chips_69000_out(0x3c6, val, chips); break; + case 0x78D: + chips_69000_out(0x3c7, val, chips); break; + case 0x790: + chips_69000_out(0x3c8, val, chips); break; + case 0x791: + chips_69000_out(0x3c9, val, chips); break; + case 0x794: + chips_69000_out(0x3ca, val, chips); break; + case 0x798: + chips_69000_out(0x3cc, val, chips); break; + case 0x79C: + chips_69000_out(0x3ce, val, chips); break; + case 0x79D: + chips_69000_out(0x3cf, val, chips); break; + case 0x7A0: + chips_69000_out(0x3d0, val, chips); break; + case 0x7A1: + chips_69000_out(0x3d1, val, chips); break; + case 0x7A4: + chips_69000_out(0x3d2, val, chips); break; + case 0x7A5: + chips_69000_out(0x3d3, val, chips); break; + case 0x7A8: + chips_69000_out(0x3d4, val, chips); break; + case 0x7A9: + chips_69000_out(0x3d5, val, chips); break; + case 0x7AC: + chips_69000_out(0x3d6, val, chips); break; + case 0x7AD: + chips_69000_out(0x3d7, val, chips); break; + case 0x7B4: + chips_69000_out(0x3da, val, chips); break; + } +} + +void +chips_69000_writew_mmio(uint32_t addr, uint16_t val, chips_69000_t* chips) +{ + if (addr & 0x10000) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + //pclog("BitBLT mono 0x%04X\n", val); + } + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + return; + } + addr &= 0xFFF; + switch (addr & 0xFFF) { + default: + chips_69000_writeb_mmio(addr, val, chips); + chips_69000_writeb_mmio(addr + 1, val >> 8, chips); + break; + } +} + +void +chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) +{ + if (addr & 0x10000) { + if ((chips->bitblt_running.bitblt.bitblt_control & (1 << 12))) { + //pclog("BitBLT mono 0x%08X\n", val); + } + chips_69000_bitblt_write(chips, val & 0xFF); + chips_69000_bitblt_write(chips, (val >> 8) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 16) & 0xFF); + chips_69000_bitblt_write(chips, (val >> 24) & 0xFF); + return; + } + addr &= 0xFFF; + switch (addr & 0xFFF) { + default: + chips_69000_writew_mmio(addr, val, chips); + chips_69000_writew_mmio(addr + 2, val >> 16, chips); + break; + } +} + +uint8_t +chips_69000_readb_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x400000) + return chips_69000_readb_mmio(addr, chips); + + return svga_readb_linear(addr & 0x1FFFFF, p); +} + +uint16_t +chips_69000_readw_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap16(chips_69000_readw_mmio(addr, chips)); + + return bswap16(svga_readw_linear(addr & 0x1FFFFF, p)); + } + + if (addr & 0x400000) + return chips_69000_readw_mmio(addr, chips); + + return svga_readw_linear(addr & 0x1FFFFF, p); +} + +uint32_t +chips_69000_readl_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x800000) { + if (addr & 0x400000) + return bswap32(chips_69000_readl_mmio(addr, chips)); + + return bswap32(svga_readl_linear(addr & 0x1FFFFF, p)); + } + + if (addr & 0x400000) + return chips_69000_readl_mmio(addr, chips); + + return svga_readl_linear(addr & 0x1FFFFF, p); +} + +void +chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x400000) + return chips_69000_writeb_mmio(addr, val, chips); + + svga_writeb_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x800000) + val = bswap16(val); + + if (addr & 0x400000) + return chips_69000_writew_mmio(addr, val, chips); + + svga_writew_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + chips_69000_t *chips = (chips_69000_t *) svga->priv; + + if (addr & 0x800000) + val = bswap32(val); + + if (addr & 0x400000) + return chips_69000_writel_mmio(addr, val, chips); + + svga_writel_linear(addr & 0x1FFFFF, val, p); +} + +void +chips_69000_vblank_start(svga_t *svga) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + chips->mem_regs[1] |= 1 << 14; + chips->svga.crtc[0x40] &= ~0x80; + + chips_69000_interrupt(chips); +} + +static void +chips_69000_hwcursor_draw_64x64(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + + for (uint8_t x = 0; x < 64; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + +static void +chips_69000_hwcursor_draw(svga_t *svga, int displine) +{ + chips_69000_t *chips = (chips_69000_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + if ((chips->ext_regs[0xa0] & 7) == 0b101) + return chips_69000_hwcursor_draw_64x64(svga, displine); + + if (svga->interlace) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + if (svga->hwcursor_oddeven) { + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + return; + } + + if ((svga->hwcursor_on & 1)) { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr - 16])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[(svga->hwcursor_latch.addr - 16) + 8])); + dat[1] <<= 32ULL; + dat[0] <<= 32ULL; + } + else { + dat[1] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr])); + dat[0] = bswap64(*(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8])); + svga->hwcursor_latch.addr += 16; + } + + for (uint8_t x = 0; x < 32; x++) { + if (!(dat[1] & (1ULL << 63))) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, chips->cursor_pallook[5]) : svga_lookup_lut_ram(svga, chips->cursor_pallook[4]); + else if (dat[0] & (1ULL << 63)) + svga->monitor->target_buffer->line[displine & 2047][(offset + svga->x_add) & 2047] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } +} + +static float +chips_69000_getclock(int clock, void *priv) +{ + const chips_69000_t *chips = (chips_69000_t *) priv; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + + int m = chips->ext_regs[0xc8]; + int n = chips->ext_regs[0xc9]; + int pl = ((chips->ext_regs[0xcb] >> 4) & 7); + + float fvco = 14318181.0 * ((float)(m + 2) / (float)(n + 2)); + if (chips->ext_regs[0xcb] & 4) + fvco *= 4.0; + float fo = fvco / (float)(1 << pl); + + return fo; +} + +uint32_t +chips_69000_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; +} + +static int +chips_69000_line_compare(svga_t* svga) +{ + const chips_69000_t *chips = (chips_69000_t *) svga->priv; + if (chips->ext_regs[0x81] & 0xF) { + return 0; + } + + return 1; +} + +static void * +chips_69000_init(const device_t *info) +{ + chips_69000_t *chips = calloc(1, sizeof(chips_69000_t)); + + /* Appears to have an odd VBIOS size. */ + if (!info->local) { + rom_init(&chips->bios_rom, "roms/video/chips/69000.ROM", 0xc0000, 0x10000, 0xffff, 0x0000, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&chips->bios_rom.mapping); + } + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_chips); + + svga_init(info, &chips->svga, chips, 1 << 21, /*2048kb*/ + chips_69000_recalctimings, + chips_69000_in, chips_69000_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, chips_69000_in, NULL, NULL, chips_69000_out, NULL, NULL, chips); + + pci_add_card(PCI_ADD_VIDEO, chips_69000_pci_read, chips_69000_pci_write, chips, &chips->slot); + + chips->svga.bpp = 8; + chips->svga.miscout = 1; + chips->svga.recalctimings_ex = chips_69000_recalctimings; + chips->svga.vblank_start = chips_69000_vblank_start; + chips->svga.hwcursor_draw = chips_69000_hwcursor_draw; + chips->svga.getclock = chips_69000_getclock; + chips->svga.conv_16to32 = chips_69000_conv_16to32; + chips->svga.line_compare = chips_69000_line_compare; + + mem_mapping_add(&chips->linear_mapping, 0, 0, chips_69000_readb_linear, chips_69000_readw_linear, chips_69000_readl_linear, chips_69000_writeb_linear, chips_69000_writew_linear, chips_69000_writel_linear, NULL, MEM_MAPPING_EXTERNAL, chips); + + chips->quit = 0; + chips->engine_active = 0; + chips->on_board = !!(info->local); + + chips->svga.packed_chain4 = 1; + + timer_add(&chips->decrement_timer, chips_69000_decrement_timer, chips, 0); + timer_on_auto(&chips->decrement_timer, 1000000. / 2000.); + + chips->i2c_ddc = i2c_gpio_init("c&t_69000_mga"); + chips->ddc = ddc_init(i2c_gpio_get_bus(chips->i2c_ddc)); + + chips->flat_panel_regs[0x01] = 1; + + return chips; +} + +static int +chips_69000_available(void) +{ + return rom_present("roms/video/chips/69000.ROM"); +} + +void +chips_69000_close(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->quit = 1; +// thread_set_event(chips->fifo_event); + // thread_wait(chips->accel_thread); + ddc_close(chips->ddc); + i2c_gpio_close(chips->i2c_ddc); + svga_close(&chips->svga); + + free(chips); +} + +void +chips_69000_speed_changed(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + svga_recalctimings(&chips->svga); +} + +void +chips_69000_force_redraw(void *p) +{ + chips_69000_t *chips = (chips_69000_t *) p; + + chips->svga.fullchange = changeframecount; +} + +const device_t chips_69000_device = { + .name = "Chips & Technologies B69000", + .internal_name = "c&t_69000", + .flags = DEVICE_PCI, + .local = 0, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; + +const device_t chips_69000_onboard_device = { + .name = "Chips & Technologies B69000 (onboard)", + .internal_name = "c&t_69000_onboard", + .flags = DEVICE_PCI, + .local = 1, + .init = chips_69000_init, + .close = chips_69000_close, + .reset = NULL, + { .available = chips_69000_available }, + .speed_changed = chips_69000_speed_changed, + .force_redraw = chips_69000_force_redraw, + .config = NULL +}; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 637598345d..bf27a700aa 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -39,6 +39,8 @@ #include <86box/vid_ddc.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define BIOS_GD5401_PATH "roms/video/cirruslogic/avga1.rom" #define BIOS_GD5402_PATH "roms/video/cirruslogic/avga2.rom" @@ -158,8 +160,9 @@ typedef struct gd54xx_t { svga_t svga; - int has_bios, rev, - bit32; + int has_bios; + int rev; + int bit32; rom_t bios_rom; uint32_t vram_size; @@ -174,61 +177,97 @@ typedef struct gd54xx_t { } ramdac; struct { - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint16_t trans_col, trans_mask; + uint16_t width; + uint16_t height; + uint16_t dst_pitch; + uint16_t src_pitch; + uint16_t trans_col; + uint16_t trans_mask; uint16_t height_internal; - uint16_t msd_buf_pos, msd_buf_cnt; + uint16_t msd_buf_pos; + uint16_t msd_buf_cnt; uint8_t status; - uint8_t mask, mode, rop, modeext; - uint8_t ms_is_dest, msd_buf[32]; - - uint32_t fg_col, bg_col; - uint32_t dst_addr_backup, src_addr_backup; - uint32_t dst_addr, src_addr; - uint32_t sys_src32, sys_cnt; + uint8_t mask; + uint8_t mode; + uint8_t rop; + uint8_t modeext; + uint8_t ms_is_dest; + uint8_t msd_buf[32]; + + uint32_t fg_col; + uint32_t bg_col; + uint32_t dst_addr_backup; + uint32_t src_addr_backup; + uint32_t dst_addr; + uint32_t src_addr; + uint32_t sys_src32; + uint32_t sys_cnt; /* Internal state */ - int pixel_width, pattern_x; - int x_count, y_count; - int xx_count, dir; + int pixel_width; + int pattern_x; + int x_count; + int y_count; + int xx_count; + int dir; int unlock_special; } blt; struct { int mode; - uint16_t stride, r1sz, r1adjust, r2sz, - r2adjust, r2sdz, wvs, wve, - hzoom, vzoom; - uint8_t occlusion, colorkeycomparemask, - colorkeycompare; - int region1size, region2size, - colorkeymode; + uint16_t stride; + uint16_t r1sz; + uint16_t r1adjust; + uint16_t r2sz; + uint16_t r2adjust; + uint16_t r2sdz; + uint16_t wvs; + uint16_t wve; + uint16_t hzoom; + uint16_t vzoom; + uint8_t occlusion; + uint8_t colorkeycomparemask; + uint8_t colorkeycompare; + int region1size; + int region2size; + int colorkeymode; uint32_t ck; } overlay; - int pci, vlb, mca, countminusone; - int vblank_irq, vportsync; + int pci; + int vlb; + int mca; + int countminusone; + int vblank_irq; + int vportsync; uint8_t pci_regs[256]; - uint8_t int_line, unlocked, status, extensions; + uint8_t int_line; + uint8_t unlocked; + uint8_t status; + uint8_t extensions; uint8_t crtcreg_mask; uint8_t fc; /* Feature Connector */ - int card, id; + int id; + + uint8_t pci_slot; + uint8_t irq_state; uint8_t pos_regs[8]; - uint32_t lfb_base, vgablt_base; + uint32_t lfb_base; + uint32_t vgablt_base; int mmio_vram_overlap; uint32_t extpallook[256]; PALETTE extpal; - void *i2c, *ddc; + void *i2c; + void *ddc; } gd54xx_t; static video_timings_t timing_gd54xx_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; @@ -236,19 +275,19 @@ static video_timings_t timing_gd54xx_vlb = { .type = VIDEO_BUS, .write_b = 4, .w static video_timings_t timing_gd54xx_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 8, .read_b = 10, .read_w = 10, .read_l = 20 }; static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); +gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv); static void -gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *p); +gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *priv); static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p); +gd543x_mmio_writew(uint32_t addr, uint16_t val, void *priv); static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p); +gd543x_mmio_writel(uint32_t addr, uint32_t val, void *priv); static uint8_t -gd543x_mmio_read(uint32_t addr, void *p); +gd543x_mmio_read(uint32_t addr, void *priv); static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p); +gd543x_mmio_readw(uint32_t addr, void *priv); static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p); +gd543x_mmio_readl(uint32_t addr, void *priv); static void gd54xx_recalc_banking(gd54xx_t *gd54xx); @@ -484,15 +523,15 @@ gd54xx_update_irqs(gd54xx_t *gd54xx) return; if ((gd54xx->vblank_irq > 0) && gd54xx_vga_vsync_enabled(gd54xx)) - pci_set_irq(gd54xx->card, PCI_INTA); + pci_set_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state); else - pci_clear_irq(gd54xx->card, PCI_INTA); + pci_clear_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state); } static void gd54xx_vblank_start(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->p; + gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; if (gd54xx->vblank_irq >= 0) { gd54xx->vblank_irq = 1; gd54xx_update_irqs(gd54xx); @@ -512,23 +551,23 @@ gd54xx_is_5422(svga_t *svga) static void gd54xx_overlay_draw(svga_t *svga, int displine) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->p; - int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; - int h_acc = svga->overlay_latch.h_acc; - int r[8]; - int g[8]; - int b[8]; - int x_read = 4; - int x_write = 4; - uint32_t *p; - uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; - int bpp = svga->bpp; - int bytesperpix = (bpp + 7) / 8; - uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; - int occl; - int ckval; - - p = &((uint32_t *) svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; + int h_acc = svga->overlay_latch.h_acc; + int r[8]; + int g[8]; + int b[8]; + int x_read = 4; + int x_write = 4; + uint32_t *p; + uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; + int bpp = svga->bpp; + int bytesperpix = (bpp + 7) / 8; + uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; + int occl; + int ckval; + + p = &(svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; src2 += gd54xx->overlay.region1size * bytesperpix; OVERLAY_SAMPLE(); @@ -612,9 +651,26 @@ gd54xx_is_5434(svga_t *svga) } static void -gd54xx_out(uint16_t addr, uint8_t val, void *p) +gd54xx_set_svga_fast(gd54xx_t *gd54xx) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) + svga->fast = ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && + !(svga->adv_flags & FLAG_ADDR_BY8); + /* TODO: needs verification on other Cirrus chips */ + else + svga->fast = ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || + svga->fb_only); +} + +static void +gd54xx_out(uint16_t addr, uint8_t val, void *priv) +{ + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint8_t old; uint8_t o; @@ -753,14 +809,16 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); break; case 0x07: - svga->packed_chain4 = svga->seqregs[7] & 1; - svga_recalctimings(svga); + svga->packed_chain4 = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; if (gd54xx_is_5422(svga)) gd543x_recalc_mapping(gd54xx); else svga->seqregs[svga->seqaddr] &= 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) - svga->set_reset_disabled = svga->seqregs[7] & 1; + svga->set_reset_disabled = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; + + gd54xx_set_svga_fast(gd54xx); + svga_recalctimings(svga); break; case 0x17: if (gd54xx_is_5422(svga)) @@ -768,6 +826,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) else return; break; + + default: + break; } return; } @@ -823,6 +884,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->dac_addr = (svga->dac_addr + 1) & 255; svga->dac_pos = 0; break; + + default: + break; } return; case 0x3ce: @@ -869,12 +933,13 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) case 7: svga->colournocare = val; break; + + default: + break; } - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); /*TODO: needs verification on other Cirrus chips*/ - else - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + gd54xx_set_svga_fast(gd54xx); + if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || ((svga->gdcaddr == 6) && ((val ^ o) & 1))) svga_recalctimings(svga); } else { @@ -905,6 +970,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } svga->seqregs[2] &= 0x0f; } + fallthrough; case 0x09: case 0x0a: gd54xx_recalc_banking(gd54xx); @@ -1024,6 +1090,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) case 0x39: gd543x_mmio_write(0xb8021, val, gd54xx); break; + + default: + break; } } return; @@ -1139,6 +1208,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->overlay.ena = (val & 1) != 0; gd54xx_update_overlay(gd54xx); break; + + default: + break; } if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -1152,14 +1224,17 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -gd54xx_in(uint16_t addr, void *p) +gd54xx_in(uint16_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint8_t index; @@ -1222,6 +1297,9 @@ gd54xx_in(uint16_t addr, void *p) case 2048: ret |= 0x18; break; + + default: + break; } } break; @@ -1246,6 +1324,9 @@ gd54xx_in(uint16_t addr, void *p) case 4096: ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ break; + + default: + break; } break; case 0x15: /*Scratch Pad 3 (Memory size for 543x)*/ @@ -1261,6 +1342,9 @@ gd54xx_in(uint16_t addr, void *p) case 4: ret |= 0x04; break; + + default: + break; } } break; @@ -1298,6 +1382,9 @@ gd54xx_in(uint16_t addr, void *p) case 0x1e: ret = gd54xx->vclk_d[svga->seqaddr - 0x1b]; break; + + default: + break; } break; } else @@ -1353,6 +1440,9 @@ gd54xx_in(uint16_t addr, void *p) else ret = svga->vgapal[index].b & 0x3f; break; + + default: + break; } break; case 0x3ce: @@ -1470,6 +1560,9 @@ gd54xx_in(uint16_t addr, void *p) gd54xx->vportsync = !gd54xx->vportsync; ret = gd54xx->vportsync ? 0x80 : 0x00; break; + + default: + break; } } else { if ((svga->gdcaddr < 2) && !gd54xx->unlocked) @@ -1510,6 +1603,9 @@ gd54xx_in(uint16_t addr, void *p) if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) ret = 0xff; /*Standard CL-GD5430/40*/ break; + + default: + break; } break; default: @@ -1546,8 +1642,6 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) } else svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } - - svga->write_bank = svga->read_bank = svga->extra_banks[0]; } static void @@ -1557,7 +1651,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) uint32_t base; uint32_t size; - if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { + if (gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->mmio_mapping); @@ -1566,7 +1660,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) gd54xx->mmio_vram_overlap = 0; - if (!gd54xx_is_5422(svga) || !(svga->seqregs[7] & 0xf0) || !(svga->seqregs[0x07] & 0x01)) { + if (!gd54xx_is_5422(svga) || !(svga->seqregs[0x07] & 0xf0) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->aperture2_mapping); switch (svga->gdcreg[6] & 0x0c) { @@ -1587,9 +1681,12 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) svga->banked_mask = 0x7fff; gd54xx->mmio_vram_overlap = 1; break; + + default: + break; } - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -1600,17 +1697,19 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } else { if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) { if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; + base = (svga->seqregs[0x07] & 0xf0) << 16; size = 1 * 1024 * 1024; } else { - base = (svga->seqregs[7] & 0xe0) << 16; + base = (svga->seqregs[0x07] & 0xe0) << 16; size = 2 * 1024 * 1024; } } else if (gd54xx->pci) { base = gd54xx->lfb_base; - /* if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - size = 32 * 1024 * 1024; - else */ +#if 0 + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + size = 32 * 1024 * 1024; + else +#endif if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; else @@ -1646,23 +1745,57 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) static void gd54xx_recalctimings(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->p; - uint8_t clocksel; - uint8_t rdmask; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + uint8_t clocksel; + uint8_t rdmask; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + + svga->hblankstart = svga->crtc[2]; + + if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { + /* Special blanking mode: the blank start and end become components of the window generator, + and the actual blanking comes from the display enable signal. */ + /* This means blanking during overscan, we already calculate it that way, so just use the + same calculation and force otvercan to 0. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | + (((svga->crtc[0x1a] >> 4) & 3) << 6); + + svga->hblank_end_mask = 0x000000ff; + + if (svga->crtc[0x1b] & 0x20) { + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3) + 1*/; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } + } svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4); svga->interlace = (svga->crtc[0x1a] & 0x01); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + svga->interlace = 0; + } + svga->map8 = svga->pallook; - if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) { + if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { if (linedbl) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) + if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) { svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } } } else if (svga->gdcreg[5] & 0x40) svga->render = svga_render_8bpp_lowres; @@ -1703,7 +1836,7 @@ gd54xx_recalctimings(svga_t *svga) break; case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { + if (gd54xx_is_5434(svga) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_32)) { svga->bpp = 32; if (linedbl) svga->render = svga_render_32bpp_lowres; @@ -1740,7 +1873,7 @@ gd54xx_recalctimings(svga_t *svga) break; case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { + switch (svga->seqregs[0x07] & CIRRUS_SR7_BPP_MASK) { case CIRRUS_SR7_BPP_32: if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { svga->bpp = 32; @@ -1785,8 +1918,14 @@ gd54xx_recalctimings(svga_t *svga) else svga->render = svga_render_8bpp_highres; break; + + default: + break; } break; + + default: + break; } } else { svga->bpp = 15; @@ -1809,18 +1948,21 @@ gd54xx_recalctimings(svga_t *svga) if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) svga->clock = (cpuclock * (float) (1ULL << 32)) / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float) n / ((float) d * m))); + int n = gd54xx->vclk_n[clocksel] & 0x7f; + int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; + uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; + float freq = (14318184.0F * ((float) n / ((float) d * m))); if (gd54xx_is_5422(svga)) { - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { + switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) { case 2: - freq /= 2.0; + freq /= 2.0F; break; case 4: if (!gd54xx_is_5434(svga)) - freq /= 3.0; + freq /= 3.0F; + break; + + default: break; } } @@ -1828,21 +1970,36 @@ gd54xx_recalctimings(svga_t *svga) } svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; + + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) + svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) + svga->render = svga_render_text_40; + else + svga->render = svga_render_text_80; + } + + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { + svga->extra_banks[0] = 0; + svga->extra_banks[1] = 0x8000; + } } static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->p; - int comb; - int b0; - int b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + int comb; + int b0; + int b1; + uint8_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; + uint32_t bgcol = gd54xx->extpallook[0x00]; + uint32_t fgcol = gd54xx->extpallook[0x0f]; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; offset <<= linedbl; @@ -1850,11 +2007,11 @@ gd54xx_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += pitch; for (int x = 0; x < svga->hwcursor.cur_xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; + dat[0] = svga->vram[svga->hwcursor_latch.addr & gd54xx->vram_mask]; if (svga->hwcursor.cur_xsize == 64) - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & gd54xx->vram_mask]; else - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & gd54xx->vram_mask]; for (uint8_t xx = 0; xx < 8; xx++) { b0 = (dat[0] >> (7 - xx)) & 1; b1 = (dat[1] >> (7 - xx)) & 1; @@ -1866,16 +2023,19 @@ gd54xx_hwcursor_draw(svga_t *svga, int displine) break; case 1: /* The pixel is shown in the cursor background color */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = bgcol; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = bgcol; break; case 2: /* The pixel is shown as the inverse of the original screen pixel (XOR cursor) */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; break; case 3: /* The pixel is shown in the cursor foreground color */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = fgcol; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = fgcol; + break; + + default: break; } } @@ -1944,22 +2104,56 @@ gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) case 0xda: *res = ~(*src & *dst); break; + + default: + break; + } +} + +static uint8_t +gd54xx_get_aperture(uint32_t addr) +{ + uint32_t ap = addr >> 22; + return (uint8_t) (ap & 0x03); +} + +static uint32_t +gd54xx_mem_sys_pos_adj(gd54xx_t *gd54xx, uint8_t ap, uint32_t pos) +{ + uint32_t ret = pos; + + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + switch (ap) { + case 1: + ret ^= 1; + break; + case 2: + ret ^= 3; + break; + } } + + return ret; } static uint8_t -gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) +gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx, uint8_t ap) { + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.msd_buf_pos); uint8_t ret = 0xff; if (gd54xx->blt.msd_buf_cnt != 0) { - ret = gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos++]; + ret = gd54xx->blt.msd_buf[adj_pos]; + + gd54xx->blt.msd_buf_pos++; gd54xx->blt.msd_buf_cnt--; if (gd54xx->blt.msd_buf_cnt == 0) { if (gd54xx->countminusone == 1) { gd54xx->blt.msd_buf_pos = 0; - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) gd54xx_start_blit(0xff, 8, gd54xx, &gd54xx->svga); else gd54xx_start_blit(0xffffffff, 32, gd54xx, &gd54xx->svga); @@ -1972,14 +2166,17 @@ gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) } static void -gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) +gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val, uint8_t ap) { - gd54xx->blt.sys_src32 &= ~(0xff << (gd54xx->blt.sys_cnt << 3)); - gd54xx->blt.sys_src32 |= (val << (gd54xx->blt.sys_cnt << 3)); + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.sys_cnt); + + gd54xx->blt.sys_src32 &= ~(0xff << (adj_pos << 3)); + gd54xx->blt.sys_src32 |= (val << (adj_pos << 3)); gd54xx->blt.sys_cnt = (gd54xx->blt.sys_cnt + 1) & 3; if (gd54xx->blt.sys_cnt == 0) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { for (uint8_t i = 0; i < 32; i += 8) gd54xx_start_blit((gd54xx->blt.sys_src32 >> i) & 0xff, 8, gd54xx, &gd54xx->svga); } else @@ -1988,30 +2185,25 @@ gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) } static void -gd54xx_write(uint32_t addr, uint8_t val, void *p) +gd54xx_write(uint32_t addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); - return; - } - - if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_write(addr, val, svga); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; - svga_write_linear(addr, val, svga); } static void -gd54xx_writew(uint32_t addr, uint16_t val, void *p) +gd54xx_writew(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { @@ -2020,11 +2212,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writew(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2036,9 +2224,9 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p) } static void -gd54xx_writel(uint32_t addr, uint32_t val, void *p) +gd54xx_writel(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { @@ -2049,11 +2237,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p) return; } - if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writel(addr, val, svga); - return; - } - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) @@ -2117,22 +2301,18 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) } } break; + + default: + break; } svga->changedvram[addr >> 12] = changeframecount; } -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - static int gd54xx_aperture2_enabled(gd54xx_t *gd54xx) { - svga_t *svga = &gd54xx->svga; + const svga_t *svga = &gd54xx->svga; if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) return 0; @@ -2147,15 +2327,15 @@ gd54xx_aperture2_enabled(gd54xx_t *gd54xx) } static uint8_t -gd54xx_readb_linear(uint32_t addr, void *p) +gd54xx_readb_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint8_t ap = gd54xx_get_aperture(addr); addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_read_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2165,11 +2345,11 @@ gd54xx_readb_linear(uint32_t addr, void *p) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + return gd54xx_mem_sys_dest_read(gd54xx, ap); switch (ap) { - case 0: default: + case 0: break; case 1: /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ @@ -2187,17 +2367,18 @@ gd54xx_readb_linear(uint32_t addr, void *p) } static uint16_t -gd54xx_readw_linear(uint32_t addr, void *p) +gd54xx_readw_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint16_t temp; addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readw_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2209,18 +2390,19 @@ gd54xx_readw_linear(uint32_t addr, void *p) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, p); - temp |= gd54xx_readb_linear(addr + 1, p) << 8; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; return temp; } switch (ap) { - case 0: default: + case 0: return svga_readw_linear(addr, svga); case 2: /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ addr ^= 0x00000002; + fallthrough; case 1: temp = svga_readb_linear(addr + 1, svga); temp |= (svga_readb_linear(addr, svga) << 8); @@ -2235,17 +2417,18 @@ gd54xx_readw_linear(uint32_t addr, void *p) } static uint32_t -gd54xx_readl_linear(uint32_t addr, void *p) +gd54xx_readl_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint32_t temp; addr &= 0x003fffff; /* 4 MB mask */ - if ((svga->seqregs[0x07] & 0x01) == 0) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readl_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { @@ -2257,16 +2440,16 @@ gd54xx_readl_linear(uint32_t addr, void *p) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, p); - temp |= gd54xx_readb_linear(addr + 1, p) << 8; - temp |= gd54xx_readb_linear(addr + 2, p) << 16; - temp |= gd54xx_readb_linear(addr + 3, p) << 24; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; + temp |= gd54xx_readb_linear(old_addr + 2, priv) << 16; + temp |= gd54xx_readb_linear(old_addr + 3, priv) << 24; return temp; } switch (ap) { - case 0: default: + case 0: return svga_readl_linear(addr, svga); case 1: temp = svga_readb_linear(addr + 1, svga); @@ -2294,25 +2477,28 @@ gd54xx_readl_linear(uint32_t addr, void *p) } static uint8_t -gd5436_aperture2_readb(uint32_t addr, void *p) +gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx, ap); return 0xff; } static uint16_t -gd5436_aperture2_readw(uint32_t addr, void *p) +gd5436_aperture2_readw(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; uint16_t ret = 0xffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd5436_aperture2_readb(addr, p); - ret |= gd5436_aperture2_readb(addr + 1, p) << 8; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd5436_aperture2_readb(addr, priv); + ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; return ret; } @@ -2320,16 +2506,17 @@ gd5436_aperture2_readw(uint32_t addr, void *p) } static uint32_t -gd5436_aperture2_readl(uint32_t addr, void *p) +gd5436_aperture2_readl(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; uint32_t ret = 0xffffffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd5436_aperture2_readb(addr, p); - ret |= gd5436_aperture2_readb(addr + 1, p) << 8; - ret |= gd5436_aperture2_readb(addr + 2, p) << 16; - ret |= gd5436_aperture2_readb(addr + 3, p) << 24; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd5436_aperture2_readb(addr, priv); + ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; + ret |= gd5436_aperture2_readb(addr + 2, priv) << 16; + ret |= gd5436_aperture2_readb(addr + 3, priv) << 24; return ret; } @@ -2337,34 +2524,35 @@ gd5436_aperture2_readl(uint32_t addr, void *p) } static void -gd5436_aperture2_writeb(uint32_t addr, uint8_t val, void *p) +gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - gd54xx_mem_sys_src_write(gd54xx, val); + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + gd54xx_mem_sys_src_write(gd54xx, val, ap); } static void -gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *p) +gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); } } static void -gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *p) +gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); gd5436_aperture2_writeb(addr + 2, val >> 16, gd54xx); @@ -2373,14 +2561,14 @@ gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *p) } static void -gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) +gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_write_linear(addr, val, svga); return; } @@ -2396,13 +2584,13 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, ap); return; } switch (ap) { - case 0: default: + case 0: break; case 1: /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ @@ -2420,14 +2608,14 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) } static void -gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) +gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writew_linear(addr, val, svga); return; } @@ -2443,15 +2631,15 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); return; } if (svga->writemode < 4) { switch (ap) { - case 0: default: + case 0: svga_writew_linear(addr, val, svga); return; case 2: @@ -2462,21 +2650,24 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) if (svga->fast) cycles -= svga->monitor->mon_video_timing_write_w; + return; case 3: return; } } else { switch (ap) { - case 0: default: + case 0: svga_write_linear(addr, val & 0xff, svga); svga_write_linear(addr + 1, val >> 8, svga); return; case 2: addr ^= 0x00000002; + fallthrough; case 1: svga_write_linear(addr + 1, val & 0xff, svga); svga_write_linear(addr, val >> 8, svga); + return; case 3: return; } @@ -2484,14 +2675,14 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) } static void -gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) +gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writel_linear(addr, val, svga); return; } @@ -2507,17 +2698,17 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); - gd54xx_writeb_linear(addr + 2, val >> 16, gd54xx); - gd54xx_writeb_linear(addr + 3, val >> 24, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr + 2, val >> 16, gd54xx); + gd54xx_writeb_linear(old_addr + 3, val >> 24, gd54xx); return; } if (svga->writemode < 4) { switch (ap) { - case 0: default: + case 0: svga_writel_linear(addr, val, svga); return; case 1: @@ -2531,13 +2722,14 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) svga_writeb_linear(addr + 2, val >> 8, svga); svga_writeb_linear(addr + 1, val >> 16, svga); svga_writeb_linear(addr, val >> 24, svga); + return; case 3: return; } } else { switch (ap) { - case 0: default: + case 0: svga_write_linear(addr, val & 0xff, svga); svga_write_linear(addr + 1, val >> 8, svga); svga_write_linear(addr + 2, val >> 16, svga); @@ -2554,6 +2746,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) svga_write_linear(addr + 2, val >> 8, svga); svga_write_linear(addr + 1, val >> 16, svga); svga_write_linear(addr, val >> 24, svga); + return; case 3: return; } @@ -2561,59 +2754,53 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) } static uint8_t -gd54xx_read(uint32_t addr, void *p) +gd54xx_read(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if ((svga->seqregs[0x07] & 0x01) == 0) - 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); + return gd54xx_mem_sys_dest_read(gd54xx, 0); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); } static uint16_t -gd54xx_readw(uint32_t addr, void *p) +gd54xx_readw(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint16_t ret; - if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readw(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_read(addr, p); - ret |= gd54xx_read(addr + 1, p) << 8; + ret = gd54xx_read(addr, priv); + ret |= gd54xx_read(addr + 1, priv) << 8; return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } static uint32_t -gd54xx_readl(uint32_t addr, void *p) +gd54xx_readl(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint32_t ret; - if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readl(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_read(addr, p); - ret |= gd54xx_read(addr + 1, p) << 8; - ret |= gd54xx_read(addr + 2, p) << 16; - ret |= gd54xx_read(addr + 3, p) << 24; + ret = gd54xx_read(addr, priv); + ret |= gd54xx_read(addr + 1, priv) << 8; + ret |= gd54xx_read(addr + 2, priv) << 16; + ret |= gd54xx_read(addr + 3, priv) << 24; return ret; } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); } @@ -2628,9 +2815,9 @@ gd543x_do_mmio(svga_t *svga, uint32_t addr) } static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) +gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint8_t old; @@ -2788,29 +2975,32 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); } break; + + default: + break; } } else if (gd54xx->mmio_vram_overlap) gd54xx_write(addr, val, gd54xx); } static void -gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *p) +gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } - gd543x_mmio_write(addr, val, p); + gd543x_mmio_write(addr, val, priv); } static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) +gd543x_mmio_writew(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (gd543x_do_mmio(svga, addr)) { @@ -2828,9 +3018,9 @@ gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) } static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) +gd543x_mmio_writel(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; if (gd543x_do_mmio(svga, addr)) { @@ -2854,9 +3044,9 @@ gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) } static uint8_t -gd543x_mmio_read(uint32_t addr, void *p) +gd543x_mmio_read(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint8_t ret = 0xff; @@ -2982,20 +3172,23 @@ gd543x_mmio_read(uint32_t addr, void *p) case 0x40: ret = gd54xx->blt.status; break; + + default: + break; } } else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx); else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_mem_sys_dest_read(gd54xx); + ret = gd54xx_mem_sys_dest_read(gd54xx, 0); } return ret; } static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p) +gd543x_mmio_readw(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint16_t ret = 0xffff; @@ -3004,8 +3197,8 @@ gd543x_mmio_readw(uint32_t addr, void *p) else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8); else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd543x_mmio_read(addr, p); - ret |= gd543x_mmio_read(addr + 1, p) << 8; + ret = gd543x_mmio_read(addr, priv); + ret |= gd543x_mmio_read(addr + 1, priv) << 8; return ret; } @@ -3013,9 +3206,9 @@ gd543x_mmio_readw(uint32_t addr, void *p) } static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p) +gd543x_mmio_readl(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint32_t ret = 0xffffffff; @@ -3024,10 +3217,10 @@ gd543x_mmio_readl(uint32_t addr, void *p) else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8) | (gd54xx_read(addr + 2, gd54xx) << 16) | (gd54xx_read(addr + 3, gd54xx) << 24); else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd543x_mmio_read(addr, p); - ret |= gd543x_mmio_read(addr + 1, p) << 8; - ret |= gd543x_mmio_read(addr + 2, p) << 16; - ret |= gd543x_mmio_read(addr + 3, p) << 24; + ret = gd543x_mmio_read(addr, priv); + ret |= gd543x_mmio_read(addr + 1, priv) << 8; + ret |= gd543x_mmio_read(addr + 2, priv) << 16; + ret |= gd543x_mmio_read(addr + 3, priv) << 24; return ret; } @@ -3035,86 +3228,86 @@ gd543x_mmio_readl(uint32_t addr, void *p) } static void -gd5480_vgablt_write(uint32_t addr, uint8_t val, void *p) +gd5480_vgablt_write(uint32_t addr, uint8_t val, void *priv) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writeb((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writeb((addr & 0x000000ff) | 0x000b8000, val, priv); else if (addr < 0x00000100) - gd54xx_out(0x03c0 + addr, val, p); + gd54xx_out(0x03c0 + addr, val, priv); } static void -gd5480_vgablt_writew(uint32_t addr, uint16_t val, void *p) +gd5480_vgablt_writew(uint32_t addr, uint16_t val, void *priv) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writew((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writew((addr & 0x000000ff) | 0x000b8000, val, priv); else if (addr < 0x00000100) { - gd5480_vgablt_write(addr, val & 0xff, p); - gd5480_vgablt_write(addr + 1, val >> 8, p); + gd5480_vgablt_write(addr, val & 0xff, priv); + gd5480_vgablt_write(addr + 1, val >> 8, priv); } } static void -gd5480_vgablt_writel(uint32_t addr, uint32_t val, void *p) +gd5480_vgablt_writel(uint32_t addr, uint32_t val, void *priv) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writel((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writel((addr & 0x000000ff) | 0x000b8000, val, priv); else if (addr < 0x00000100) { - gd5480_vgablt_writew(addr, val & 0xffff, p); - gd5480_vgablt_writew(addr + 2, val >> 16, p); + gd5480_vgablt_writew(addr, val & 0xffff, priv); + gd5480_vgablt_writew(addr + 2, val >> 16, priv); } } static uint8_t -gd5480_vgablt_read(uint32_t addr, void *p) +gd5480_vgablt_read(uint32_t addr, void *priv) { uint8_t ret = 0xff; addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_read((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_read((addr & 0x000000ff) | 0x000b8000, priv); else if (addr < 0x00000100) - ret = gd54xx_in(0x03c0 + addr, p); + ret = gd54xx_in(0x03c0 + addr, priv); return ret; } static uint16_t -gd5480_vgablt_readw(uint32_t addr, void *p) +gd5480_vgablt_readw(uint32_t addr, void *priv) { uint16_t ret = 0xffff; addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_readw((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_readw((addr & 0x000000ff) | 0x000b8000, priv); else if (addr < 0x00000100) { - ret = gd5480_vgablt_read(addr, p); - ret |= (gd5480_vgablt_read(addr + 1, p) << 8); + ret = gd5480_vgablt_read(addr, priv); + ret |= (gd5480_vgablt_read(addr + 1, priv) << 8); } return ret; } static uint32_t -gd5480_vgablt_readl(uint32_t addr, void *p) +gd5480_vgablt_readl(uint32_t addr, void *priv) { uint32_t ret = 0xffffffff; addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_readl((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_readl((addr & 0x000000ff) | 0x000b8000, priv); else if (addr < 0x00000100) { - ret = gd5480_vgablt_readw(addr, p); - ret |= (gd5480_vgablt_readw(addr + 2, p) << 16); + ret = gd5480_vgablt_readw(addr, priv); + ret |= (gd5480_vgablt_readw(addr + 2, priv) << 16); } return ret; @@ -3151,6 +3344,9 @@ gd54xx_get_pixel_width(gd54xx_t *gd54xx) case CIRRUS_BLTMODE_PIXELWIDTH32: ret = 4; break; + + default: + break; } return ret; @@ -3232,21 +3428,21 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) pattern_pitch = 1; - dsta = gd54xx->blt.dst_addr & svga->vram_mask; + dsta = gd54xx->blt.dst_addr & gd54xx->vram_mask; /* The vertical offset is in the three low-order bits of the Source Address register. */ pattern_y = gd54xx->blt.src_addr & 0x07; - /* Mode Pattern bytes Pattern line bytes + /* Mode Pattern bytes Pattern line bytes --------------------------------------------------- - Color Expansion 8 1 - 8-bpp 64 8 - 16-bpp 128 16 - 24-bpp 256 32 - 32-bpp 256 32 + Color Expansion 8 1 + 8-bpp 64 8 + 16-bpp 128 16 + 24-bpp 256 32 + 32-bpp 256 32 */ /* The boundary has to be equal to the size of the pattern. */ - srca = (gd54xx->blt.src_addr & ~0x07) & svga->vram_mask; + srca = (gd54xx->blt.src_addr & ~0x07) & gd54xx->vram_mask; for (uint16_t y = 0; y <= gd54xx->blt.height; y++) { /* Go to the correct pattern line. */ @@ -3257,16 +3453,16 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) bitmask = 1; else - bitmask = svga->vram[srca2 & svga->vram_mask] & (0x80 >> pixel); + bitmask = svga->vram[srca2 & gd54xx->vram_mask] & (0x80 >> pixel); } for (int xx = 0; xx < gd54xx->blt.pixel_width; xx++) { if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) src = gd54xx_color_expand(gd54xx, bitmask, xx); else { - src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & svga->vram_mask]; + src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & gd54xx->vram_mask]; bitmask = gd54xx_transparent_comp(gd54xx, xx, src); } - dst = &(svga->vram[(dsta + x + xx) & svga->vram_mask]); + dst = &(svga->vram[(dsta + x + xx) & gd54xx->vram_mask]); target = *dst; gd54xx_rop(gd54xx, &target, &target, &src); if (gd54xx->blt.pixel_width == 3) @@ -3275,7 +3471,7 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) gd54xx_blit(gd54xx, bitmask, dst, target, (x < gd54xx->blt.pattern_x)); } pixel = (pixel + 1) & 7; - svga->changedvram[((dsta + x) & svga->vram_mask) >> 12] = changeframecount; + svga->changedvram[((dsta + x) & gd54xx->vram_mask) >> 12] = changeframecount; } pattern_y = (pattern_y + 1) & 7; dsta += gd54xx->blt.dst_pitch; @@ -3336,7 +3532,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) bitmask = gd54xx_transparent_comp(gd54xx, gd54xx->blt.xx_count, exp); } - dst = &(svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); + dst = &(svga->vram[gd54xx->blt.dst_addr_backup & gd54xx->vram_mask]); target = *dst; gd54xx_rop(gd54xx, &target, &target, &exp); if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) @@ -3349,7 +3545,7 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) gd54xx->blt.xx_count = (gd54xx->blt.xx_count + 1) % gd54xx->blt.pixel_width; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; + svga->changedvram[(gd54xx->blt.dst_addr_backup & gd54xx->vram_mask) >> 12] = changeframecount; if (!gd54xx->blt.xx_count) { /* 1 mask bit = 1 blitted pixel */ @@ -3406,20 +3602,20 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) mask = 0; if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - mask = svga->vram[src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); + mask = svga->vram[src_addr & gd54xx->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); shift = (gd54xx->blt.x_count % gd54xx->blt.pixel_width); src = gd54xx_color_expand(gd54xx, mask, shift); } else { - src = svga->vram[src_addr & svga->vram_mask]; + src = svga->vram[src_addr & gd54xx->vram_mask]; src_addr += gd54xx->blt.dir; mask = 1; } count--; - dst = svga->vram[dst_addr & svga->vram_mask]; - svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount; + dst = svga->vram[dst_addr & gd54xx->vram_mask]; + svga->changedvram[(dst_addr & gd54xx->vram_mask) >> 12] = changeframecount; - gd54xx_rop(gd54xx, (uint8_t *) &dst, (uint8_t *) &dst, (const uint8_t *) &src); + gd54xx_rop(gd54xx, &dst, &dst, (const uint8_t *) &src); if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) mask = !mask; @@ -3429,7 +3625,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) mask = 0; if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) { - svga->vram[dst_addr & svga->vram_mask] = dst; + svga->vram[dst_addr & gd54xx->vram_mask] = dst; } dst_addr += gd54xx->blt.dir; @@ -3453,10 +3649,10 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) } else src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir); - dst_addr &= svga->vram_mask; - gd54xx->blt.dst_addr_backup &= svga->vram_mask; - src_addr &= svga->vram_mask; - gd54xx->blt.src_addr_backup &= svga->vram_mask; + dst_addr &= gd54xx->vram_mask; + gd54xx->blt.dst_addr_backup &= gd54xx->vram_mask; + src_addr &= gd54xx->vram_mask; + gd54xx->blt.src_addr_backup &= gd54xx->vram_mask; gd54xx->blt.x_count = 0; @@ -3497,7 +3693,7 @@ gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.msd_buf_pos = 0; while (gd54xx->blt.msd_buf_pos < 32) { - gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & svga->vram_mask]; + gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & gd54xx->vram_mask]; gd54xx->blt.src_addr_backup += gd54xx->blt.dir; gd54xx->blt.msd_buf_pos++; @@ -3557,16 +3753,15 @@ gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *sv } static uint8_t -cl_pci_read(int func, int addr, void *p) +cl_pci_read(UNUSED(int func), int addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; - uint8_t ret = 0x00; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; + const svga_t *svga = &gd54xx->svga; + uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) ret = 0x00; - else - switch (addr) { + else switch (addr) { case 0x00: ret = 0x13; /*Cirrus Logic*/ break; @@ -3615,7 +3810,7 @@ cl_pci_read(int func, int addr, void *p) case 0x13: ret = gd54xx->lfb_base >> 24; if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - ret = 0xfe; + ret &= 0xfe; break; case 0x14: @@ -3650,17 +3845,20 @@ cl_pci_read(int func, int addr, void *p) case 0x3d: ret = PCI_INTA; break; - } + + default: + break; + } return ret; } static void -cl_pci_write(int func, int addr, uint8_t val, void *p) +cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; - svga_t *svga = &gd54xx->svga; - uint32_t byte; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + const svga_t *svga = &gd54xx->svga; + uint32_t byte; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) return; @@ -3720,33 +3918,40 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) case 0x3c: gd54xx->int_line = val; return; + + default: + break; } } static uint8_t -gd5428_mca_read(int port, void *p) +gd5428_mca_read(int port, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; return gd54xx->pos_regs[port & 7]; } static void -gd5428_mca_write(int port, uint8_t val, void *p) +gd5428_mca_write(int port, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; if (port < 0x102) return; gd54xx->pos_regs[port & 7] = val; - gd543x_recalc_mapping(gd54xx); + mem_mapping_disable(&gd54xx->bios_rom.mapping); + if (gd54xx->pos_regs[2] & 0x01) + mem_mapping_enable(&gd54xx->bios_rom.mapping); } static uint8_t -gd5428_mca_feedb(void *p) +gd5428_mca_feedb(void *priv) { - return 1; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; + + return gd54xx->pos_regs[2] & 0x01; } static void @@ -3768,7 +3973,7 @@ gd54xx_reset(void *priv) io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); mem_mapping_disable(&gd54xx->vgablt_mapping); - if (gd54xx->has_bios && gd54xx->pci) + if (gd54xx->has_bios && (gd54xx->pci || gd54xx->mca)) mem_mapping_disable(&gd54xx->bios_rom.mapping); memset(gd54xx->pci_regs, 0x00, 256); @@ -3821,17 +4026,17 @@ gd54xx_reset(void *priv) gd54xx->unlocked = 0; } -static void - * - gd54xx_init(const device_t *info) +static void * +gd54xx_init(const device_t *info) { - gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - int vram; - char *romfn = NULL; - char *romfn1 = NULL; - char *romfn2 = NULL; + gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); + svga_t *svga = &gd54xx->svga; + int id = info->local & 0xff; + int vram; + const char *romfn = NULL; + const char *romfn1 = NULL; + const char *romfn2 = NULL; + memset(gd54xx, 0, sizeof(gd54xx_t)); gd54xx->pci = !!(info->flags & DEVICE_PCI); @@ -3927,7 +4132,11 @@ static void break; case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else + romfn = BIOS_GD5436_PATH; break; case CIRRUS_ID_CLGD5430: @@ -3944,9 +4153,9 @@ static void if (info->local & 0x200) { romfn = NULL; gd54xx->has_bios = 0; - } else if (gd54xx->pci) { + } else if (gd54xx->pci) romfn = BIOS_GD5430_PATH; - } else if ((gd54xx->vlb) && (info->local & 0x100)) + else if ((gd54xx->vlb) && (info->local & 0x100)) romfn = BIOS_GD5430_ORCHID_VLB_PATH; else romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH; @@ -3963,6 +4172,9 @@ static void case CIRRUS_ID_CLGD5480: romfn = BIOS_GD5480_PATH; break; + + default: + break; } if (info->flags & DEVICE_MCA) { @@ -4056,7 +4268,10 @@ static void io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) { - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); + if (romfn == NULL) + pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot); mem_mapping_disable(&gd54xx->bios_rom.mapping); } @@ -4106,6 +4321,7 @@ static void if (gd54xx->mca) { gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b; gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91; + mem_mapping_disable(&gd54xx->bios_rom.mapping); mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx); io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); } @@ -4264,9 +4480,9 @@ gd5480_available(void) } void -gd54xx_close(void *p) +gd54xx_close(void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_close(&gd54xx->svga); @@ -4279,17 +4495,17 @@ gd54xx_close(void *p) } void -gd54xx_speed_changed(void *p) +gd54xx_speed_changed(void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_recalctimings(&gd54xx->svga); } void -gd54xx_force_redraw(void *p) +gd54xx_force_redraw(void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) p; + gd54xx_t *gd54xx = (gd54xx_t *) priv; gd54xx->svga.fullchange = gd54xx->svga.monitor->mon_changeframecount; } @@ -4752,6 +4968,20 @@ const device_t gd5428_onboard_device = { .config = gd5428_onboard_config }; +const device_t gd5428_vlb_onboard_device = { + .name = "Cirrus Logic GD5428 (VLB) (On-Board)", + .internal_name = "cl_gd5428_vlb_onboard", + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5428_onboard_config +}; + const device_t gd5429_isa_device = { .name = "Cirrus Logic GD5429 (ISA)", .internal_name = "cl_gd5429_isa", @@ -4809,6 +5039,20 @@ const device_t gd5430_vlb_device = { .config = gd5429_config }; +const device_t gd5430_onboard_vlb_device = { + .name = "Cirrus Logic GD5430 (On-Board)", + .internal_name = "cl_gd5430_onboard_vlb", + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5430 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config +}; + const device_t gd5430_pci_device = { .name = "Cirrus Logic GD5430 (PCI)", .internal_name = "cl_gd5430_pci", @@ -4823,6 +5067,20 @@ const device_t gd5430_pci_device = { .config = gd5429_config }; +const device_t gd5430_onboard_pci_device = { + .name = "Cirrus Logic GD5430 (PCI) (On-Board)", + .internal_name = "cl_gd5430_onboard_pci", + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5430 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config +}; + const device_t gd5434_isa_device = { .name = "Cirrus Logic GD5434 (ISA)", .internal_name = "cl_gd5434_isa", @@ -4894,6 +5152,20 @@ const device_t gd5434_pci_device = { .config = gd5434_config }; +const device_t gd5436_onboard_pci_device = { + .name = "Cirrus Logic GD5436 (PCI) (On-Board)", + .internal_name = "cl_gd5436_onboard_pci", + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5436 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + { .available = NULL }, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config +}; + const device_t gd5436_pci_device = { .name = "Cirrus Logic GD5436 (PCI)", .internal_name = "cl_gd5436_pci", diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 81c1746f33..dcc72a76b9 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -34,6 +34,7 @@ #include <86box/vid_cga.h> #include <86box/vid_colorplus.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> /* Bits in the colorplus control register: */ #define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ @@ -55,9 +56,9 @@ video_timings_t timing_colorplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = void cga_recalctimings(cga_t *cga); void -colorplus_out(uint16_t addr, uint8_t val, void *p) +colorplus_out(uint16_t addr, uint8_t val, void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; if (addr == 0x3DD) { colorplus->control = val & 0x70; @@ -67,17 +68,17 @@ colorplus_out(uint16_t addr, uint8_t val, void *p) } uint8_t -colorplus_in(uint16_t addr, void *p) +colorplus_in(uint16_t addr, void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; return cga_in(addr, &colorplus->cga); } void -colorplus_write(uint32_t addr, uint8_t val, void *p) +colorplus_write(uint32_t addr, uint8_t val, void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { addr ^= 0x4000; @@ -94,9 +95,9 @@ colorplus_write(uint32_t addr, uint8_t val, void *p) } uint8_t -colorplus_read(uint32_t addr, void *p) +colorplus_read(uint32_t addr, void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { addr ^= 0x4000; @@ -119,9 +120,9 @@ colorplus_recalctimings(colorplus_t *colorplus) } void -colorplus_poll(void *p) +colorplus_poll(void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; int x; int c; int oldvc; @@ -134,8 +135,8 @@ colorplus_poll(void *p) 0x18, 0x1A, 0x1C, 0x1E, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F }; - uint8_t *plane0 = colorplus->cga.vram; - uint8_t *plane1 = colorplus->cga.vram + 0x4000; + const uint8_t *plane0 = colorplus->cga.vram; + const uint8_t *plane1 = colorplus->cga.vram + 0x4000; /* If one of the extra modes is not selected, drop down to the CGA * drawing code. */ @@ -333,7 +334,7 @@ colorplus_init(colorplus_t *colorplus) } void * -colorplus_standalone_init(const device_t *info) +colorplus_standalone_init(UNUSED(const device_t *info)) { int display_type; @@ -362,18 +363,18 @@ colorplus_standalone_init(const device_t *info) } void -colorplus_close(void *p) +colorplus_close(void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; free(colorplus->cga.vram); free(colorplus); } void -colorplus_speed_changed(void *p) +colorplus_speed_changed(void *priv) { - colorplus_t *colorplus = (colorplus_t *) p; + colorplus_t *colorplus = (colorplus_t *) priv; cga_recalctimings(&colorplus->cga); } diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index c913e6e7cd..430c7a64d1 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -83,9 +83,9 @@ compaq_cga_recalctimings(compaq_cga_t *self) } void -compaq_cga_poll(void *p) +compaq_cga_poll(void *priv) { - compaq_cga_t *self = (compaq_cga_t *) p; + compaq_cga_t *self = (compaq_cga_t *) priv; uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; int drawcursor; int x; @@ -121,7 +121,7 @@ compaq_cga_poll(void *p) if (self->cga.displine < self->cga.firstline) { self->cga.firstline = self->cga.displine; video_wait_for_buffer(); - compaq_cga_log("Firstline %i\n", firstline); + compaq_cga_log("Firstline %i\n", self->cga.firstline); } self->cga.lastline = self->cga.displine; @@ -452,18 +452,18 @@ compaq_cga_init(const device_t *info) } void -compaq_cga_close(void *p) +compaq_cga_close(void *priv) { - compaq_cga_t *self = (compaq_cga_t *) p; + compaq_cga_t *self = (compaq_cga_t *) priv; free(self->cga.vram); free(self); } void -compaq_cga_speed_changed(void *p) +compaq_cga_speed_changed(void *priv) { - compaq_cga_t *self = (compaq_cga_t *) p; + compaq_cga_t *self = (compaq_cga_t *) priv; if (self->cga.crtc[9] == 13) /* Character height */ compaq_cga_recalctimings(self); diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 8cfd51db6c..8f995117c8 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -17,6 +17,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -26,6 +27,7 @@ #include "cpu.h" #include <86box/io.h> #include <86box/timer.h> +#include <86box/pic.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> @@ -39,7 +41,7 @@ void ega_doblit(int wx, int wy, ega_t *ega); #define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" #define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" #define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" -#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" +#define BIOS_ATIEGA800P_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" #define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" #define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" @@ -47,7 +49,7 @@ enum { EGA_IBM = 0, EGA_COMPAQ, EGA_SUPEREGA, - EGA_ATI, + EGA_ATI800P, EGA_ISKRA, EGA_TSENG }; @@ -56,23 +58,21 @@ static video_timings_t timing_ega = { .type = VIDEO_ISA, .write_b = 8, .write_w static uint8_t ega_rotate[8][256]; static uint32_t pallook16[256]; static uint32_t pallook64[256]; -static int ega_type = 0; +static int ega_type = 0; static int old_overscan_color = 0; -uint8_t egaremap2bpp[256]; - /* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour): 7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */ int egaswitchread; -int egaswitches = 9; +int egaswitches = 9; int update_overscan = 0; -uint8_t ega_in(uint16_t addr, void *p); +uint8_t ega_in(uint16_t addr, void *priv); void -ega_out(uint16_t addr, uint8_t val, void *p) +ega_out(uint16_t addr, uint8_t val, void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; uint8_t o; uint8_t old; @@ -89,19 +89,12 @@ ega_out(uint16_t addr, uint8_t val, void *p) case 0xb0: ega_recalctimings(ega); break; - case 0xb2: - case 0xbe: -#if 0 - if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ - svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; -#endif - break; case 0xb3: ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); break; + + default: + break; } break; @@ -115,6 +108,8 @@ ega_out(uint16_t addr, uint8_t val, void *p) ega_recalctimings(ega); } } else { + if ((ega->attraddr == 0x13) && (ega->attrregs[0x13] != val)) + ega->fullchange = changeframecount; o = ega->attrregs[ega->attraddr & 31]; ega->attrregs[ega->attraddr & 31] = val; if (ega->attraddr < 16) @@ -153,8 +148,7 @@ ega_out(uint16_t addr, uint8_t val, void *p) io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if (!(val & 1)) io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if ((o ^ val) & 0x80) - ega_recalctimings(ega); + ega_recalctimings(ega); break; case 0x3c4: ega->seqaddr = val; @@ -180,8 +174,15 @@ ega_out(uint16_t addr, uint8_t val, void *p) case 4: ega->chain2_write = !(val & 4); break; + + default: + break; } break; + case 0x3c6: + if (ega_type == 2) + ega->ctl_mode = val; + break; case 0x3ce: ega->gdcaddr = val; break; @@ -213,23 +214,39 @@ ega_out(uint16_t addr, uint8_t val, void *p) case 0xC: /*32k at B8000*/ mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); break; + + default: + break; } break; case 7: ega->colournocare = val; break; + + default: + break; } break; case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; + if (ega->chipset) + ega->crtcreg = val & 0x3f; + else + ega->crtcreg = val & 0x1f; return; case 0x3d1: case 0x3d5: - if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) - return; - if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) - val = (ega->crtc[7] & ~0x10) | (val & 0x10); + if (ega->chipset) { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } else { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } old = ega->crtc[ega->crtcreg]; ega->crtc[ega->crtcreg] = val; if (old != val) { @@ -244,13 +261,16 @@ ega_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } } uint8_t -ega_in(uint16_t addr, void *p) +ega_in(uint16_t addr, void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; uint8_t ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) @@ -267,6 +287,7 @@ ega_in(uint16_t addr, void *p) if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) ret |= 8; break; + default: ret = ega->regs[ega->index]; break; @@ -274,48 +295,52 @@ ega_in(uint16_t addr, void *p) break; case 0x3c0: - if (ega_type) + if (ega_type == 1) ret = ega->attraddr | ega->attr_palette_enable; break; case 0x3c1: - if (ega_type) + if (ega_type == 1) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; break; case 0x3c4: - if (ega_type) + if (ega_type == 1) ret = ega->seqaddr; break; case 0x3c5: - if (ega_type) + if (ega_type == 1) ret = ega->seqregs[ega->seqaddr & 0xf]; break; + case 0x3c6: + if (ega_type == 2) + ret = ega->ctl_mode; + break; case 0x3c8: - if (ega_type) + if (ega_type == 1) ret = 2; break; case 0x3cc: - if (ega_type) + if (ega_type == 1) ret = ega->miscout; break; case 0x3ce: - if (ega_type) + if (ega_type == 1) ret = ega->gdcaddr; break; case 0x3cf: - if (ega_type) + if (ega_type == 1) ret = ega->gdcreg[ega->gdcaddr & 0xf]; break; case 0x3d0: case 0x3d4: - if (ega_type) + if (ega_type == 1) ret = ega->crtcreg; break; case 0x3d1: case 0x3d5: - switch(ega->crtcreg) { + switch (ega->crtcreg) { case 0xc: case 0xd: case 0xe: @@ -324,21 +349,69 @@ ega_in(uint16_t addr, void *p) break; case 0x10: + if (ega_type == 1) + ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen >> 8; + break; + case 0x11: - // TODO: Return light pen address once implemented - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; + else + ret = ega->light_pen & 0xff; break; default: - if (ega_type) + if (ega_type == 1) ret = ega->crtc[ega->crtcreg]; + break; } break; case 0x3da: ega->attrff = 0; - ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - ret = ega->stat; + if (ega_type == 2) { + ret = ega->stat & 0xcf; + switch ((ega->attrregs[0x12] >> 4) & 0x03) { + case 0x00: + /* 00 = Pri. Red (5), Pri. Blue (4) */ + ret |= (ega->color_mux & 0x04) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x01) ? 0x10 : 0x00; + break; + case 0x01: + case 0x03: + /* 01 = Sec. Red (5), Sec. Green (4) */ + /* 11 = Sec. Red (5), Sec. Green (4) */ + ret |= (ega->color_mux & 0x20) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x10) ? 0x10 : 0x00; + break; + case 0x02: + /* 10 = Sec. Blue (5), Pri. Green (4) */ + ret |= (ega->color_mux & 0x08) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x02) ? 0x10 : 0x00; + break; + } + } else { + ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ + ret = ega->stat; + } + break; + case 0x7c6: + ret = 0xfd; /* EGA mode supported. */ + break; + case 0xbc6: + /* 0000 = None; + 0001 = Compaq Dual-Mode (DM) Monitor; + 0010 = RGBI Color Monitor; + 0011 = COMPAQ Color Monitor (RrGgBb) or Compatible; + 0100 - 1111 = Reserved. */ + ret = 0x01; + break; + case 0xfc6: + ret = 0xfd; + break; + + default: break; } @@ -349,6 +422,7 @@ void ega_recalctimings(ega_t *ega) { int clksel; + int color; double _dispontime; double _dispofftime; @@ -392,7 +466,26 @@ ega_recalctimings(ega_t *ega) ega->linedbl = ega->crtc[9] & 0x80; ega->rowcount = ega->crtc[9] & 0x1f; - if (ega->eeprom) { + if (ega_type == 2) { + color = (ega->miscout & 1); + clksel = ((ega->miscout & 0xc) >> 2); + + if (color) { + if (ega->vidclock) + crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); + else + crtcconst = (cpuclock / (157500000.0 / 11.0) * (double) (1ULL << 32)); + } else { + if (ega->vidclock) + crtcconst = (cpuclock / 18981000.0 * (double) (1ULL << 32)); + else + crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32)); + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; + } else if (ega->eeprom) { clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); switch (clksel) { @@ -423,6 +516,10 @@ ega_recalctimings(ega_t *ega) else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); } + if (!(ega->seqregs[1] & 1)) + ega->dot_clock = crtcconst / 9.0; + else + ega->dot_clock = crtcconst / 8.0; ega->interlace = 0; @@ -435,29 +532,42 @@ ega_recalctimings(ega_t *ega) ega->hdisp *= (ega->seqregs[1] & 1) ? 16 : 18; else ega->hdisp *= (ega->seqregs[1] & 1) ? 8 : 9; - ega->render = ega_render_text; + ega->render = ega_render_text; ega->hdisp_old = ega->hdisp; } else { ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; - ega->render = ega_render_graphics; + ega->render = ega_render_graphics; ega->hdisp_old = ega->hdisp; } } - if (enable_overscan) { - overscan_y = (ega->rowcount + 1) << 1; - - if (overscan_y < 16) - overscan_y = 16; + if (ega->chipset) { + if (ega->hdisp > 640) { + ega->dispend <<= 1; + ega->vtotal <<= 1; + ega->split <<= 1; + ega->vsyncstart <<= 1; + } } + overscan_y = (ega->rowcount + 1) << 1; + + if (overscan_y < 16) + overscan_y = 16; + overscan_x = (ega->seqregs[1] & 1) ? 16 : 18; + if (ega->vres) + overscan_y <<= 1; + if (ega->seqregs[1] & 8) overscan_x <<= 1; - ega->y_add = (overscan_y >> 1) - (ega->crtc[8] & 0x1f); - ega->x_add = (overscan_x >> 1); + ega->y_add = (overscan_y >> 1); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; + + if (ega->vres) + ega->y_add >>= 1; if (ega->seqregs[1] & 8) { disptime = (double) ((ega->crtc[0] + 2) << 1); @@ -477,14 +587,115 @@ ega_recalctimings(ega_t *ega) if (ega->dispofftime < TIMER_USEC) ega->dispofftime = TIMER_USEC; + ega->dot_time = (uint64_t) (ega->dot_clock); + if (ega->dot_time < TIMER_USEC) + ega->dot_time = TIMER_USEC; + ega_recalc_remap_func(ega); } +/* This is needed for the Compaq EGA so that it can pass the 3DA + palette mux part of the self-test. */ void -ega_poll(void *p) +ega_dot_poll(void *priv) { - ega_t *ega = (ega_t *) p; - int x; + ega_t *ega = (ega_t *) priv; + static uint8_t chr; + static uint8_t attr; + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool attrlinechars = (ega->attrregs[0x10] & 4); + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); + const bool blinked = ega->blink & 0x10; + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth * (seq9dot ? 9 : 8); + const int cursoron = (ega->sc == (ega->crtc[10] & 31)); + const int cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + uint32_t addr; + int drawcursor; + uint32_t charaddr; + static int fg; + static int bg; + static uint32_t dat; + static int disptime; + static int _dispontime; + static int _dispofftime; + static int cclock = 0; + static int active = 0; + + if (ega->seqregs[1] & 8) { + disptime = ((ega->crtc[0] + 2) << 1); + _dispontime = ((ega->crtc[1] + 1) << 1); + } else { + disptime = (ega->crtc[0] + 2); + _dispontime = (ega->crtc[1] + 1); + } + _dispofftime = disptime - _dispontime; + + timer_advance_u64(&ega->dot_timer, ega->dot_time); + + if (ega->render == ega_render_text) + ega->color_mux = (dat & (0x100 >> (ega->dot >> dwshift))) ? fg : bg; + else + ega->color_mux = 0x00; + + addr = ega->remap_func(ega, ega->cca) & ega->vrammask; + + if (!crtcreset) { + chr = ega->vram[addr]; + attr = ega->vram[addr + 1]; + } else + chr = attr = 0; + + drawcursor = ((ega->cca == cursoraddr) && cursoron && ega->cursoron); + + if (attr & 8) + charaddr = ega->charsetb + (chr * 0x80); + else + charaddr = ega->charseta + (chr * 0x80); + + dat = ega->vram[charaddr + (ega->sc << 2)]; + dat <<= 1; + if ((chr & ~0x1F) == 0xC0 && attrlinechars) + dat |= (dat >> 1) & 1; + + if (!active) + dat = 0x200; + + if (drawcursor) { + bg = ega->egapal[attr & 0x0f]; + fg = ega->egapal[attr >> 4]; + } else { + fg = ega->egapal[attr & 0x0f]; + bg = ega->egapal[attr >> 4]; + if ((attr & 0x80) && attrblink) { + bg = ega->egapal[(attr >> 4) & 7]; + if (blinked) + fg = bg; + } + } + + ega->dot = (ega->dot + 1) % charwidth; + + if (ega->dot == 0) { + ega->cca = (ega->cca + 4) & 0x3ffff; + + cclock++; + + if (active && (cclock == _dispofftime)) + active = 0; + else if (!active && (cclock == _dispontime)) + active = 1; + } +} + +void +ega_poll(void *priv) +{ + ega_t *ega = (ega_t *) priv; + int x, y; int old_ma; int wx = 640; int wy = 350; @@ -504,37 +715,26 @@ ega_poll(void *p) video_wait_for_buffer(); } - if (ega->vres) { - old_ma = ega->ma; - - ega->displine <<= 1; - ega->y_add <<= 1; - - ega->render(ega); - - ega->x_add = (overscan_x >> 1); - ega_render_overscan_left(ega); - ega_render_overscan_right(ega); - ega->x_add = (overscan_x >> 1) - ega->scrollcache; - - ega->displine++; - - ega->ma = old_ma; - + old_ma = ega->ma; + ega->displine *= ega->vres + 1; + ega->y_add *= ega->vres + 1; + for (y = 0; y <= ega->vres; y++) { + /* Render scanline */ ega->render(ega); + /* Render overscan */ ega->x_add = (overscan_x >> 1); ega_render_overscan_left(ega); ega_render_overscan_right(ega); ega->x_add = (overscan_x >> 1) - ega->scrollcache; - ega->y_add >>= 1; - ega->displine >>= 1; - } else { - ega_render_overscan_left(ega); - ega->render(ega); - ega_render_overscan_right(ega); + if (y != ega->vres) { + ega->ma = old_ma; + ega->displine++; + } } + ega->displine /= ega->vres + 1; + ega->y_add /= ega->vres + 1; if (ega->lastline < ega->displine) ega->lastline = ega->displine; @@ -546,8 +746,18 @@ ega_poll(void *p) if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) ega->stat &= ~8; ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; + if (ega->chipset) { + if (ega->hdisp > 640) { + if (ega->displine > 2000) + ega->displine = 0; + } else { + if (ega->displine > 500) + ega->displine = 0; + } + } else { + if (ega->displine > 500) + ega->displine = 0; + } } else { timer_advance_u64(&ega->timer, ega->dispontime); @@ -559,9 +769,11 @@ ega_poll(void *p) if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount)) ega->con = 0; if (ega->dispon) { + /* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll */ if (ega->linedbl && !ega->linecountff) { ega->linecountff = 1; ega->ma = ega->maback; + ega->cca = ega->maback; } if (ega->sc == (ega->crtc[9] & 31)) { ega->linecountff = 0; @@ -572,15 +784,23 @@ ega_poll(void *p) ega->maback += (ega->rowoffset << 3); ega->maback &= ega->vrammask; ega->ma = ega->maback; + ega->cca = ega->maback; } else { ega->linecountff = 0; ega->sc++; ega->sc &= 31; ega->ma = ega->maback; + ega->cca = ega->maback; } } ega->vc++; - ega->vc &= 511; + if (ega->chipset) { + if (ega->hdisp > 640) + ega->vc &= 1023; + else + ega->vc &= 511; + } else + ega->vc &= 511; if (ega->vc == ega->split) { // TODO: Implement the hardware bug where the first scanline is drawn twice when the split happens if (ega->interlace && ega->oddeven) @@ -588,12 +808,9 @@ ega_poll(void *p) else ega->ma = ega->maback = 0; ega->ma <<= 2; + ega->cca = ega->ma; ega->maback <<= 2; ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) { - ega->scrollcache = 0; - ega->x_add = (overscan_x >> 1); - } } if (ega->vc == ega->dispend) { ega->dispon = 0; @@ -615,6 +832,9 @@ ega_poll(void *p) if (ega->vc == ega->vsyncstart) { ega->dispon = 0; ega->stat |= 8; +#if 0 + picint(1 << 2); +#endif x = ega->hdisp; if (ega->interlace && !ega->oddeven) @@ -654,24 +874,19 @@ ega_poll(void *p) ega->ma <<= 2; ega->maback <<= 2; ega->ca <<= 2; + ega->cca = ega->ma; } if (ega->vc == ega->vtotal) { ega->vc = 0; - ega->sc = 0; + ega->sc = (ega->crtc[0x8] & 0x1f); ega->dispon = 1; ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; ega->scrollcache = (ega->attrregs[0x13] & 0x0f); - if (!(ega->gdcreg[6] & 1) && !(ega->attrregs[0x10] & 1)) { /*Text mode*/ - if (ega->seqregs[1] & 1) - ega->scrollcache &= 0x07; - else { - ega->scrollcache++; - if (ega->scrollcache > 8) - ega->scrollcache = 0; - } - } else - ega->scrollcache &= 0x07; + if (ega->scrollcache >= 0x8) + ega->scrollcache = 0; + else + ega->scrollcache++; if (ega->seqregs[1] & 8) ega->scrollcache <<= 1; @@ -688,11 +903,12 @@ ega_poll(void *p) void ega_doblit(int wx, int wy, ega_t *ega) { - int y_add = enable_overscan ? overscan_y : 0; + int unscaled_overscan_y = ega->vres ? overscan_y >> 1 : overscan_y; + int y_add = enable_overscan ? unscaled_overscan_y : 0; int x_add = enable_overscan ? overscan_x : 0; - int y_start = enable_overscan ? 0 : (overscan_y >> 1); + int y_start = enable_overscan ? 0 : (unscaled_overscan_y >> 1); int x_start = enable_overscan ? 0 : (overscan_x >> 1); - int bottom = (overscan_y >> 1) + (ega->crtc[8] & 0x1f); + int bottom = (unscaled_overscan_y >> 1); uint32_t *p; int i; int j; @@ -779,7 +995,7 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) if (ega->gdcreg[6] & 2) { a0mux |= 2; } - if (ega->vram_limit <= 64*1024) { + if (ega->vram_limit <= 64 * 1024) { a0mux |= 1; } @@ -798,6 +1014,9 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) case 0xC: // 32K B800 addr &= 0x7FFF; break; + + default: + break; } switch (a0mux) { @@ -811,15 +1030,18 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) // A0 becomes the inversion of PGSEL (reg 0x3C2, miscout, bit 5) // That is, 1 selects the "low" 64k, and 0 selects the "high" 64k. addr &= ~1; - addr |= (~ega->miscout>>5)&1; + addr |= (~ega->miscout >> 5) & 1; break; case 3: // A0 becomes A14 addr &= ~1; - addr |= (inaddr>>14)&1; + addr |= (inaddr >> 14) & 1; break; case 6: // A0 becomes A16 addr &= ~1; - addr |= (inaddr>>16)&1; + addr |= (inaddr >> 16) & 1; + break; + + default: break; } @@ -831,9 +1053,9 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) } void -ega_write(uint32_t addr, uint8_t val, void *p) +ega_write(uint32_t addr, uint8_t val, void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; uint8_t vala; uint8_t valb; uint8_t valc; @@ -940,6 +1162,9 @@ ega_write(uint32_t addr, uint8_t val, void *p) if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; break; + + default: + break; } } break; @@ -999,16 +1224,22 @@ ega_write(uint32_t addr, uint8_t val, void *p) if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; break; + + default: + break; } } break; + + default: + break; } } uint8_t -ega_read(uint32_t addr, void *p) +ega_read(uint32_t addr, void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; uint8_t temp; uint8_t temp2; uint8_t temp3; @@ -1068,32 +1299,6 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) } } - for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) - edatlookup[c][d] |= 1; - if (d & 1) - edatlookup[c][d] |= 2; - if (c & 2) - edatlookup[c][d] |= 0x10; - if (d & 2) - edatlookup[c][d] |= 0x20; - } - } - - for (c = 0; c < 256; c++) { - egaremap2bpp[c] = 0; - if (c & 0x01) - egaremap2bpp[c] |= 0x01; - if (c & 0x04) - egaremap2bpp[c] |= 0x02; - if (c & 0x10) - egaremap2bpp[c] |= 0x04; - if (c & 0x40) - egaremap2bpp[c] |= 0x08; - } - if (is_mono) { for (c = 0; c < 256; c++) { if (((c >> 3) & 3) == 0) @@ -1111,6 +1316,9 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) case 3: pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); break; + + default: + break; } break; case DISPLAY_AMBER: @@ -1124,6 +1332,9 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) case 3: pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); break; + + default: + break; } break; case DISPLAY_WHITE: @@ -1138,6 +1349,9 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) case 3: pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); break; + + default: + break; } break; } @@ -1178,6 +1392,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) ega->crtc[6] = 255; timer_add(&ega->timer, ega_poll, ega, 1); + if (ega_type == 2) + timer_add(&ega->dot_timer, ega_dot_poll, ega, 1); } static void * @@ -1186,7 +1402,7 @@ ega_standalone_init(const device_t *info) ega_t *ega = malloc(sizeof(ega_t)); int monitor_type; - memset(ega, 0, sizeof(ega_t)); + memset(ega, 0x00, sizeof(ega_t)); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega); @@ -1197,16 +1413,22 @@ ega_standalone_init(const device_t *info) if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || (info->local == EGA_TSENG)) ega_type = 0; + else if (info->local == EGA_COMPAQ) + ega_type = 2; else ega_type = 1; + ega->actual_type = info->local; + ega->chipset = 0; + switch (info->local) { - case EGA_IBM: default: + case EGA_IBM: rom_init(&ega->bios_rom, BIOS_IBM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; case EGA_COMPAQ: + ega->ctl_mode = 0x21; rom_init(&ega->bios_rom, BIOS_CPQ_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; @@ -1214,9 +1436,10 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; - case EGA_ATI: - rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, + case EGA_ATI800P: + rom_init(&ega->bios_rom, BIOS_ATIEGA800P_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ega->chipset = 1; break; case EGA_ISKRA: rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, @@ -1245,11 +1468,16 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (info->local == EGA_ATI) { + if (ega->chipset) { io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); ega->eeprom = malloc(sizeof(ati_eeprom_t)); memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); - ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); + ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800p.nvr", 0); + } else if (info->local == EGA_COMPAQ) { + io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x0fc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); } return ega; @@ -1274,9 +1502,9 @@ sega_standalone_available(void) } static int -atiega_standalone_available(void) +atiega800p_standalone_available(void) { - return rom_present(BIOS_ATIEGA_PATH); + return rom_present(BIOS_ATIEGA800P_PATH); } static int @@ -1292,9 +1520,9 @@ et2000_standalone_available(void) } static void -ega_close(void *p) +ega_close(void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; if (ega->eeprom) free(ega->eeprom); @@ -1303,19 +1531,19 @@ ega_close(void *p) } static void -ega_speed_changed(void *p) +ega_speed_changed(void *priv) { - ega_t *ega = (ega_t *) p; + ega_t *ega = (ega_t *) priv; ega_recalctimings(ega); } /* SW1 SW2 SW3 SW4 - OFF OFF ON OFF Monochrome (5151) 1011 0x0B - ON OFF OFF ON Color 40x25 (5153) 0110 0x06 - OFF OFF OFF ON Color 80x25 (5153) 0111 0x07 - ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08 - OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09 + OFF OFF ON OFF Monochrome (5151) 1011 0x0B + ON OFF OFF ON Color 40x25 (5153) 0110 0x06 + OFF OFF OFF ON Color 80x25 (5153) 0111 0x07 + ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08 + OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09 0 = Switch closed (ON); 1 = Switch open (OFF). */ @@ -1394,7 +1622,7 @@ static const device_config_t ega_config[] = { }; const device_t ega_device = { - .name = "EGA", + .name = "IBM EGA", .internal_name = "ega", .flags = DEVICE_ISA, .local = EGA_IBM, @@ -1435,15 +1663,15 @@ const device_t sega_device = { .config = ega_config }; -const device_t atiega_device = { +const device_t atiega800p_device = { .name = "ATI EGA Wonder 800+", - .internal_name = "egawonder800", + .internal_name = "egawonder800p", .flags = DEVICE_ISA, - .local = EGA_ATI, + .local = EGA_ATI800P, .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = atiega_standalone_available }, + { .available = atiega800p_standalone_available }, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 4b67108911..0cb1216ad8 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -47,29 +47,30 @@ ega_display_line(ega_t *ega) void ega_render_blank(ega_t *ega) { - int xx; - if ((ega->displine + ega->y_add) < 0) return; for (int x = 0; x < (ega->hdisp + ega->scrollcache); x++) { switch (ega->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) + for (uint8_t xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0; break; case 1: - for (xx = 0; xx < 8; xx++) + for (uint8_t xx = 0; xx < 8; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 8) + xx] = 0; break; case 8: - for (xx = 0; xx < 18; xx++) + for (uint8_t xx = 0; xx < 18; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 18) + xx] = 0; break; case 9: - for (xx = 0; xx < 16; xx++) + for (uint8_t xx = 0; xx < 16; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 16) + xx] = 0; break; + + default: + break; } } } @@ -114,16 +115,24 @@ ega_render_text(ega_t *ega) ega->lastline_draw = ega->displine; if (ega->fullchange) { - const bool doublewidth = ((ega->seqregs[1] & 8) != 0); - const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); const bool attrlinechars = (ega->attrregs[0x10] & 4); - const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); - const bool seq9dot = ((ega->seqregs[1] & 1) == 0); - const int dwshift = doublewidth ? 1 : 0; - const int dotwidth = 1 << dwshift; - const int charwidth = dotwidth*(seq9dot ? 9 : 8); - const bool blinked = ega->blink & 0x10; - uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth * (seq9dot ? 9 : 8); + const bool blinked = ega->blink & 0x10; + uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + + /* Compensate for 8dot scroll */ + if (!seq9dot) { + for (int x = 0; x < dotwidth; x++) { + p[x] = ega->overscan_color; + } + p += dotwidth; + } for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; @@ -166,7 +175,7 @@ ega_render_text(ega_t *ega) dat |= (dat >> 1) & 1; for (int xx = 0; xx < charwidth; xx++) - p[xx] = (dat & (0x100 >> (xx>>dwshift))) ? fg : bg; + p[xx] = (dat & (0x100 >> (xx >> dwshift))) ? fg : bg; ega->ma += 4; p += charwidth; @@ -185,28 +194,38 @@ ega_render_graphics(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - const bool doublewidth = ((ega->seqregs[1] & 8) != 0); - const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0); - const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); - const bool blinked = ega->blink & 0x10; - const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); - const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); - const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0); - uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - const int dwshift = doublewidth ? 1 : 0; - const int dotwidth = 1 << dwshift; - const int charwidth = dotwidth*8; - int secondcclk = 0; + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool cga2bpp = ((ega->gdcreg[5] & 0x20) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool blinked = ega->blink & 0x10; + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); + const bool seqoddeven = ((ega->seqregs[1] & 4) != 0); + const uint8_t blinkmask = (attrblink && blinked ? 0x8 : 0x0); + uint32_t *p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth * 8; + int secondcclk = 0; + + /* Compensate for 8dot scroll */ + if (!seq9dot) { + for (int x = 0; x < dotwidth; x++) { + p[x] = ega->overscan_color; + } + p += dotwidth; + } + for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; uint8_t edat[4]; if (seqoddeven) { // FIXME: Verify the behaviour of planes 1,3 on actual hardware - edat[0] = ega->vram[(addr | 0) ^ secondcclk]; - edat[1] = ega->vram[(addr | 1) ^ secondcclk]; - edat[2] = ega->vram[(addr | 2) ^ secondcclk]; - edat[3] = ega->vram[(addr | 3) ^ secondcclk]; + edat[0] = ega->vram[(addr | 0) ^ secondcclk]; + edat[1] = ega->vram[(addr | 1) ^ secondcclk]; + edat[2] = ega->vram[(addr | 2) ^ secondcclk]; + edat[3] = ega->vram[(addr | 3) ^ secondcclk]; secondcclk = (secondcclk + 1) & 1; if (secondcclk == 0) ega->ma += 4; @@ -218,25 +237,25 @@ ega_render_graphics(ega_t *ega) if (cga2bpp) { // Remap CGA 2bpp-chunky data into fully planar data - uint8_t dat0 = egaremap2bpp[edat[1] ] | (egaremap2bpp[edat[0] ] << 4); - uint8_t dat1 = egaremap2bpp[edat[1]>>1] | (egaremap2bpp[edat[0]>>1] << 4); - uint8_t dat2 = egaremap2bpp[edat[3] ] | (egaremap2bpp[edat[2] ] << 4); - uint8_t dat3 = egaremap2bpp[edat[3]>>1] | (egaremap2bpp[edat[2]>>1] << 4); - edat[0] = dat0; - edat[1] = dat1; - edat[2] = dat2; - edat[3] = dat3; + uint8_t dat0 = egaremap2bpp[edat[1]] | (egaremap2bpp[edat[0]] << 4); + uint8_t dat1 = egaremap2bpp[edat[1] >> 1] | (egaremap2bpp[edat[0] >> 1] << 4); + uint8_t dat2 = egaremap2bpp[edat[3]] | (egaremap2bpp[edat[2]] << 4); + uint8_t dat3 = egaremap2bpp[edat[3] >> 1] | (egaremap2bpp[edat[2] >> 1] << 4); + edat[0] = dat0; + edat[1] = dat1; + edat[2] = dat2; + edat[3] = dat3; } if (!crtcreset) { for (int i = 0; i < 8; i += 2) { const int outoffs = i << dwshift; const int inshift = 6 - i; - uint8_t dat = (edatlookup[(edat[0] >> inshift) & 3][(edat[1] >> inshift) & 3] ) - | (edatlookup[(edat[2] >> inshift) & 3][(edat[3] >> inshift) & 3] << 2); + uint8_t dat = (edatlookup[(edat[0] >> inshift) & 3][(edat[1] >> inshift) & 3]) + | (edatlookup[(edat[2] >> inshift) & 3][(edat[3] >> inshift) & 3] << 2); // FIXME: Confirm blink behaviour is actually XOR on real hardware uint32_t p0 = ega->pallook[ega->egapal[((dat >> 4) & ega->plane_mask) ^ blinkmask]]; - uint32_t p1 = ega->pallook[ega->egapal[(dat & ega->plane_mask) ^ blinkmask]]; + uint32_t p1 = ega->pallook[ega->egapal[(dat & ega->plane_mask) ^ blinkmask]]; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; for (int subx = 0; subx < dotwidth; subx++) diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index 28e3a0f024..97da08822c 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -14,11 +14,13 @@ * * Copyright 2016-2018 Miran Grca. */ -#include +#include #include +#include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> #include <86box/mca.h> @@ -40,7 +42,12 @@ typedef struct { rom_t bios_rom; + uint8_t pel_wd; uint8_t banking; + uint8_t reg_3d8; + uint8_t reg_3bf; + uint8_t tries; + uint8_t ext_enable; } et3000_t; static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 }; @@ -48,27 +55,130 @@ static video_timings_t timing_et3000_isa = { VIDEO_ISA, 3, 3, 6, 5, 5, 10 }; static uint8_t et3000_in(uint16_t addr, void *priv); static void et3000_out(uint16_t addr, uint8_t val, void *priv); +#ifdef ENABLE_ET3000_LOG +int svga_do_log = ENABLE_ET3000_LOG; + +static void +et3000_log(const char *fmt, ...) +{ + va_list ap; + + if (et3000_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define et3000_log(fmt, ...) +#endif + static uint8_t et3000_in(uint16_t addr, void *priv) { et3000_t *dev = (et3000_t *) priv; svga_t *svga = &dev->svga; + uint8_t ret = 0xff; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((addr >= 0x03b0) && (addr < 0x03bc) && (svga->miscout & 1)) + return 0xff; + + if ((addr >= 0x03d0) && (addr < 0x03dc) && !(svga->miscout & 1)) + return 0xff; switch (addr) { + default: + ret = svga_in(addr, svga); + +#ifdef ENABLE_ET3000_LOG + if (addr != 0x03da) + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); +#endif + break; + + case 0x3c1: + /* It appears the extended attribute registers are **NOT** + protected by key on the ET3000AX, as the BIOS attempts to + write to attribute register 16h without the key. */ + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->attraddr, ret, dev->ext_enable); + break; + + case 0x3c5: + if ((svga->seqaddr >= 6) && !dev->ext_enable) + ret = 0xff; + else + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->seqaddr, ret, dev->ext_enable); + break; + + case 0x3cf: + if ((svga->gdcaddr >= 0x0d) && !dev->ext_enable) + ret = 0xff; + else + ret = svga_in(addr, svga); + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X (%i)\n", CS, cpu_state.pc, + addr, svga->gdcaddr & 15, ret, dev->ext_enable); + break; + + case 0x3cb: /*PEL Address/Data Wd*/ + ret = dev->pel_wd; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + case 0x3cd: /*Banking*/ - return dev->banking; + ret = dev->banking; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + case 0x3b4: case 0x3d4: - return svga->crtcreg; + ret = svga->crtcreg; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + case 0x3b5: case 0x3d5: - return svga->crtc[svga->crtcreg]; + if ((svga->crtcreg >= 0x18) && (svga->crtcreg < 0x23) && !dev->ext_enable) + ret = 0xff; + else if (svga->crtcreg > 0x25) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + et3000_log("[%04X:%08X] [R] %04X: %02X = %02X\n", CS, cpu_state.pc, + addr, svga->crtcreg, ret); + break; + + case 0x3b8: + case 0x3d8: + ret = dev->reg_3d8; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; + + case 0x3ba: + case 0x3da: + svga->attrff = 0; + + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + + ret = svga->cgastat; + + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; + break; + + case 0x3bf: + ret = dev->reg_3bf; + et3000_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + break; } - return svga_in(addr, svga); + return ret; } static void @@ -77,62 +187,192 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) et3000_t *dev = (et3000_t *) priv; svga_t *svga = &dev->svga; uint8_t old; + uint8_t index; + + et3000_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + if ((addr >= 0x03b0) && (addr < 0x03bc) && (svga->miscout & 1)) + return; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((addr >= 0x03d0) && (addr < 0x03dc) && !(svga->miscout & 1)) + return; switch (addr) { case 0x3c0: - case 0x3c1: + /* It appears the extended attribute registers are **NOT** + protected by key on the ET3000AX, as the BIOS attempts to + write to attribute register 16h without the key. */ + if (svga->attrff && (svga->attraddr == 0x11) && (svga->attrregs[0x16] & 0x01)) + val = (val & 0xf0) | (svga->attrregs[0x11] & 0x0f); +#ifdef ENABLE_ET3000_LOG + if (svga->attrff && (svga->attraddr > 0x14)) + et3000_log("3C1: %02X = %02X\n", svga->attraddr, val); +#endif if (svga->attrff && (svga->attraddr == 0x16)) { svga->attrregs[0x16] = val; svga->chain4 &= ~0x10; if (svga->gdcreg[5] & 0x40) svga->chain4 |= (svga->attrregs[0x16] & 0x10); svga_recalctimings(svga); + return; } break; + case 0x3c1: + return; + + case 0x3c2: + svga->miscout = val; + svga->vidclock = val & 4; + svga_recalctimings(svga); + return; + case 0x3c4: + svga->seqaddr = val & 0x07; + return; case 0x3c5: + if ((svga->seqaddr >= 6) && !dev->ext_enable) + return; + if (svga->seqaddr == 4) { svga->seqregs[4] = val; svga->chain2_write = !(val & 4); svga->chain4 = (svga->chain4 & ~8) | (val & 8); - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); + et3000_log("CHAIN2 = %i, CHAIN4 = %i\n", svga->chain2_write, svga->chain4); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && svga->chain4 && + !(svga->adv_flags & FLAG_ADDR_BY8); return; } +#ifdef ENABLE_ET3000_LOG + else if (svga->seqaddr > 4) + et3000_log("3C5: %02X = %02X\n", svga->seqaddr, val); +#endif break; - case 0x3cf: - if ((svga->gdcaddr & 15) == 5) { - svga->chain4 &= ~0x10; - if (val & 0x40) - svga->chain4 |= (svga->attrregs[0x16] & 0x10); + case 0x3c9: + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = svga->monitor->mon_changeframecount; + switch (svga->dac_pos) { + case 0: + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 255; + if (!(svga->attrregs[0x16] & 0x02) && !(svga->attrregs[0x17] & 0x80)) { + svga->dac_b = val; + svga->vgapal[index].r = svga->dac_r; + svga->vgapal[index].g = svga->dac_g; + svga->vgapal[index].b = svga->dac_b; + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, + svga->vgapal[index].b); + else + svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], + video_6to8[svga->vgapal[index].g & 0x3f], + video_6to8[svga->vgapal[index].b & 0x3f]); + } + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + + default: + break; } + return; + + case 0x3cb: /*PEL Address/Data Wd*/ + et3000_log("3CB = %02X\n", val); + dev->pel_wd = val; break; case 0x3cd: /*Banking*/ - dev->banking = val; + et3000_log("3CD = %02X\n", val); if (!(svga->crtc[0x23] & 0x80) && !(svga->gdcreg[6] & 0x08)) { switch ((val >> 6) & 3) { case 0: /*128K segments*/ - svga->write_bank = (val & 7) << 17; + svga->write_bank = ((val >> 0) & 7) << 17; svga->read_bank = ((val >> 3) & 7) << 17; break; case 1: /*64K segments*/ svga->write_bank = (val & 7) << 16; svga->read_bank = ((val >> 3) & 7) << 16; break; + + default: + break; } } + dev->banking = val; + return; + + case 0x3ce: + svga->gdcaddr = val & 0x0f; return; + case 0x3cf: + if ((svga->gdcaddr >= 0x0d) && !dev->ext_enable) + return; + + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x10; + if (val & 0x40) + svga->chain4 |= (svga->attrregs[0x16] & 0x10); + } else if ((svga->gdcaddr & 15) == 6) { + if (!(svga->crtc[0x23] & 0x80) && !(val & 0x08)) { + switch ((dev->banking >> 6) & 3) { + case 0: /*128K segments*/ + svga->write_bank = ((dev->banking >> 0) & 7) << 17; + svga->read_bank = ((dev->banking >> 3) & 7) << 17; + break; + case 1: /*64K segments*/ + svga->write_bank = (dev->banking & 7) << 16; + svga->read_bank = ((dev->banking >> 3) & 7) << 16; + break; + + default: + break; + } + } else + svga->write_bank = svga->read_bank = 0; + + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /* Override mask - ET3000 supports linear 128k at A0000. */ + svga->banked_mask = 0x1ffff; + } + return; + } +#ifdef ENABLE_ET3000_LOG + else if ((svga->gdcaddr & 15) > 8) + et3000_log("3CF: %02X = %02X\n", (svga->gdcaddr & 15), val); +#endif + break; + case 0x3b4: case 0x3d4: svga->crtcreg = val & 0x3f; return; + case 0x3b5: case 0x3d5: + if ((svga->crtcreg >= 0x18) && (svga->crtcreg < 0x23) && !dev->ext_enable) + return; + else if (svga->crtcreg > 0x25) + return; + + /* Unlike the ET4000AX, which protects all bits of the + overflow high register (0x35 there, 0x25 here) except for + bits 4 and 7, if bit 7 of CRTC 11h is set, the ET3000AX + does not to that. */ if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -140,6 +380,11 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; +#ifdef ENABLE_ET3000_LOG + if (svga->crtcreg > 0x18) + et3000_log("3D5: %02X = %02X\n", svga->crtcreg, val); +#endif + if (old != val) { if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; @@ -147,6 +392,30 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) } } break; + + case 0x3b8: + case 0x3d8: + et3000_log("%04X = %02X\n", addr, val); + dev->reg_3d8 = val; + if ((val == 0xa0) && (dev->tries == 1)) { + dev->ext_enable = 1; + dev->tries = 0; + } else if (val == 0x29) + dev->tries = 1; + return; + + case 0x3bf: + et3000_log("%04X = %02X\n", addr, val); + dev->reg_3bf = val; + if ((val == 0x01) && (dev->tries == 1)) { + dev->ext_enable = 0; + dev->tries = 0; + } else if (val == 0x03) + dev->tries = 1; + return; + + default: + break; } svga_out(addr, val, svga); @@ -184,11 +453,14 @@ et3000_recalctimings(svga_t *svga) case 0x60: svga->render = svga_render_8bpp_highres; break; + + default: + break; } } - /* pclog("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n", - svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); */ + et3000_log("HDISP = %i, HTOTAL = %i, ROWOFFSET = %i, INTERLACE = %i\n", + svga->hdisp, svga->htotal, svga->rowoffset, svga->interlace); switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x24] << 1) & 4)) { case 0: @@ -224,12 +496,15 @@ et3000_init(const device_t *info) svga_init(info, &dev->svga, dev, device_get_config_int("memory") << 10, et3000_recalctimings, et3000_in, et3000_out, NULL, NULL); - io_sethandler(0x03c0, 32, + io_sethandler(0x03b0, 48, et3000_in, NULL, NULL, et3000_out, NULL, NULL, dev); break; + + default: + break; } - rom_init(&dev->bios_rom, (char *) fn, + rom_init(&dev->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); dev->svga.bpp = 8; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index b4c505daea..5fe524fd8e 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -52,18 +52,22 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#define ET4000_TYPE_TC6058AF 0 /* ISA ET4000AX (TC6058AF) */ #define ET4000_TYPE_ISA 1 /* ISA ET4000AX */ #define ET4000_TYPE_MCA 2 /* MCA ET4000AX */ #define ET4000_TYPE_KOREAN 3 /* Korean ET4000 */ #define ET4000_TYPE_TRIGEM 4 /* Trigem 286M ET4000 */ #define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */ -#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" -#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" -#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" -#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" -#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" +#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" +#define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin" +#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" +#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" +#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" +#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" typedef struct { const char *name; @@ -105,14 +109,15 @@ static const uint8_t crtc_mask[0x40] = { static video_timings_t timing_et4000_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_et4000_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; -static void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); -static uint8_t et4000_kasan_in(uint16_t addr, void *p); +static void et4000_kasan_out(uint16_t addr, uint8_t val, void *priv); +static uint8_t et4000_kasan_in(uint16_t addr, void *priv); static uint8_t et4000_in(uint16_t addr, void *priv) { et4000_t *dev = (et4000_t *) priv; svga_t *svga = &dev->svga; + uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -136,7 +141,8 @@ et4000_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - return sc1502x_ramdac_in(addr, svga->ramdac, svga); + if (dev->type >= ET4000_TYPE_ISA) + return sc1502x_ramdac_in(addr, svga->ramdac, svga); case 0x3cd: /*Banking*/ return dev->banking; @@ -146,6 +152,29 @@ et4000_in(uint16_t addr, void *priv) case 0x3d5: return svga->crtc[svga->crtcreg]; + + case 0x3da: + svga->attrff = 0; + + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + + ret = svga->cgastat; + + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; + + if (ret & 0x08) + ret &= 0x7f; + else + ret |= 0x80; + + return ret; + + default: + break; } return svga_in(addr, svga); @@ -215,17 +244,88 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) et4000_t *dev = (et4000_t *) priv; svga_t *svga = &dev->svga; uint8_t old; + uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { + case 0x3c0: + case 0x3c1: + if (!svga->attrff) { + svga->attraddr = val & 0x1f; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) + svga->fullchange = svga->monitor->mon_changeframecount; + old = svga->attrregs[svga->attraddr & 0x1f]; + svga->attrregs[svga->attraddr & 0x1f] = val; + if (svga->attraddr < 0x10) + svga->fullchange = svga->monitor->mon_changeframecount; + + if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) { + for (int c = 0; c < 0x10; c++) { + if (svga->attrregs[0x10] & 0x80) + svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else if (svga->ati_4color) + svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)]; + else + svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + svga->fullchange = svga->monitor->mon_changeframecount; + } + /* Recalculate timings on change of attribute register 0x11 + (overscan border color) too. */ + if (svga->attraddr == 0x10) { + svga->chain4 &= ~0x02; + if ((val & 0x40) && (svga->attrregs[0x10] & 0x40)) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + if (old != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x11) { + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + if (old != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = svga->monitor->mon_changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + return; + + case 0x3c5: + if (svga->seqaddr == 4) { + svga->seqregs[4] = val; + + svga->chain2_write = !(val & 4); + svga->chain4 = (svga->chain4 & ~8) | (val & 8); + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8); + return; + } else if (svga->seqaddr == 0x0e) { + svga->seqregs[0x0e] = val; + svga->chain4 &= ~0x02; + if ((svga->gdcreg[5] & 0x40) && svga->lowres) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + svga_recalctimings(svga); + return; + } + break; + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - return; + if (dev->type >= ET4000_TYPE_ISA) { + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + break; case 0x3cd: /*Banking*/ if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { @@ -236,7 +336,11 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) return; case 0x3cf: - if ((svga->gdcaddr & 15) == 6) { + if ((svga->gdcaddr & 15) == 5) { + svga->chain4 &= ~0x02; + if ((val & 0x40) && svga->lowres) + svga->chain4 |= (svga->seqregs[0x0e] & 0x02); + } else if ((svga->gdcaddr & 15) == 6) { if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { svga->write_bank = (dev->banking & 0x0f) * 0x10000; svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; @@ -288,6 +392,9 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); @@ -359,8 +466,8 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv) static uint8_t et4000_kasan_in(uint16_t addr, void *priv) { - et4000_t *et4000 = (et4000_t *) priv; - uint8_t val = 0xFF; + const et4000_t *et4000 = (et4000_t *) priv; + uint8_t val = 0xFF; if (addr == 0x258) { val = et4000->kasan_cfg_index; @@ -410,7 +517,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) break; case 1: case 2: - et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + if ((et4000->kasan_cfg_index - 0xF0) <= 16) + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); @@ -425,6 +533,7 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) case 5: et4000->kasan_cfg_regs[5] = val; et4000->svga.ksc5601_english_font_type = 0x100 | val; + fallthrough; case 6: case 7: et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; @@ -454,7 +563,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) case 4: case 5: if (et4000->kasan_cfg_regs[0] & 1) { - et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; + if ((addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)) <= 4) + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; } break; case 6: @@ -474,10 +584,10 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) } uint32_t -get_et4000_addr(uint32_t addr, void *p) +get_et4000_addr(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - uint32_t nbank; + const svga_t *svga = (svga_t *) priv; + uint32_t nbank; switch (svga->crtc[0x37] & 0x0B) { case 0x00: @@ -536,25 +646,30 @@ get_et4000_addr(uint32_t addr, void *p) static void et4000_recalctimings(svga_t *svga) { - et4000_t *dev = (et4000_t *) svga->p; + const et4000_t *dev = (et4000_t *) svga->priv; svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + if (svga->crtc[0x35] & 1) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 2) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 4) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 8) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (!svga->rowoffset) svga->rowoffset = 0x100; if (svga->crtc[0x3f] & 1) - svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) + svga->htotal |= 0x100; + if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: @@ -575,10 +690,15 @@ et4000_recalctimings(svga_t *svga) case 15: case 16: svga->hdisp /= 2; + svga->dots_per_clock /= 2; break; case 24: svga->hdisp /= 3; + svga->dots_per_clock /= 3; + break; + + default: break; } @@ -593,17 +713,39 @@ et4000_recalctimings(svga_t *svga) } } } + + if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x40)) { + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + } + + if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40) && svga->lowres) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + svga->render = svga_render_8bpp_highres; + } + + if (dev->type == ET4000_TYPE_TC6058AF) { + if (svga->render == svga_render_8bpp_lowres) + svga->render = svga_render_8bpp_tseng_lowres; + else if (svga->render == svga_render_8bpp_highres) + svga->render = svga_render_8bpp_tseng_highres; + } } static void et4000_kasan_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *) svga->p; + const et4000_t *et4000 = (et4000_t *) svga->priv; et4000_recalctimings(svga); if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { - svga->ma_latch -= 3; + svga->hdisp += svga->dots_per_clock; + svga->ma_latch -= 4; svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) @@ -614,7 +756,7 @@ et4000_kasan_recalctimings(svga_t *svga) static uint8_t et4000_mca_read(int port, void *priv) { - et4000_t *et4000 = (et4000_t *) priv; + const et4000_t *et4000 = (et4000_t *) priv; return (et4000->pos_regs[port & 7]); } @@ -633,7 +775,7 @@ et4000_mca_write(int port, uint8_t val, void *priv) } static uint8_t -et4000_mca_feedb(void *priv) +et4000_mca_feedb(UNUSED(void *priv)) { return 1; } @@ -652,6 +794,7 @@ et4000_init(const device_t *info) fn = BIOS_ROM_PATH; switch (dev->type) { + case ET4000_TYPE_TC6058AF: /* ISA ET4000AX (TC6058AF) */ case ET4000_TYPE_ISA: /* ISA ET4000AX */ dev->vram_size = device_get_config_int("memory") << 10; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); @@ -660,6 +803,8 @@ et4000_init(const device_t *info) NULL, NULL); io_sethandler(0x03c0, 32, et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + if (dev->type == ET4000_TYPE_TC6058AF) + fn = TC6058AF_BIOS_ROM_PATH; break; case ET4000_TYPE_MCA: /* MCA ET4000AX */ @@ -734,13 +879,17 @@ et4000_init(const device_t *info) loadfont(KASAN_FONT_ROM_PATH, 6); fn = KASAN_BIOS_ROM_PATH; break; + + default: + break; } - dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + if (dev->type >= ET4000_TYPE_ISA) + dev->svga.ramdac = device_add(&sc1502x_ramdac_device); dev->vram_mask = dev->vram_size - 1; - rom_init(&dev->bios_rom, (char *) fn, + rom_init(&dev->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); dev->svga.translate_address = get_et4000_addr; @@ -776,6 +925,12 @@ et4000_force_redraw(void *priv) dev->svga.fullchange = changeframecount; } +static int +et4000_tc6058af_available(void) +{ + return rom_present(TC6058AF_BIOS_ROM_PATH); +} + static int et4000_available(void) { @@ -794,6 +949,33 @@ et4000_kasan_available(void) return rom_present(KASAN_BIOS_ROM_PATH) && rom_present(KASAN_FONT_ROM_PATH); } +static const device_config_t et4000_tc6058af_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +// clang-format on +}; + static const device_config_t et4000_config[] = { // clang-format off { @@ -825,6 +1007,20 @@ static const device_config_t et4000_config[] = { // clang-format on }; +const device_t et4000_tc6058af_isa_device = { + .name = "Tseng Labs ET4000AX (TC6058AF) (ISA)", + .internal_name = "et4000ax_tc6058af", + .flags = DEVICE_ISA, + .local = 0, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, + { .available = et4000_tc6058af_available }, + .speed_changed = et4000_speed_changed, + .force_redraw = et4000_force_redraw, + .config = et4000_tc6058af_config +}; + const device_t et4000_isa_device = { .name = "Tseng Labs ET4000AX (ISA)", .internal_name = "et4000ax", diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index e9ea4d111c..39b5b9ecc5 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -69,7 +69,7 @@ typedef struct et4000w32p_t { svga_t svga; - uint8_t banking, banking2, adjust_cursor, rev; + uint8_t banking, banking2, adjust_cursor, rev, pci_slot; uint8_t regs[256], pci_regs[256]; @@ -130,14 +130,14 @@ static video_timings_t timing_et4000w32_isa = { .type = VIDEO_ISA, .write_b = 4, void et4000w32p_recalcmapping(et4000w32p_t *et4000); -static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); -static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); +static uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv); +static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv); static void et4000w32_blit_start(et4000w32p_t *et4000); static void et4000w32p_blit_start(et4000w32p_t *et4000); static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000); static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); -uint8_t et4000w32p_in(uint16_t addr, void *p); +uint8_t et4000w32p_in(uint16_t addr, void *priv); #ifdef ENABLE_ET4000W32_LOG int et4000w32_do_log = ENABLE_ET4000W32_LOG; @@ -158,9 +158,9 @@ et4000w32_log(const char *fmt, ...) #endif void -et4000w32p_out(uint16_t addr, uint8_t val, void *p) +et4000w32p_out(uint16_t addr, uint8_t val, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; uint8_t old; uint32_t add2addr = 0; @@ -210,6 +210,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->gdcreg[svga->gdcaddr & 15] = val; et4000w32p_recalcmapping(et4000); return; + + default: + break; } break; case 0x3d4: @@ -277,7 +280,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); svga->hwcursor.xoff = et4000->regs[0xE2]; svga->hwcursor.yoff = et4000->regs[0xE6]; - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && et4000->regs[0xe2] && et4000->regs[0xe6])) ? 128 : 64; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && (et4000->regs[0xe2] >= 0x1f) && (et4000->regs[0xe6] >= 0x1f))) ? 128 : 64; if (et4000->type == ET4000W32) { if ((svga->bpp == 15) || (svga->bpp == 16)) { @@ -290,6 +293,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) case 8: svga->hwcursor.xoff += 32; break; + + default: + break; } } @@ -315,15 +321,18 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16); svga->hwcursor.addr += add2addr; return; + + default: + break; } svga_out(addr, val, svga); } uint8_t -et4000w32p_in(uint16_t addr, void *p) +et4000w32p_in(uint16_t addr, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -343,7 +352,6 @@ et4000w32p_in(uint16_t addr, void *p) return sdac_ramdac_in(addr, 0, svga->ramdac, svga); else return stg_ramdac_in(addr, svga->ramdac, svga); - break; case 0x3cb: return et4000->banking2; @@ -409,6 +417,9 @@ et4000w32p_in(uint16_t addr, void *p) return (et4000->regs[0xef] & 0x8f) | (et4000->rev << 4) | et4000->vlb; } return et4000->regs[et4000->index]; + + default: + break; } return svga_in(addr, svga); @@ -417,25 +428,30 @@ et4000w32p_in(uint16_t addr, void *p) void et4000w32p_recalctimings(svga_t *svga) { - et4000w32p_t *et4000 = (et4000w32p_t *) svga->p; + et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv; svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; + + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + if (svga->crtc[0x35] & 0x01) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x35] & 0x02) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x35] & 0x04) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x35] & 0x08) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; + svga->split |= 0x400; if (svga->crtc[0x3F] & 0x80) - svga->rowoffset += 0x100; + svga->rowoffset |= 0x100; if (svga->crtc[0x3F] & 0x01) - svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) + svga->htotal |= 0x100; + if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); @@ -453,31 +469,10 @@ et4000w32p_recalctimings(svga_t *svga) case 24: svga->clock /= 4; break; - } - } - } - } - - if (svga->adv_flags & FLAG_NOSKEW) { - /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ - svga->ma_latch--; - if (svga->seqregs[1] & 8) /*40 column*/ - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else { - /* Also adjust the graphics mode clocks in some cases. */ - if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) { - if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else if ((svga->gdcreg[5] & 0x40) == 0) { - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - if (svga->hdisp == 648 || svga->hdisp == 808 || svga->hdisp == 1032) - svga->hdisp -= 8; + default: + break; + } } } } @@ -491,6 +486,9 @@ et4000w32p_recalctimings(svga_t *svga) break; svga->hdisp -= 24; break; + + default: + break; } } } @@ -501,7 +499,10 @@ et4000w32p_recalctimings(svga_t *svga) switch (svga->bpp) { case 15: case 16: - svga->hdisp >>= 1; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } if (et4000->type <= ET4000W32P_REVC) { if (et4000->type == ET4000W32P_REVC) { if (svga->hdisp != 1024) @@ -512,12 +513,16 @@ et4000w32p_recalctimings(svga_t *svga) break; case 24: svga->hdisp /= 3; + svga->dots_per_clock /= 3; if (et4000->type <= ET4000W32P_REVC) et4000->adjust_cursor = 2; - if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640 / 2 || svga->hdisp == 1232)) { + if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) { svga->hdisp = 640; } break; + + default: + break; } svga->render = svga_render_blank; @@ -528,15 +533,8 @@ et4000w32p_recalctimings(svga_t *svga) else svga->render = svga_render_text_80; } else { - if (svga->adv_flags & FLAG_NOSKEW) { - svga->ma_latch--; - } - switch (svga->gdcreg[5] & 0x60) { case 0x00: - if (et4000->rev == 5) - svga->ma_latch++; - if (svga->seqregs[1] & 8) /* Low res (320) */ svga->render = svga_render_4bpp_lowres; else @@ -591,8 +589,14 @@ et4000w32p_recalctimings(svga_t *svga) else svga->render = svga_render_32bpp_highres; break; + + default: + break; } break; + + default: + break; } } } @@ -667,6 +671,9 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } @@ -833,6 +840,9 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) case 0xaf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); break; + + default: + break; } } @@ -899,9 +909,9 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin } static void -et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) +et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; switch (addr & 0x6000) { @@ -968,17 +978,23 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) case 0x31: et4000->acl.osr = val; break; + + default: + break; } } break; + + default: + break; } } static uint8_t -et4000w32p_mmu_read(uint32_t addr, void *p) +et4000w32p_mmu_read(uint32_t addr, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; - svga_t *svga = &et4000->svga; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; + const svga_t *svga = &et4000->svga; uint8_t temp; switch (addr & 0x6000) { @@ -1073,9 +1089,7 @@ et4000w32p_mmu_read(uint32_t addr, void *p) case 0x8e: if (et4000->type >= ET4000W32P_REVC) return et4000->acl.internal.pixel_depth; - else - return et4000->acl.internal.vbus; - break; + return et4000->acl.internal.vbus; case 0x8f: return et4000->acl.internal.xy_dir; case 0x90: @@ -1106,9 +1120,15 @@ et4000w32p_mmu_read(uint32_t addr, void *p) return et4000->acl.internal.dest_addr >> 16; case 0xa3: return et4000->acl.internal.dest_addr >> 24; + + default: + break; } return 0xff; + + default: + break; } return 0xff; @@ -2084,7 +2104,7 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4 uint8_t source; uint8_t dest; uint8_t rop; - uint8_t out; + uint8_t out = 0; int mixmap; if (!(et4000->acl.status & ACL_XYST) && !et4000->acl.mmu_start) { @@ -2341,6 +2361,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 case 7: /* X- */ et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); break; + + default: + break; } et4000->acl.internal.error += et4000->acl.internal.dmin; if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { @@ -2366,6 +2389,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 et4000w32_decy(et4000); et4000->acl.internal.pos_y++; break; + + default: + break; } } if ((et4000->acl.internal.pos_x > et4000->acl.internal.count_x) || (et4000->acl.internal.pos_y > et4000->acl.internal.count_y)) { @@ -2453,16 +2479,17 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { - et4000w32p_t *et4000 = (et4000w32p_t *) svga->p; - int offset; - int xx; - int xx2; - int shift = (et4000->adjust_cursor + 1); - int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff); - int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16; - int x_acc = 4; - int minus_width = 0; - uint8_t dat; + const et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv; + int offset; + int xx; + int xx2; + int shift = (et4000->adjust_cursor + 1); + int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff); + int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16; + int x_acc = 4; + int minus_width = 0; + uint8_t dat; + offset = svga->hwcursor_latch.xoff; if ((et4000->type == ET4000W32) && (pitch == 32)) { @@ -2476,6 +2503,9 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine) minus_width = 64; x_acc = 2; break; + + default: + break; } } @@ -2559,9 +2589,12 @@ et4000w32p_io_set(et4000w32p_t *et4000) } uint8_t -et4000w32p_pci_read(int func, int addr, void *p) +et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + const et4000w32p_t *et4000 = (et4000w32p_t *) priv; + + if (func > 0) + return 0xff; addr &= 0xff; @@ -2609,17 +2642,23 @@ et4000w32p_pci_read(int func, int addr, void *p) return 0x00; case 0x33: return et4000->pci_regs[0x33] & 0xf0; + + default: + break; } return 0; } void -et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) +et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; + if (func > 0) + return; + addr &= 0xff; switch (addr) { @@ -2660,6 +2699,9 @@ et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&et4000->bios_rom.mapping); } return; + + default: + break; } } @@ -2740,7 +2782,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_REVC: @@ -2765,7 +2806,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_CARDEX: @@ -2778,7 +2818,6 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; break; case ET4000W32P_DIAMOND: @@ -2792,6 +2831,9 @@ et4000w32p_init(const device_t *info) et4000->svga.clock_gen = device_add(&icd2061_device); et4000->svga.getclock = icd2061_getclock; break; + + default: + break; } if (info->flags & DEVICE_PCI) mem_mapping_disable(&et4000->bios_rom.mapping); @@ -2802,7 +2844,7 @@ et4000w32p_init(const device_t *info) et4000w32p_io_set(et4000); if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); + pci_add_card(PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot); /* Hardwired bits: 00000000 1xx0x0xx */ /* R/W bits: xx xxxx */ @@ -2873,9 +2915,9 @@ et4000w32p_cardex_available(void) } void -et4000w32p_close(void *p) +et4000w32p_close(void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_close(&et4000->svga); @@ -2883,17 +2925,17 @@ et4000w32p_close(void *p) } void -et4000w32p_speed_changed(void *p) +et4000w32p_speed_changed(void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_recalctimings(&et4000->svga); } void -et4000w32p_force_redraw(void *p) +et4000w32p_force_redraw(void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) p; + et4000w32p_t *et4000 = (et4000w32p_t *) priv; et4000->svga.fullchange = changeframecount; } diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index d2fd22dce4..772926e1e0 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -24,12 +24,12 @@ * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * Lubomir Rintel, * * Copyright 2018-2019 Fred N. van Kempen. * Copyright 2018-2019 Miran Grca. - * Copyright 2018-2019 Sarah Walker. + * Copyright 2018-2019 John Elliott. * Copyright 2021 Lubomir Rintel. * * This program is free software; you can redistribute it and/or modify @@ -39,7 +39,7 @@ * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -63,6 +63,7 @@ #include "cpu.h" #include <86box/video.h> #include <86box/vid_cga.h> +#include <86box/plat_unused.h> #define F82C425_XSIZE 640 #define F82C425_YSIZE 200 @@ -226,9 +227,9 @@ f82c425_colormap(f82c425_t *f82c425) } static void -f82c425_out(uint16_t addr, uint8_t val, void *p) +f82c425_out(uint16_t addr, uint8_t val, void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; if (addr == 0x3d4) f82c425->crtcreg = val; @@ -267,13 +268,16 @@ f82c425_out(uint16_t addr, uint8_t val, void *p) f82c425_smartmap(f82c425); f82c425_colormap(f82c425); break; + + default: + break; } } static uint8_t -f82c425_in(uint16_t addr, void *p) +f82c425_in(uint16_t addr, void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; if ((f82c425->function & 0x01) == 0) return 0xff; @@ -299,24 +303,28 @@ f82c425_in(uint16_t addr, void *p) return f82c425->timing; case 0xdf: return f82c425->function; + + default: + break; } return 0xff; } static void -f82c425_write(uint32_t addr, uint8_t val, void *p) +f82c425_write(uint32_t addr, uint8_t val, void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; f82c425->vram[addr & 0x3fff] = val; cycles -= 4; } static uint8_t -f82c425_read(uint32_t addr, void *p) +f82c425_read(uint32_t addr, void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + const f82c425_t *f82c425 = (f82c425_t *) priv; + cycles -= 4; return f82c425->vram[addr & 0x3fff]; @@ -390,12 +398,12 @@ f82c425_text_row(f82c425_t *f82c425) if (f82c425->cga.cgamode & 0x01) { /* High resolution (80 cols) */ for (c = 0; c < sl; c++) { - ((uint32_t *) buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; } } else { /* Low resolution (40 columns, stretch pixels horizontally) */ for (c = 0; c < sl; c++) { - ((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[f82c425->displine])[(x << 4) + c * 2] = (buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; } } @@ -419,7 +427,7 @@ f82c425_cgaline6(f82c425_t *f82c425) addr++; for (uint8_t c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + c] = colormap[dat & 0x80 ? 3 : 0]; + (buffer32->line[f82c425->displine])[x * 8 + c] = colormap[dat & 0x80 ? 3 : 0]; dat = dat << 1; } @@ -446,7 +454,7 @@ f82c425_cgaline4(f82c425_t *f82c425) if (!(f82c425->cga.cgamode & 0x08)) pattern = 0; - ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c] = ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c + 1] = colormap[pattern & 3]; + (buffer32->line[f82c425->displine])[x * 8 + 2 * c] = (buffer32->line[f82c425->displine])[x * 8 + 2 * c + 1] = colormap[pattern & 3]; dat = dat << 2; } @@ -454,9 +462,9 @@ f82c425_cgaline4(f82c425_t *f82c425) } static void -f82c425_poll(void *p) +f82c425_poll(void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; if (f82c425->video_options != st_video_options || !!(f82c425->function & 1) != st_enabled) { f82c425->video_options = st_video_options; @@ -505,6 +513,9 @@ f82c425_poll(void *p) case 0x01: f82c425_text_row(f82c425); break; + + default: + break; } } f82c425->displine++; @@ -560,9 +571,10 @@ f82c425_poll(void *p) } static void * -f82c425_init(const device_t *info) +f82c425_init(UNUSED(const device_t *info)) { f82c425_t *f82c425 = malloc(sizeof(f82c425_t)); + memset(f82c425, 0, sizeof(f82c425_t)); cga_init(&f82c425->cga); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_f82c425); @@ -595,18 +607,18 @@ f82c425_init(const device_t *info) } static void -f82c425_close(void *p) +f82c425_close(void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; free(f82c425->vram); free(f82c425); } static void -f82c425_speed_changed(void *p) +f82c425_speed_changed(void *priv) { - f82c425_t *f82c425 = (f82c425_t *) p; + f82c425_t *f82c425 = (f82c425_t *) priv; f82c425_recalctimings(f82c425); } diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 09f2f6adaa..4ae8e6fd19 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -10,10 +10,10 @@ * * * - * Authors: Sarah Walker, + * Authors: John Elliott, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. + * Copyright 2008-2019 John Elliott. * Copyright 2016-2019 Miran Grca. */ #include @@ -74,7 +74,7 @@ static video_timings_t timing_genius = { .type = VIDEO_ISA, .write_b = 8, .write * Two card-specific registers control text and graphics display: * * 03B0: Control register. - * Bit 0: Map all graphics framebuffer into memory. + * Bit 0: Map all graphics framebuffer into memory. * Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T. * Bit 4: Set for CGA-compatible graphics, clear for native graphics. * Bit 5: Set for black on white, clear for white on black. @@ -138,13 +138,13 @@ static uint8_t genius_pal[4]; static uint8_t mdaattr[256][2][2]; void genius_recalctimings(genius_t *genius); -void genius_write(uint32_t addr, uint8_t val, void *p); -uint8_t genius_read(uint32_t addr, void *p); +void genius_write(uint32_t addr, uint8_t val, void *priv); +uint8_t genius_read(uint32_t addr, void *priv); void -genius_out(uint16_t addr, uint8_t val, void *p) +genius_out(uint16_t addr, uint8_t val, void *priv) { - genius_t *genius = (genius_t *) p; + genius_t *genius = (genius_t *) priv; switch (addr) { case 0x3b0: /* Command / control register */ @@ -204,14 +204,17 @@ genius_out(uint16_t addr, uint8_t val, void *p) case 0x3d9: genius->cga_colour = val; return; + + default: + break; } } uint8_t -genius_in(uint16_t addr, void *p) +genius_in(uint16_t addr, void *priv) { - genius_t *genius = (genius_t *) p; - uint8_t ret = 0xff; + const genius_t *genius = (genius_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0x3b0: @@ -253,6 +256,9 @@ genius_in(uint16_t addr, void *p) case 0x3da: ret = genius->cga_stat; break; + + default: + break; } return ret; @@ -269,9 +275,9 @@ genius_waitstates(void) } void -genius_write(uint32_t addr, uint8_t val, void *p) +genius_write(uint32_t addr, uint8_t val, void *priv) { - genius_t *genius = (genius_t *) p; + genius_t *genius = (genius_t *) priv; genius_waitstates(); if (genius->genius_control & 1) { @@ -293,10 +299,11 @@ genius_write(uint32_t addr, uint8_t val, void *p) } uint8_t -genius_read(uint32_t addr, void *p) +genius_read(uint32_t addr, void *priv) { - genius_t *genius = (genius_t *) p; - uint8_t ret; + const genius_t *genius = (genius_t *) priv; + uint8_t ret; + genius_waitstates(); if (genius->genius_control & 1) { @@ -364,6 +371,9 @@ genius_lines(genius_t *genius) case 0x13: ret = 492; /* 80x41 */ break; + + default: + break; } return ret; @@ -379,7 +389,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) uint8_t attr; uint8_t sc; uint8_t ctrl; - uint8_t *crtc; + const uint8_t *crtc; uint8_t bitmap[2]; int blink; int c; @@ -390,7 +400,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) uint16_t addr; uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; - unsigned char *framebuf = genius->vram + 0x10000; + const uint8_t *framebuf = genius->vram + 0x10000; uint32_t col; uint32_t dl = genius->displine; @@ -404,13 +414,13 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) charh = 15 - (genius->genius_charh & 3); #if 0 - if (genius->genius_charh & 0x10) { - row = ((dl >> 1) / charh); - sc = ((dl >> 1) % charh); - } else { - row = (dl / charh); - sc = (dl % charh); - } + if (genius->genius_charh & 0x10) { + row = ((dl >> 1) / charh); + sc = ((dl >> 1) % charh); + } else { + row = (dl / charh); + sc = (dl % charh); + } #else row = (dl / charh); sc = (dl % charh); @@ -449,10 +459,10 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) for (int x = 0; x < w; x++) { #if 0 - if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF)) - chr = 0x00; - if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF)) - attr = 0x00; + if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF)) + chr = 0x00; + if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF)) + attr = 0x00; #endif chr = framebuf[(addr + 2 * x) & 0x3FFF]; attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; @@ -466,6 +476,9 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) case 0x60: drawcursor = drawcursor && (genius->blink & 32); break; + + default: + break; } blink = ((genius->blink & 16) && (ctrl & 0x20) && (attr & 0x80) && !drawcursor); @@ -623,9 +636,9 @@ genius_hiresline(genius_t *genius) } void -genius_poll(void *p) +genius_poll(void *priv) { - genius_t *genius = (genius_t *) p; + genius_t *genius = (genius_t *) priv; uint8_t background; if (!genius->linepos) { @@ -721,9 +734,8 @@ genius_poll(void *p) } } -void - * - genius_init(const device_t *info) +void * +genius_init(UNUSED(const device_t *info)) { genius_t *genius = malloc(sizeof(genius_t)); @@ -784,9 +796,9 @@ void } void -genius_close(void *p) +genius_close(void *priv) { - genius_t *genius = (genius_t *) p; + genius_t *genius = (genius_t *) priv; free(genius->vram); free(genius); @@ -799,9 +811,9 @@ genius_available(void) } void -genius_speed_changed(void *p) +genius_speed_changed(void *priv) { - genius_t *genius = (genius_t *) p; + genius_t *genius = (genius_t *) priv; genius_recalctimings(genius); } diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index f3ce178cd8..2a725488db 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -32,6 +32,7 @@ #include <86box/device.h> #include <86box/video.h> #include <86box/vid_hercules.h> +#include <86box/plat_unused.h> static video_timings_t timing_hercules = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -151,8 +152,8 @@ hercules_out(uint16_t addr, uint8_t val, void *priv) static uint8_t hercules_in(uint16_t addr, void *priv) { - hercules_t *dev = (hercules_t *) priv; - uint8_t ret = 0xff; + const hercules_t *dev = (hercules_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0x03b0: @@ -192,7 +193,7 @@ hercules_in(uint16_t addr, void *priv) } static void -hercules_waitstates(void *p) +hercules_waitstates(UNUSED(void *priv)) { int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; @@ -493,7 +494,9 @@ hercules_poll(void *priv) else video_blit_memtoscreen(8, dev->firstline + 14, xsize, ysize); frames++; - // if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) { +#if 0 + if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) { +#endif if (dev->ctrl & 0x02) { video_res_x = dev->crtc[1] * 16; video_res_y = dev->crtc[6] * 4; @@ -527,7 +530,7 @@ hercules_poll(void *priv) } static void * -hercules_init(const device_t *info) +hercules_init(UNUSED(const device_t *info)) { hercules_t *dev; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index a5422fbc12..429632f197 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -30,6 +30,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/plat_unused.h> /* extended CRTC registers */ #define HERCULESPLUS_CRTC_XMODE 20 /* xMode register */ @@ -138,6 +139,7 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) return; old = dev->crtc[dev->crtcreg]; dev->crtc[dev->crtcreg] = val; + if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { /*Fix for Generic Turbo XT BIOS, *which sets up cursor registers wrong*/ @@ -162,14 +164,17 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) else mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); return; + + default: + break; } } static uint8_t herculesplus_in(uint16_t port, void *priv) { - herculesplus_t *dev = (herculesplus_t *) priv; - uint8_t ret = 0xff; + const herculesplus_t *dev = (herculesplus_t *) priv; + uint8_t ret = 0xff; switch (port) { case 0x3b0: @@ -191,6 +196,9 @@ herculesplus_in(uint16_t port, void *priv) /* 0x10: Hercules Plus card identity */ ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; break; + + default: + break; } return ret; @@ -207,7 +215,7 @@ herculesplus_write(uint32_t addr, uint8_t val, void *priv) static uint8_t herculesplus_read(uint32_t addr, void *priv) { - herculesplus_t *dev = (herculesplus_t *) priv; + const herculesplus_t *dev = (herculesplus_t *) priv; return dev->vram[addr & 0xffff]; } @@ -223,9 +231,10 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) int elg; int blk; int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; blk = 0; - if (dev->ctrl & HERCULESPLUS_CTRL_BLINK) { + if (blink) { if (attr & 0x80) blk = (dev->blink & 16); attr &= 0x7f; @@ -275,8 +284,8 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { unsigned ull; unsigned val; + unsigned ifg; unsigned ibg; - unsigned cfg; const uint8_t *fnt; int elg; int blk; @@ -292,42 +301,39 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) /* MDA-compatible attributes */ ibg = 0; + ifg = 7; if ((attr & 0x77) == 0x70) { /* Invert */ + ifg = 0; ibg = 7; } if (attr & 8) - if (attr & 0x80) - ibg |= 8; /* High intensity BG */ + ifg |= 8; /* High intensity FG */ + if (attr & 0x80) + ibg |= 8; /* High intensity BG */ if ((attr & 0x77) == 0) /* Blank */ - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + ifg = ibg; + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) elg = 0; else elg = ((chr >= 0xc0) && (chr <= 0xdf)); + fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; if (blk) { - /* Blinking, draw all background */ - val = 0x000; + val = 0x000; /* Blinking, draw all background */ } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + val = 0x1ff; /* Underscore, draw all foreground */ } else { - val = fnt[0x00000] << 1; + val = fnt[0] << 1; if (elg) val |= (val >> 1) & 1; } for (int i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = 0; - - /* cfg = colour of foreground pixels */ - if ((attr & 0x77) == 0) - cfg = ibg; /* 'blank' attribute */ - - buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][!!blink][cfg]; + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; val = val << 1; } } @@ -335,96 +341,65 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) static void draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { - int elg; - int blk; - int ul; - int ol; - int bld; - unsigned ull; - unsigned oll; - unsigned ulc = 0; - unsigned olc = 0; - unsigned val; - unsigned ibg; - unsigned cfg; - const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; - int font = (attr & 0x0F); + unsigned ull; + unsigned val; + unsigned ifg; + unsigned ibg; + const uint8_t *fnt; + int elg; + int blk; + int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; + int font = (attr & 0x0F); if (font >= 12) font &= 7; + attr = (attr >> 4) ^ 0x0f; + blk = 0; if (blink) { - if (attr & 0x40) + if (attr & 0x80) blk = (dev->blink & 16); attr &= 0x7f; } /* MDA-compatible attributes */ - if (blink) { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } else { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - - if (ul) { - ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F; - ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) - ulc = 7; - } else { - ull = 0xFFFF; - } - - if (ol) { - oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F; - olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) - olc = 7; - } else { - oll = 0xFFFF; + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) { /* Invert */ + ifg = 0; + ibg = 7; } + if (attr & 8) + ifg |= 8; /* High intensity FG */ + if (attr & 0x80) + ibg |= 8; /* High intensity BG */ + if ((attr & 0x77) == 0) /* Blank */ + ifg = ibg; + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) elg = 0; else elg = ((chr >= 0xc0) && (chr <= 0xdf)); + fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; - if (blk) { /* Blinking, draw all background */ - val = 0x000; + if (blk) { + val = 0x000; /* Blinking, draw all background */ } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + val = 0x1ff; /* Underscore, draw all foreground */ } else { - val = fnt[0x00000] << 1; + val = fnt[0] << 1; if (elg) val |= (val >> 1) & 1; - if (bld) - val |= (val >> 1); } for (int i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = val & 0x100; - if (dev->sc == oll) - cfg = olc ^ ibg; /* Strikethrough */ - else if (dev->sc == ull) - cfg = ulc ^ ibg; /* Underline */ - else - cfg |= ibg; - - buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][!!blink][cfg]; - val = val << 1; + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; + val = val << 1; } } @@ -438,8 +413,8 @@ text_line(herculesplus_t *dev, uint16_t ca) for (uint8_t x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + chr = dev->vram[(dev->ma << 1) & 0x3fff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; } else chr = attr = 0; @@ -458,6 +433,9 @@ text_line(herculesplus_t *dev, uint16_t ca) case 5: /* 48k RAMfont */ draw_char_ram48(dev, x, chr, attr); break; + + default: + break; } ++dev->ma; @@ -511,6 +489,7 @@ herculesplus_poll(void *priv) int x; int oldvc; int oldsc; + int cw = HERCULESPLUS_CW; VIDEO_MONITOR_PROLOGUE(); if (!dev->linepos) { @@ -534,7 +513,7 @@ herculesplus_poll(void *priv) if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; video_process_8(x, dev->displine); } @@ -597,7 +576,7 @@ herculesplus_poll(void *priv) if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; dev->lastline++; if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; @@ -641,7 +620,7 @@ herculesplus_poll(void *priv) } static void * -herculesplus_init(const device_t *info) +herculesplus_init(UNUSED(const device_t *info)) { herculesplus_t *dev; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 6b99975d5e..b87d936659 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -35,6 +35,8 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> typedef struct ht216_t { svga_t svga; @@ -92,8 +94,8 @@ typedef struct ht216_t { void ht216_remap(ht216_t *ht216); -void ht216_out(uint16_t addr, uint8_t val, void *p); -uint8_t ht216_in(uint16_t addr, void *p); +void ht216_out(uint16_t addr, uint8_t val, void *priv); +uint8_t ht216_in(uint16_t addr, void *priv); #define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN" #define BIOS_VIDEO7_VGA_1024I_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" @@ -134,7 +136,7 @@ dword_remap(svga_t *svga, uint32_t in_addr) static void ht216_recalc_bank_regs(ht216_t *ht216, int mode) { - svga_t *svga = &ht216->svga; + const svga_t *svga = &ht216->svga; if (mode) { ht216->read_bank_reg[0] = ht216->ht_regs[0xe8]; @@ -164,9 +166,9 @@ ht216_recalc_bank_regs(ht216_t *ht216, int mode) } void -ht216_out(uint16_t addr, uint8_t val, void *p) +ht216_out(uint16_t addr, uint8_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; uint8_t old; @@ -310,6 +312,10 @@ ht216_out(uint16_t addr, uint8_t val, void *p) ht216_remap(ht216); break; + case 0xca: + svga_recalctimings(svga); + break; + case 0xc9: case 0xcf: ht216_remap(ht216); @@ -319,7 +325,8 @@ ht216_out(uint16_t addr, uint8_t val, void *p) svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; if (val & 0x04) svga->adv_flags |= FLAG_RAMDAC_SHIFT; - /* FALLTHROUGH */ + svga_recalctimings(svga); + fallthrough; /*Bank registers*/ case 0xe8: case 0xe9: @@ -380,6 +387,9 @@ ht216_out(uint16_t addr, uint8_t val, void *p) svga->fullchange = changeframecount; svga_recalctimings(svga); break; + + default: + break; } return; } @@ -444,28 +454,27 @@ ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0x46e8: - if ((ht216->id == 0x7152) && ht216->isabus) - io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&ht216->linear_mapping); if (val & 8) { - if ((ht216->id == 0x7152) && ht216->isabus) - io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_enable(&svga->mapping); ht216_remap(ht216); } break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -ht216_in(uint16_t addr, void *p) +ht216_in(uint16_t addr, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; uint8_t ret = 0xff; @@ -525,6 +534,9 @@ ht216_in(uint16_t addr, void *p) ret = svga->latch.b[ht216->bg_plane_sel]; ht216->bg_plane_sel = 0; break; + + default: + break; } return ret; @@ -555,6 +567,9 @@ ht216_in(uint16_t addr, void *p) if (svga->crtcreg == 0x1f) return svga->crtc[0xc] ^ 0xea; return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); @@ -606,7 +621,7 @@ ht216_remap(ht216_t *ht216) void ht216_recalctimings(svga_t *svga) { - ht216_t *ht216 = (ht216_t *) svga->p; + ht216_t *ht216 = (ht216_t *) svga->priv; int high_res_256 = 0; switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | ((ht216->ht_regs[0xf8] << 1) & 8)) { @@ -674,7 +689,7 @@ ht216_recalctimings(svga_t *svga) if (!(svga->crtc[1] & 1)) svga->hdisp--; svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp *= svga->dots_per_clock; svga->rowoffset <<= 1; if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ svga->crtc[0x17] |= 0x40; @@ -697,16 +712,19 @@ ht216_recalctimings(svga_t *svga) svga->vram_display_mask = 0x7ffff; else svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; + + if (ht216->ht_regs[0xe0] & 0x20) + svga->hblankstart = ((ht216->ht_regs[0xca] >> 2) << 8) + svga->crtc[4]; } static void ht216_hwcursor_draw(svga_t *svga, int displine) { - ht216_t *ht216 = (ht216_t *) svga->p; - int shift = (ht216->adjust_cursor ? 2 : 1); - uint32_t dat[2]; - int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; - int width = (ht216->adjust_cursor ? 16 : 32); + const ht216_t *ht216 = (ht216_t *) svga->priv; + int shift = (ht216->adjust_cursor ? 2 : 1); + uint32_t dat[2]; + int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; + int width = (ht216->adjust_cursor ? 16 : 32); if (ht216->adjust_cursor) offset >>= 1; @@ -719,9 +737,9 @@ ht216_hwcursor_draw(svga_t *svga, int displine) for (int x = 0; x < width; x++) { if (!(dat[0] & 0x80000000)) - ((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] = 0; + (buffer32->line[displine])[svga->x_add + offset + x] = 0; if (dat[1] & 0x80000000) - ((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; + (buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; dat[0] <<= shift; dat[1] <<= shift; @@ -857,6 +875,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u for (i = 0; i < count; i++) fg_data[i] = ht216->fg_latch[i]; break; + + default: + break; } switch (svga->writemode) { @@ -918,6 +939,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u reset_wm = 1; break; + + default: + break; } switch (svga->gdcreg[3] & 0x18) { @@ -965,6 +989,9 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u } } break; + + default: + break; } if (reset_wm) @@ -1015,6 +1042,9 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi case 0x0c: input_a = ht216->bg_latch[addr & 7]; break; + + default: + break; } fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); @@ -1102,10 +1132,10 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) 01 = Bit mask (3CF:8) 1x = (3C4:F5) */ - svga_t *svga = &ht216->svga; - int i; - uint8_t bit_mask = 0; - uint8_t rop_select = 0; + const svga_t *svga = &ht216->svga; + int i; + uint8_t bit_mask = 0; + uint8_t rop_select = 0; cycles -= video_timing_write_b; @@ -1126,6 +1156,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) case 0x30: rop_select = ht216->ht_regs[0xf5]; break; + + default: + break; } switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) { case 0x00: @@ -1138,6 +1171,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) case 0x0c: bit_mask = ht216->ht_regs[0xf5]; break; + + default: + break; } if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/ @@ -1164,9 +1200,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) } static void -ht216_write(uint32_t addr, uint8_t val, void *p) +ht216_write(uint32_t addr, uint8_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; @@ -1185,9 +1221,9 @@ ht216_write(uint32_t addr, uint8_t val, void *p) } static void -ht216_writew(uint32_t addr, uint16_t val, void *p) +ht216_writew(uint32_t addr, uint16_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; @@ -1208,9 +1244,9 @@ ht216_writew(uint32_t addr, uint16_t val, void *p) } static void -ht216_writel(uint32_t addr, uint32_t val, void *p) +ht216_writel(uint32_t addr, uint32_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; @@ -1233,9 +1269,9 @@ ht216_writel(uint32_t addr, uint32_t val, void *p) } static void -ht216_write_linear(uint32_t addr, uint8_t val, void *p) +ht216_write_linear(uint32_t addr, uint8_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; addr -= ht216->linear_base; @@ -1250,9 +1286,9 @@ ht216_write_linear(uint32_t addr, uint8_t val, void *p) } static void -ht216_writew_linear(uint32_t addr, uint16_t val, void *p) +ht216_writew_linear(uint32_t addr, uint16_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; addr -= ht216->linear_base; @@ -1269,9 +1305,9 @@ ht216_writew_linear(uint32_t addr, uint16_t val, void *p) } static void -ht216_writel_linear(uint32_t addr, uint32_t val, void *p) +ht216_writel_linear(uint32_t addr, uint32_t val, void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_t *svga = &ht216->svga; addr -= ht216->linear_base; @@ -1372,11 +1408,11 @@ ht216_read_common(ht216_t *ht216, uint32_t addr) } static uint8_t -ht216_read(uint32_t addr, void *p) +ht216_read(uint32_t addr, void *priv) { - ht216_t *ht216 = (ht216_t *) p; - svga_t *svga = &ht216->svga; - uint32_t prev_addr = addr; + ht216_t *ht216 = (ht216_t *) priv; + const svga_t *svga = &ht216->svga; + uint32_t prev_addr = addr; addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1]; @@ -1390,10 +1426,10 @@ ht216_read(uint32_t addr, void *p) } static uint8_t -ht216_read_linear(uint32_t addr, void *p) +ht216_read_linear(uint32_t addr, void *priv) { - ht216_t *ht216 = (ht216_t *) p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) priv; + const svga_t *svga = &ht216->svga; addr -= ht216->linear_base; if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ @@ -1406,8 +1442,10 @@ ht216_read_linear(uint32_t addr, void *p) static uint8_t radius_mca_read(int port, void *priv) { - ht216_t *ht216 = (ht216_t *) priv; + const ht216_t *ht216 = (ht216_t *) priv; + ht216_log("Port %03x MCA read = %02x\n", port, ht216->pos_regs[port & 7]); + return (ht216->pos_regs[port & 7]); } @@ -1427,14 +1465,13 @@ radius_mca_write(int port, uint8_t val, void *priv) } static uint8_t -radius_mca_feedb(void *priv) +radius_mca_feedb(UNUSED(void *priv)) { return 1; } -void - * - ht216_init(const device_t *info, uint32_t mem_size, int has_rom) +void * +ht216_init(const device_t *info, uint32_t mem_size, int has_rom) { ht216_t *ht216 = malloc(sizeof(ht216_t)); svga_t *svga; @@ -1502,6 +1539,9 @@ void } rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; + + default: + break; } svga->hwcursor.cur_ysize = 32; @@ -1611,9 +1651,9 @@ radius_svga_multiview_available(void) } void -ht216_close(void *p) +ht216_close(void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_close(&ht216->svga); @@ -1621,17 +1661,17 @@ ht216_close(void *p) } void -ht216_speed_changed(void *p) +ht216_speed_changed(void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; svga_recalctimings(&ht216->svga); } void -ht216_force_redraw(void *p) +ht216_force_redraw(void *priv) { - ht216_t *ht216 = (ht216_t *) p; + ht216_t *ht216 = (ht216_t *) priv; ht216->svga.fullchange = changeframecount; } diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index 339cf6700d..1b19a3a0fa 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -25,33 +25,43 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> -typedef union { +typedef union ibm_rgb528_pixel8_t { uint8_t pixel; struct { - uint8_t b : 2, g : 3, r : 2; + uint8_t b : 2; + uint8_t g : 3; + uint8_t r : 2; }; } ibm_rgb528_pixel8_t; -typedef union { +typedef union ibm_rgb528_pixel16_t { uint16_t pixel; struct { - uint16_t b_ : 5, g_ : 6, r_ : 5; + uint16_t b_ : 5; + uint16_t g_ : 6; + uint16_t r_ : 5; }; struct { - uint16_t b : 5, g : 5, r : 5, c : 1; + uint16_t b : 5; + uint16_t g : 5; + uint16_t r : 5; + uint16_t c : 1; }; } ibm_rgb528_pixel16_t; -typedef union { +typedef union ibm_rgb528_pixel32_t { uint32_t pixel; struct { - uint8_t b, g, r, a; + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; }; } ibm_rgb528_pixel32_t; -typedef struct -{ +typedef struct ibm_rgb528_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t indexed_data[2048]; @@ -59,33 +69,37 @@ typedef struct uint8_t cursor64_data[1024]; uint8_t palettes[3][256]; ibm_rgb528_pixel32_t extra_pal[4]; - int16_t hwc_y, hwc_x; - uint16_t index, smlc_part; + int16_t hwc_y; + int16_t hwc_x; + uint16_t index; + uint16_t smlc_part; uint8_t cmd_r0; uint8_t cmd_r1; uint8_t cmd_r2; uint8_t cmd_r3; uint8_t cmd_r4; - uint8_t status, indx_cntl; - uint8_t cursor_array, - cursor_hotspot_x, cursor_hotspot_y; + uint8_t status; + uint8_t indx_cntl; + uint8_t cursor_array; + uint8_t cursor_hotspot_x; + uint8_t cursor_hotspot_y; } ibm_rgb528_ramdac_t; void ibm_rgb528_render_4bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint32_t *p; + ibm_rgb528_pixel32_t dat_out; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) return; @@ -154,16 +168,16 @@ ibm_rgb528_render_4bpp(svga_t *svga) void ibm_rgb528_render_8bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint32_t *p; + ibm_rgb528_pixel32_t dat_out; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) return; @@ -223,24 +237,24 @@ ibm_rgb528_render_8bpp(svga_t *svga) void ibm_rgb528_render_15_16bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel16_t *dat_ex; - ibm_rgb528_pixel32_t dat_out; - uint16_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; - uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; - uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel16_t *dat_ex; + ibm_rgb528_pixel32_t dat_out; + uint16_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; + uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; + uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -348,18 +362,18 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) void ibm_rgb528_render_24bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat; - uint64_t dat64[6]; - uint8_t *dat8 = (uint8_t *) dat64; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel32_t *dat_ex; + uint32_t dat; + uint64_t dat64[6]; + uint8_t *dat8 = (uint8_t *) dat64; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -437,19 +451,19 @@ ibm_rgb528_render_24bpp(svga_t *svga) void ibm_rgb528_render_32bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; - uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel32_t *dat_ex; + uint32_t dat = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; + uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -550,9 +564,9 @@ ibm_rgb528_set_bpp(ibm_rgb528_ramdac_t *ramdac, svga_t *svga) } void -ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -611,6 +625,9 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga case 0xc0: ramdac->smlc_part = 0x0400; break; + + default: + break; } svga->dac_hwcursor.addr = ramdac->smlc_part; svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32; @@ -711,15 +728,18 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga case 0x07: ramdac->indx_cntl = val & 0x01; break; + + default: + break; } return; } uint8_t -ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); uint8_t loc_read = (ramdac->indexed_data[0x30] & 0x10); @@ -780,15 +800,18 @@ ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) case 0x07: temp = ramdac->indx_cntl; break; + + default: + break; } return temp; } void -ibm_rgb528_recalctimings(void *p, svga_t *svga) +ibm_rgb528_recalctimings(void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; svga->interlace = ramdac->indexed_data[0x071] & 0x20; @@ -813,6 +836,9 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) case 32: svga->render = ibm_rgb528_render_32bpp; break; + + default: + break; } } } @@ -823,16 +849,16 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) { - uint8_t dat; - uint8_t four_pixels = 0x00; - int pitch; - int x_pos; - int y_pos; - int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; - uint32_t *p; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; - uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; + uint8_t dat; + uint8_t four_pixels = 0x00; + int pitch; + int x_pos; + int y_pos; + int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; + uint32_t *p; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; + uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; /* The planes come in one part, and each plane is 2bpp, so a 32x32 cursor has 8 bytes per line, and a 64x64 @@ -872,6 +898,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Cursor Color 3 */ p[x_pos] = ramdac->extra_pal[2].pixel; break; + + default: + break; } break; case 0x02: @@ -888,6 +917,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Complement */ p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 0x03: @@ -900,8 +932,14 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Cursor Color 2 */ p[x_pos] = ramdac->extra_pal[1].pixel; break; + + default: + break; } break; + + default: + break; } if ((x & 3) == 3) @@ -913,7 +951,7 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) } void * -ibm_rgb528_ramdac_init(const device_t *info) +ibm_rgb528_ramdac_init(UNUSED(const device_t *info)) { ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) malloc(sizeof(ibm_rgb528_ramdac_t)); memset(ramdac, 0, sizeof(ibm_rgb528_ramdac_t)); diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 57dcdce38d..4c23d6ec55 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -29,13 +29,17 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/plat_unused.h> typedef struct icd2061_t { float freq[3]; - int count, bit_count, - unlocked, state; - uint32_t data, ctrl; + int count; + int bit_count; + int unlocked; + int state; + uint32_t data; + uint32_t ctrl; } icd2061_t; #ifdef ENABLE_ICD2061_LOG @@ -57,9 +61,9 @@ icd2061_log(const char *fmt, ...) #endif void -icd2061_write(void *p, int val) +icd2061_write(void *priv, int val) { - icd2061_t *icd2061 = (icd2061_t *) p; + icd2061_t *icd2061 = (icd2061_t *) priv; int nd; int oc; @@ -135,9 +139,9 @@ icd2061_write(void *p, int val) } float -icd2061_getclock(int clock, void *p) +icd2061_getclock(int clock, void *priv) { - icd2061_t *icd2061 = (icd2061_t *) p; + const icd2061_t *icd2061 = (icd2061_t *) priv; if (clock > 2) clock = 2; @@ -146,7 +150,7 @@ icd2061_getclock(int clock, void *p) } static void * -icd2061_init(const device_t *info) +icd2061_init(UNUSED(const device_t *info)) { icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); memset(icd2061, 0, sizeof(icd2061_t)); diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index 99a877a752..309d07966b 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -49,9 +49,9 @@ ics2494_log(const char *fmt, ...) #endif float -ics2494_getclock(int clock, void *p) +ics2494_getclock(int clock, void *priv) { - ics2494_t *ics2494 = (ics2494_t *) p; + const ics2494_t *ics2494 = (ics2494_t *) priv; if (clock > 15) clock = 15; @@ -66,6 +66,63 @@ ics2494_init(const device_t *info) memset(ics2494, 0, sizeof(ics2494_t)); switch (info->local) { + case 10: + /* ATI 18810 for ATI 28800 */ + ics2494->freq[0x0] = 30240000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 37500000.0; + ics2494->freq[0x3] = 39000000.0; + ics2494->freq[0x4] = 42954000.0; + ics2494->freq[0x5] = 48771000.0; + ics2494->freq[0x6] = 16657000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 40000000.0; + ics2494->freq[0x9] = 56644000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 28322000.0; + ics2494->freq[0xf] = 44900000.0; + break; + case 110: + /* ATI 18811-0 for ATI Mach32 */ + ics2494->freq[0x0] = 30240000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 110000000.0; + ics2494->freq[0x3] = 80000000.0; + ics2494->freq[0x4] = 42954000.0; + ics2494->freq[0x5] = 48771000.0; + ics2494->freq[0x6] = 92400000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 39910000.0; + ics2494->freq[0x9] = 44900000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 0.0; + ics2494->freq[0xf] = 44900000.0; + break; + case 111: + /* ATI 18811-1 for ATI Mach32 MCA */ + ics2494->freq[0x0] = 135000000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 110000000.0; + ics2494->freq[0x3] = 80000000.0; + ics2494->freq[0x4] = 100000000.0; + ics2494->freq[0x5] = 126000000.0; + ics2494->freq[0x6] = 92400000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 39910000.0; + ics2494->freq[0x9] = 44900000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 0.0; + ics2494->freq[0xf] = 44900000.0; + break; case 305: /* ICS2494A(N)-205 for S3 86C924 */ ics2494->freq[0x0] = 25175000.0; @@ -85,6 +142,9 @@ ics2494_init(const device_t *info) ics2494->freq[0xe] = 75000000.0; ics2494->freq[0xf] = 94500000.0; break; + + default: + break; } return ics2494; @@ -112,3 +172,45 @@ const device_t ics2494an_305_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ati18810_device = { + .name = "ATI 18810 Clock Generator", + .internal_name = "ati18810", + .flags = 0, + .local = 10, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ati18811_0_device = { + .name = "ATI 18811-0 Clock Generator", + .internal_name = "ati18811_0", + .flags = 0, + .local = 110, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ati18811_1_device = { + .name = "ATI 18811-1 Clock Generator", + .internal_name = "ati18811_1", + .flags = 0, + .local = 111, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index 520bcda431..ecb414f2bc 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -23,11 +23,14 @@ #include #include <86box/86box.h> #include <86box/device.h> +#include <86box/plat_unused.h> typedef struct ics2595_t { - int oldfs3, oldfs2; + int oldfs3; + int oldfs2; int dat; - int pos, state; + int pos; + int state; double clocks[16]; double output_clock; @@ -42,9 +45,9 @@ enum { static int ics2595_div[4] = { 8, 4, 2, 1 }; void -ics2595_write(void *p, int strobe, int dat) +ics2595_write(void *priv, int strobe, int dat) { - ics2595_t *ics2595 = (ics2595_t *) p; + ics2595_t *ics2595 = (ics2595_t *) priv; int d; int n; int l; @@ -70,6 +73,9 @@ ics2595_write(void *p, int strobe, int dat) ics2595->state = ICS2595_IDLE; } break; + + default: + break; } } @@ -81,9 +87,10 @@ ics2595_write(void *p, int strobe, int dat) } static void * -ics2595_init(const device_t *info) +ics2595_init(UNUSED(const device_t *info)) { ics2595_t *ics2595 = (ics2595_t *) malloc(sizeof(ics2595_t)); + memset(ics2595, 0, sizeof(ics2595_t)); return ics2595; @@ -99,17 +106,17 @@ ics2595_close(void *priv) } double -ics2595_getclock(void *p) +ics2595_getclock(void *priv) { - ics2595_t *ics2595 = (ics2595_t *) p; + const ics2595_t *ics2595 = (ics2595_t *) priv; return ics2595->output_clock; } void -ics2595_setclock(void *p, double clock) +ics2595_setclock(void *priv, double clock) { - ics2595_t *ics2595 = (ics2595_t *) p; + ics2595_t *ics2595 = (ics2595_t *) priv; ics2595->output_clock = clock; } diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index cb3999be4f..c7602ffd03 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -635,7 +635,7 @@ hndl_poly(pgc_t *pgc) } static int -parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c) +parse_poly(pgc_t *pgc, pgc_cl_t *cl, UNUSED(int c)) { uint8_t count; @@ -763,15 +763,15 @@ hndl_tsize(pgc_t *pgc) static void hndl_twrite(pgc_t *pgc) { - uint8_t buf[256]; - im1024_t *dev = (im1024_t *) pgc; - uint8_t count; - uint8_t mask; - uint8_t *row; - int wb; - int n; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; + uint8_t buf[256]; + const im1024_t *dev = (im1024_t *) pgc; + uint8_t count; + uint8_t mask; + const uint8_t *row; + int wb; + int n; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; if (!pgc_param_byte(pgc, &count)) return; @@ -811,13 +811,13 @@ hndl_twrite(pgc_t *pgc) static void hndl_txt88(pgc_t *pgc) { - uint8_t buf[256]; - uint8_t count; - uint8_t mask; - uint8_t *row; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; - unsigned n; + uint8_t buf[256]; + uint8_t count; + uint8_t mask; + const uint8_t *row; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; + unsigned int n; if (!pgc_param_byte(pgc, &count)) return; @@ -1031,7 +1031,7 @@ static const pgc_cmd_t im1024_commands[] = { }; static void * -im1024_init(const device_t *info) +im1024_init(UNUSED(const device_t *info)) { im1024_t *dev; @@ -1085,7 +1085,7 @@ im1024_speed_changed(void *priv) const device_t im1024_device = { .name = "ImageManager 1024", .internal_name = "im1024", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA, .local = 0, .init = im1024_init, .close = im1024_close, diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index 6e8054aaa3..e3f37ec65e 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -30,6 +30,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/plat_unused.h> /* extended CRTC registers */ #define INCOLOR_CRTC_XMODE 20 /* xMode register */ @@ -251,6 +252,9 @@ incolor_out(uint16_t port, uint8_t val, void *priv) else mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); return; + + default: + break; } } @@ -353,6 +357,9 @@ incolor_write(uint32_t addr, uint8_t val, void *priv) else w = ((~latch) & vmask); break; + + default: + break; } /* w is nonzero to write a 1, zero to write a 0 */ @@ -748,8 +755,8 @@ text_line(incolor_t *dev, uint16_t ca) for (uint8_t x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + chr = dev->vram[(dev->ma << 1) & 0x3fff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; } else chr = attr = 0; @@ -768,6 +775,9 @@ text_line(incolor_t *dev, uint16_t ca) case 5: /* 48k RAMfont */ draw_char_ram48(dev, x, chr, attr); break; + + default: + break; } ++dev->ma; @@ -849,6 +859,7 @@ incolor_poll(void *priv) int x; int oldvc; int oldsc; + int cw = INCOLOR_CW; if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); @@ -930,7 +941,7 @@ incolor_poll(void *priv) if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; dev->lastline++; if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; @@ -972,7 +983,7 @@ incolor_poll(void *priv) } static void * -incolor_init(const device_t *info) +incolor_init(UNUSED(const device_t *info)) { incolor_t *dev; int c; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 44f91ec954..702fb7e328 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -31,6 +31,7 @@ #include <86box/device.h> #include <86box/video.h> #include <86box/vid_mda.h> +#include <86box/plat_unused.h> static int mdacols[256][2][2]; @@ -39,9 +40,10 @@ static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w void mda_recalctimings(mda_t *mda); void -mda_out(uint16_t addr, uint8_t val, void *p) +mda_out(uint16_t addr, uint8_t val, void *priv) { - mda_t *mda = (mda_t *) p; + mda_t *mda = (mda_t *) priv; + switch (addr) { case 0x3b0: case 0x3b2: @@ -64,13 +66,17 @@ mda_out(uint16_t addr, uint8_t val, void *p) case 0x3b8: mda->ctrl = val; return; + + default: + break; } } uint8_t -mda_in(uint16_t addr, void *p) +mda_in(uint16_t addr, void *priv) { - mda_t *mda = (mda_t *) p; + const mda_t *mda = (mda_t *) priv; + switch (addr) { case 0x3b0: case 0x3b2: @@ -84,21 +90,25 @@ mda_in(uint16_t addr, void *p) return mda->crtc[mda->crtcreg]; case 0x3ba: return mda->stat | 0xF0; + + default: + break; } return 0xff; } void -mda_write(uint32_t addr, uint8_t val, void *p) +mda_write(uint32_t addr, uint8_t val, void *priv) { - mda_t *mda = (mda_t *) p; + mda_t *mda = (mda_t *) priv; mda->vram[addr & 0xfff] = val; } uint8_t -mda_read(uint32_t addr, void *p) +mda_read(uint32_t addr, void *priv) { - mda_t *mda = (mda_t *) p; + const mda_t *mda = (mda_t *) priv; + return mda->vram[addr & 0xfff]; } @@ -118,9 +128,9 @@ mda_recalctimings(mda_t *mda) } void -mda_poll(void *p) +mda_poll(void *priv) { - mda_t *mda = (mda_t *) p; + mda_t *mda = (mda_t *) priv; uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; int drawcursor; int x; @@ -155,9 +165,9 @@ mda_poll(void *p) buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; } else { for (c = 0; c < 8; c++) - buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr + mda->fontbase][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; if ((chr & ~0x1f) == 0xc0) - buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; + buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr + mda->fontbase][mda->sc] & 1]; else buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; } @@ -299,7 +309,7 @@ mda_init(mda_t *mda) } void * -mda_standalone_init(const device_t *info) +mda_standalone_init(UNUSED(const device_t *info)) { mda_t *mda = malloc(sizeof(mda_t)); memset(mda, 0, sizeof(mda_t)); @@ -324,18 +334,18 @@ mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) } void -mda_close(void *p) +mda_close(void *priv) { - mda_t *mda = (mda_t *) p; + mda_t *mda = (mda_t *) priv; free(mda->vram); free(mda); } void -mda_speed_changed(void *p) +mda_speed_changed(void *priv) { - mda_t *mda = (mda_t *) p; + mda_t *mda = (mda_t *) priv; mda_recalctimings(mda); } @@ -376,7 +386,7 @@ static const device_config_t mda_config[] = { }; const device_t mda_device = { - .name = "MDA", + .name = "IBM MDA", .internal_name = "mda", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 677531c29c..f40385fef3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,6 +15,7 @@ * Copyright 2008-2020 Sarah Walker. */ #include +#include #include #include #include @@ -36,9 +37,11 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" -#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" -#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" +#define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" +#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" +#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_G100 "roms/video/matrox/productiva8mbsdr.BIN" #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -55,7 +58,7 @@ #define FIFO_ADDR 0x00ffffff #define DMA_POLL_TIME_US 100 /*100us*/ -#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ +#define DMA_MAX_WORDS (20 * 14) /*280 quad words per 100us poll*/ /*These registers are also mirrored into 0x1dxx, with the mirrored versions starting the blitter*/ @@ -111,6 +114,14 @@ #define REG_DR14 0x1cf8 #define REG_DR15 0x1cfc +#define REG_DR0_Z32LSB 0x2c50 +#define REG_DR0_Z32MSB 0x2c54 +#define REG_DR2_Z32LSB 0x2c60 +#define REG_DR2_Z32MSB 0x2c64 +#define REG_DR3_Z32LSB 0x2c68 +#define REG_DR3_Z32MSB 0x2c6c +#define REG_TEXFILTER 0x2c58 + #define REG_FIFOSTATUS 0x1e10 #define REG_STATUS 0x1e14 #define REG_ICLEAR 0x1e18 @@ -157,6 +168,14 @@ #define REG_SECADDRESS 0x2c40 #define REG_SECEND 0x2c44 #define REG_SOFTRAP 0x2c48 +#define REG_ALPHASTART 0x2c70 +#define REG_ALPHACTRL 0x2c7c +#define REG_ALPHAXINC 0x2c74 +#define REG_ALPHAYINC 0x2c78 +#define REG_FOGSTART 0x1cc4 +#define REG_FOGXINC 0x1cd4 +#define REG_FOGYINC 0x1ce4 +#define REG_FOGCOL 0x1cf4 /*Mystique only*/ #define REG_PALWTADD 0x3c00 @@ -173,6 +192,8 @@ #define CRTCX_R0_OFFSET_MASK (3 << 4) #define CRTCX_R1_HTOTAL8 (1 << 0) +#define CRTCX_R1_HBLKSTRT8 (1 << 1) +#define CRTCX_R1_HBLKEND6 (1 << 6) #define CRTCX_R2_VTOTAL10 (1 << 0) #define CRTCX_R2_VTOTAL11 (1 << 1) @@ -234,6 +255,7 @@ #define XREG_XPIXPLLSTAT 0x4f #define XMISCCTRL_VGA8DAC (1 << 3) +#define XMISCCTRL_RAMCS (1 << 4) #define XMULCTRL_DEPTH_MASK (7 << 0) #define XMULCTRL_DEPTH_8 (0 << 0) @@ -308,6 +330,8 @@ #define MACCESS_PWIDTH_16 (1 << 0) #define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_ZWIDTH (1 << 3) +#define MACCESS_FOGEN (1 << 26) #define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) @@ -348,7 +372,10 @@ #define TEXCTL_PALSEL_MASK (0xf << 4) #define TEXCTL_TPITCH_SHIFT (16) #define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_TPITCHLIN (1 << 8) +#define TEXCTL_TPITCHEXT_MASK (0x7ff << 9) #define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_AZEROEXTEND (1 << 23) #define TEXCTL_DECALCKEY (1 << 24) #define TEXCTL_TAKEY (1 << 25) #define TEXCTL_TAMASK (1 << 26) @@ -382,6 +409,8 @@ enum { MGA_2064W, /*Millennium*/ MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ + MGA_2164W, /*Millennium II*/ + MGA_G100, /*Productiva G100*/ }; enum { @@ -424,12 +453,12 @@ typedef struct mystique_t { xcolkeyl, xcolkeyh, xcrcbitsel; + uint8_t pci_slot, irq_state, pad, pad0; + uint8_t pci_regs[256], crtcext_regs[6], xreg_regs[256], dmamap[16]; - int card, vram_size, crtcext_idx, xreg_idx, - xzoomctrl, - pixel_count, trap_count; + int vram_size, crtcext_idx, xreg_idx, xzoomctrl; atomic_int busy, blitter_submit_refcount, blitter_submit_dma_refcount, blitter_complete_refcount, @@ -439,7 +468,10 @@ typedef struct mystique_t { uint32_t vram_mask, vram_mask_w, vram_mask_l, lfb_base, ctrl_base, iload_base, ma_latch_old, maccess, mctlwtst, maccess_running, - status, softrap_pending_val; + softrap_pending_val; + + atomic_uint status; + atomic_bool softrap_status_read; uint64_t blitter_time, status_time; @@ -470,7 +502,7 @@ typedef struct mystique_t { int xoff, yoff, selline, ydst, length_cur, iload_rem_count, idump_end_of_line, words, ta_key, ta_mask, lastpix_r, lastpix_g, - lastpix_b, highv_line, beta, dither; + lastpix_b, highv_line, beta, dither, err, k1, k2; int pattern[8][16]; @@ -478,11 +510,16 @@ typedef struct mystique_t { pitch, plnwt, ybot, ydstorg, ytop, texorg, texwidth, texheight, texctl, textrans, zorg, ydst_lin, - src_addr, z_base, iload_rem_data, highv_data; + src_addr, z_base, iload_rem_data, highv_data, + fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24, + alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24, + texfilter; uint32_t src[4], ar[7], dr[16], tmr[9]; + uint64_t extended_dr[4]; + struct { int sdydxl, scanleft, sdxl, sdy, @@ -504,13 +541,14 @@ typedef struct mystique_t { struct { - int pri_pos, sec_pos, iload_pos, - pri_state, sec_state, iload_state, state; + atomic_int pri_state, sec_state, iload_state, state; - uint32_t primaddress, primend, secaddress, secend, + atomic_uint primaddress, primend, secaddress, secend, pri_header, sec_header, iload_header; + atomic_uint words_expected; + mutex_t *lock; } dma; @@ -622,6 +660,13 @@ static const uint8_t trans_masks[16][16] = { static int8_t dither5[256][2][2]; static int8_t dither6[256][2][2]; +static double bayer_mat[4][4] = +{ + { 0.0, 8. / 16., 2. / 16., 10. / 16.}, + { 12. / 16., 4. / 16., 14. / 16., 6. / 16.}, + { 3. / 16., 11. / 16., 1. / 16., 9. / 16.}, + { 15. / 16., 7. / 16., 13. / 16., 5. / 16.}, +}; static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -633,28 +678,28 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -static uint8_t mystique_readb_linear(uint32_t addr, void *p); -static uint16_t mystique_readw_linear(uint32_t addr, void *p); -static uint32_t mystique_readl_linear(uint32_t addr, void *p); -static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); -static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); -static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); +static uint8_t mystique_readb_linear(uint32_t addr, void *priv); +static uint16_t mystique_readw_linear(uint32_t addr, void *priv); +static uint32_t mystique_readl_linear(uint32_t addr, void *priv); +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); -static uint8_t mystique_iload_read_b(uint32_t addr, void *p); -static uint32_t mystique_iload_read_l(uint32_t addr, void *p); -static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p); -static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p); +static uint8_t mystique_iload_read_b(uint32_t addr, void *priv); +static uint32_t mystique_iload_read_l(uint32_t addr, void *priv); +static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *priv); +static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *priv); static uint32_t blit_idump_read(mystique_t *mystique); static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); void -mystique_out(uint16_t addr, uint8_t val, void *p) +mystique_out(uint16_t addr, uint8_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; uint8_t old; @@ -664,10 +709,11 @@ mystique_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3c8: mystique->xreg_idx = val; + fallthrough; case 0x3c6: case 0x3c7: case 0x3c9: - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga); return; } @@ -713,32 +759,66 @@ mystique_out(uint16_t addr, uint8_t val, void *p) mystique->crtcext_idx = val; break; case 0x3df: - if (mystique->crtcext_idx < 6) - mystique->crtcext_regs[mystique->crtcext_idx] = val; if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + old = mystique->crtcext_regs[mystique->crtcext_idx]; + if (mystique->crtcext_idx < 6) + mystique->crtcext_regs[mystique->crtcext_idx] = val; + + if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { + svga->rowoffset = svga->crtc[0x13] | + ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; + + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | + (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; + + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } } + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ - svga->read_bank = (val & 0x7f) << 16; - svga->write_bank = (val & 0x7f) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = val << 16; + svga->write_bank = val << 16; + } else { + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } } else { /*128k banks*/ - svga->read_bank = (val & 0x7e) << 16; - svga->write_bank = (val & 0x7e) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = (val & 0xfe) << 16; + svga->write_bank = (val & 0xfe) << 16; + } else { + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } } } + svga_recalctimings(svga); + break; + + default: break; } @@ -746,9 +826,9 @@ mystique_out(uint16_t addr, uint8_t val, void *p) } uint8_t -mystique_in(uint16_t addr, void *p) +mystique_in(uint16_t addr, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; uint8_t temp = 0xff; @@ -767,7 +847,7 @@ mystique_in(uint16_t addr, void *p) case 0x3c7: case 0x3c8: case 0x3c9: - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga); else temp = svga_in(addr, svga); @@ -803,7 +883,7 @@ mystique_in(uint16_t addr, void *p) static int mystique_line_compare(svga_t *svga) { - mystique_t *mystique = (mystique_t *) svga->p; + mystique_t *mystique = (mystique_t *) svga->priv; mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); @@ -811,10 +891,22 @@ mystique_line_compare(svga_t *svga) return 0; } +static void +mystique_vblank_start(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *) svga->priv; + + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) + svga->ma_latch <<= 1; + } +} + static void mystique_vsync_callback(svga_t *svga) { - mystique_t *mystique = (mystique_t *) svga->p; + mystique_t *mystique = (mystique_t *) svga->priv; if (svga->crtc[0x11] & 0x10) { mystique->status |= STATUS_VSYNCPEN; @@ -823,9 +915,9 @@ mystique_vsync_callback(svga_t *svga) } static float -mystique_getclock(int clock, void *p) +mystique_getclock(int clock, void *priv) { - mystique_t *mystique = (mystique_t *) p; + const mystique_t *mystique = (mystique_t *) priv; if (clock == 0) return 25175000.0; @@ -845,84 +937,129 @@ mystique_getclock(int clock, void *p) void mystique_recalctimings(svga_t *svga) { - mystique_t *mystique = (mystique_t *) svga->p; + mystique_t *mystique = (mystique_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; svga->clock = (cpuclock * (float) (1ULL << 32)) / svga->getclock(clk_sel & 3, svga->clock_gen); if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) - svga->htotal += 0x100; + svga->htotal |= 0x100; + + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2]; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) - svga->vtotal += 0x800; + svga->vtotal |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) - svga->vblankstart += 0x800; + svga->vblankstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) - svga->vsyncstart += 0x800; + svga->vsyncstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) - svga->split += 0x400; + svga->split |= 0x400; - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_recalctimings(svga->ramdac, svga); - else + svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80); + } else svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; - svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + + svga->dots_per_clock = 8; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); + svga->hblank_end_mask = 0x0000007f; + + if (mystique->type != MGA_2164W && mystique->type != MGA_2064W) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); + + if (mystique->type >= MGA_1064SG) + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + if (mystique->type >= MGA_1064SG) + svga->ma_latch <<= 1; } + if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take + /*Mystique and later, unlike most SVGA cards, allows display start to take effect mid-screen*/ + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); else - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } - svga->rowoffset <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; + if (mystique->type != MGA_2164W) { + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { - case XMULCTRL_DEPTH_8: - case XMULCTRL_DEPTH_2G8V16: - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case XMULCTRL_DEPTH_15: - case XMULCTRL_DEPTH_G16V16: - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_16: - svga->render = svga_render_16bpp_highres; - svga->bpp = 16; - break; - case XMULCTRL_DEPTH_24: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case XMULCTRL_DEPTH_32: - case XMULCTRL_DEPTH_32_OVERLAYED: - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; + default: + break; + } + } else { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } } } else { switch (svga->bpp) { @@ -943,13 +1080,26 @@ mystique_recalctimings(svga_t *svga) break; } } + svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; + if (mystique->type < MGA_1064SG) + svga->vblank_start = mystique_vblank_start; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; + svga->lut_map = 0; if (mystique->type >= MGA_1064SG) svga->bpp = 8; + else + svga->vblank_start = NULL; } + + svga->fb_only = svga->packed_chain4; + svga->disable_blink = (svga->bpp > 4); + video_force_resize_set_monitor(1, svga->monitor_index); +#if 0 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); +#endif } static void @@ -975,7 +1125,7 @@ mystique_recalc_mapping(mystique_t *mystique) mem_mapping_disable(&mystique->ctrl_mapping); if (mystique->lfb_base) - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, (mystique->type >= MGA_2164W) ? 0x1000000 : 0x800000); else mem_mapping_disable(&mystique->lfb_mapping); @@ -987,8 +1137,8 @@ mystique_recalc_mapping(mystique_t *mystique) if (mystique->pci_regs[0x41] & 1) { switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0x1ffff; + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); @@ -1002,6 +1152,9 @@ mystique_recalc_mapping(mystique_t *mystique) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -1019,18 +1172,20 @@ mystique_recalc_mapping(mystique_t *mystique) static void mystique_update_irqs(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - int irq = 0; + const svga_t *svga = &mystique->svga; + int irq = 0; if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) irq = 1; + if ((mystique->status & mystique->ien) & STATUS_VLINEPEN) + irq = 1; if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) irq = 1; if (irq) - pci_set_irq(mystique->card, PCI_INTA); + pci_set_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state); else - pci_clear_irq(mystique->card, PCI_INTA); + pci_clear_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state); } #define READ8(addr, var) \ @@ -1255,6 +1410,8 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) case XREG_XMISCCTRL: mystique->xmiscctrl = val; svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); break; case XREG_XGENCTRL: @@ -1361,18 +1518,18 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) } static uint8_t -mystique_ctrl_read_b(uint32_t addr, void *p) +mystique_ctrl_read_b(uint32_t addr, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; uint8_t ret = 0xff; int fifocount; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -1420,13 +1577,16 @@ mystique_ctrl_read_b(uint32_t addr, void *p) ret = mystique->status & 0xff; if (svga->cgastat & 8) ret |= REG_STATUS_VSYNCSTS; + if (ret & 1) + mystique->softrap_status_read = 1; break; case REG_STATUS + 1: ret = (mystique->status >> 8) & 0xff; break; case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; - if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY) + if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY + || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -1434,7 +1594,7 @@ mystique_ctrl_read_b(uint32_t addr, void *p) break; case REG_IEN: - ret = mystique->ien & 0x64; + ret = mystique->ien & 0x65; break; case REG_IEN + 1: case REG_IEN + 2: @@ -1586,9 +1746,9 @@ mystique_ctrl_read_b(uint32_t addr, void *p) } static void -mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; int start_blit = 0; if ((addr & 0x300) == 0x100) { @@ -1603,6 +1763,10 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) case REG_MACCESS + 3: WRITE8(addr, mystique->maccess, val); mystique->dwgreg.dither = mystique->maccess >> 30; + if (mystique->type < MGA_2164W) + mystique->maccess &= ~MACCESS_ZWIDTH; + else + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_MCTLWTST: @@ -1705,7 +1869,9 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) case REG_YDSTLEN: case REG_YDSTLEN + 1: WRITE8(addr, mystique->dwgreg.length, val); - /* pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); */ +#if 0 + pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); +#endif break; case REG_YDSTLEN + 2: mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; @@ -1737,7 +1903,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) case REG_YDSTORG + 2: case REG_YDSTORG + 3: WRITE8(addr, mystique->dwgreg.ydstorg, val); - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_YTOP: case REG_YTOP + 1: @@ -1924,16 +2090,16 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) } static void -mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -1962,7 +2128,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) } if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_b(addr, val, p); + mystique_iload_write_b(addr, val, priv); return; } if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { @@ -1975,6 +2141,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) switch (addr & 0x3fff) { case REG_ICLEAR: if (val & ICLEAR_SOFTRAPICLR) { + //pclog("softrapiclr\n"); mystique->status &= ~STATUS_SOFTRAPEN; mystique_update_irqs(mystique); } @@ -2019,6 +2186,10 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; + if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { + mystique->dma.words_expected = 0; + } + mystique->dma.state = DMA_STATE_IDLE; thread_release_mutex(mystique->dma.lock); break; @@ -2052,6 +2223,12 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) mystique->blitter_complete_refcount = 0; mystique->dwgreg.iload_rem_count = 0; mystique->status = STATUS_ENDPRDMASTS; + thread_wait_mutex(mystique->dma.lock); + mystique->dma.pri_state = 0; + mystique->dma.sec_state = 0; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + thread_release_mutex(mystique->dma.lock); break; case REG_ATTR_IDX: @@ -2144,25 +2321,25 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) } static uint32_t -mystique_ctrl_read_l(uint32_t addr, void *p) +mystique_ctrl_read_l(uint32_t addr, void *priv) { uint32_t ret; if ((addr & 0x3fff) < 0x1c00) - return mystique_iload_read_l(addr, p); + return mystique_iload_read_l(addr, priv); - ret = mystique_ctrl_read_b(addr, p); - ret |= mystique_ctrl_read_b(addr + 1, p) << 8; - ret |= mystique_ctrl_read_b(addr + 2, p) << 16; - ret |= mystique_ctrl_read_b(addr + 3, p) << 24; + ret = mystique_ctrl_read_b(addr, priv); + ret |= mystique_ctrl_read_b(addr + 1, priv) << 8; + ret |= mystique_ctrl_read_b(addr + 2, priv) << 16; + ret |= mystique_ctrl_read_b(addr + 3, priv) << 24; return ret; } static void -mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; int start_blit = 0; if ((addr & 0x300) == 0x100) { @@ -2209,7 +2386,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_ZORG: mystique->dwgreg.zorg = val; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_PLNWT: @@ -2217,10 +2394,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) break; case REG_SHIFT: - mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.funcnt = val & 0x7f; mystique->dwgreg.xoff = val & 7; mystique->dwgreg.yoff = (val >> 4) & 7; - mystique->dwgreg.stylelen = (val >> 16) & 0xff; + mystique->dwgreg.stylelen = (val >> 16) & 0x7f; break; case REG_PITCH: @@ -2256,7 +2433,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) mystique->dwgreg.pattern[y][x] = val & (1 << (x + (y * 16))); } } - // pclog("SRC0 = 0x%08X\n", val); +#if 0 + pclog("SRC0 = 0x%08X\n", val); +#endif if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[0], 32); } @@ -2269,7 +2448,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 2) * 16))); } } - // pclog("SRC1 = 0x%08X\n", val); +#if 0 + pclog("SRC1 = 0x%08X\n", val); +#endif if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[1], 32); } @@ -2282,7 +2463,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 4) * 16))); } } - // pclog("SRC2 = 0x%08X\n", val); +#if 0 + pclog("SRC2 = 0x%08X\n", val); +#endif if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[2], 32); break; @@ -2295,7 +2478,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) mystique->dwgreg.pattern[y][x] = val & (1 << (x + ((y - 6) * 16))); } } - // pclog("SRC3 = 0x%08X\n", val); +#if 0 + pclog("SRC3 = 0x%08X\n", val); +#endif if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[3], 32); break; @@ -2328,14 +2513,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) mystique->dwgreg.ar[6] = val; break; + case REG_DR0_Z32LSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR0_Z32MSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32LSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32MSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32LSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32MSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + case REG_DR0: mystique->dwgreg.dr[0] = val; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR2: mystique->dwgreg.dr[2] = val; + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR3: mystique->dwgreg.dr[3] = val; + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR4: mystique->dwgreg.dr[4] = val; @@ -2373,16 +2591,54 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_SOFTRAP: mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; mystique->softrap_pending_val = val; - mystique->softrap_pending = 1; + mystique->softrap_pending += 1; + break; + + case REG_ALPHACTRL: + mystique->dwgreg.alphactrl = val; + break; + + case REG_ALPHASTART: + mystique->dwgreg.alphastart = val; + break; + + case REG_ALPHAXINC: + mystique->dwgreg.alphaxinc = val; + break; + + case REG_ALPHAYINC: + mystique->dwgreg.alphayinc = val; + break; + + case REG_FOGCOL: + mystique->dwgreg.fogcol = val; + break; + + case REG_FOGSTART: + mystique->dwgreg.fogstart = val; + break; + + case REG_FOGXINC: + mystique->dwgreg.fogxinc = val; + break; + + case REG_FOGYINC: + mystique->dwgreg.fogyinc = val; + break; + + case REG_TEXFILTER: + mystique->dwgreg.texfilter = val; break; default: - mystique_accel_ctrl_write_b(addr, val & 0xff, p); - mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); - mystique_accel_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); - mystique_accel_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + mystique_accel_ctrl_write_b(addr, val & 0xff, priv); + mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); + mystique_accel_ctrl_write_b(addr + 2, (val >> 16) & 0xff, priv); + mystique_accel_ctrl_write_b(addr + 3, (val >> 24) & 0xff, priv); break; } @@ -2391,13 +2647,13 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) } static void -mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; uint32_t reg_addr; if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_l(addr, val, p); + mystique_iload_write_l(addr, val, priv); return; } @@ -2412,14 +2668,25 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_PRIMEND: thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; + //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; mystique->dma.state = DMA_STATE_PRI; - mystique->dma.pri_state = 0; + //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } + /* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE. + + The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference. + Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */ + if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000) + { + mystique->dma.primaddress = mystique->dma.primend; + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } thread_release_mutex(mystique->dma.lock); break; @@ -2452,18 +2719,18 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) break; default: - mystique_ctrl_write_b(addr, val & 0xff, p); - mystique_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); - mystique_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); - mystique_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + mystique_ctrl_write_b(addr, val & 0xff, priv); + mystique_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); + mystique_ctrl_write_b(addr + 2, (val >> 16) & 0xff, priv); + mystique_ctrl_write_b(addr + 3, (val >> 24) & 0xff, priv); break; } } static uint8_t -mystique_iload_read_b(uint32_t addr, void *p) +mystique_iload_read_b(UNUSED(uint32_t addr), void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; wait_fifo_idle(mystique); @@ -2474,9 +2741,9 @@ mystique_iload_read_b(uint32_t addr, void *p) } static uint32_t -mystique_iload_read_l(uint32_t addr, void *p) +mystique_iload_read_l(UNUSED(uint32_t addr), void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; wait_fifo_idle(mystique); @@ -2488,22 +2755,23 @@ mystique_iload_read_l(uint32_t addr, void *p) } static void -mystique_iload_write_b(uint32_t addr, uint8_t val, void *p) +mystique_iload_write_b(UNUSED(uint32_t addr), UNUSED(uint8_t val), UNUSED(void *priv)) { + // } static void -mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) +mystique_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); } static void -mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) +mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; switch (mystique->dwgreg.dmamod) { case DMA_MODE_REG: @@ -2531,17 +2799,27 @@ mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) blit_iload_write(mystique, val, 32); break; - /* default: - pclog("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); */ + default: +#if 0 + pclog("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); */ +#endif + break; } } static uint8_t -mystique_readb_linear(uint32_t addr, void *p) +mystique_readb_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + const svga_t *svga = (svga_t *) priv; + + cycles -= svga->monitor->mon_video_timing_read_b; - cycles -= video_timing_read_b; + if (!svga->fast) { + if (svga->chain2_read) { + addr &= ~1; + addr <<= 2; + } + } addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2551,11 +2829,11 @@ mystique_readb_linear(uint32_t addr, void *p) } static uint16_t -mystique_readw_linear(uint32_t addr, void *p) +mystique_readw_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_w; + cycles -= svga->monitor->mon_video_timing_read_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2565,11 +2843,11 @@ mystique_readw_linear(uint32_t addr, void *p) } static uint32_t -mystique_readl_linear(uint32_t addr, void *p) +mystique_readl_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_l; + cycles -= svga->monitor->mon_video_timing_read_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2579,47 +2857,54 @@ mystique_readl_linear(uint32_t addr, void *p) } static void -mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) +mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_b; + + if (!svga->fast) { + if (svga->chain2_write) { + addr &= ~1; + addr <<= 2; + } + } addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; svga->vram[addr] = val; } static void -mystique_writew_linear(uint32_t addr, uint16_t val, void *p) +mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_w; + cycles -= svga->monitor->mon_video_timing_write_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &svga->vram[addr] = val; } static void -mystique_writel_linear(uint32_t addr, uint32_t val, void *p) +mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_l; + cycles -= svga->monitor->mon_video_timing_write_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } @@ -2630,27 +2915,52 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); + if (mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read) + { + thread_release_mutex(mystique->dma.lock); + return; + } + if (mystique->dma.state == DMA_STATE_IDLE) { + if (!(mystique->status & STATUS_ENDPRDMASTS)) + { + /* Force this to appear. */ + mystique->endprdmasts_pending = 1; + } thread_release_mutex(mystique->dma.lock); return; } while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { - switch (mystique->dma.state) { + switch (atomic_load(&mystique->dma.state)) { case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); + //pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); mystique->dma.primaddress += 4; + mystique->dma.words_expected = 4; + words_transferred++; + } + + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; } - if ((mystique->dma.pri_header & 0xff) != 0x15) { + { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.primaddress += 4; + words_transferred++; reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2661,15 +2971,24 @@ run_dma(mystique_t *mystique) if ((reg_addr & 0x300) == 0x100) mystique->blitter_submit_dma_refcount++; + //pclog("DMA value: 0x%08X to reg 0x%04X\n", val, reg_addr); mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if (reg_addr == REG_SOFTRAP) { + mystique->dma.primaddress += 4; + break; + } } + if (mystique->dma.words_expected) + mystique->dma.words_expected--; + mystique->dma.primaddress += 4; + mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - words_transferred++; - if (mystique->dma.state == DMA_STATE_SEC) - mystique->dma.pri_state = 0; + if (mystique->dma.state == DMA_STATE_SEC) { + mystique->dma.sec_state = 0; + } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2684,9 +3003,36 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; + //pclog("DMA header (secondary): 0x%08X\n", mystique->dma.sec_header); + words_transferred++; + } + + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } uint32_t val; @@ -2705,23 +3051,40 @@ run_dma(mystique_t *mystique) mystique->blitter_submit_dma_refcount++; mystique_accel_ctrl_write_l(reg_addr, val, mystique); - + //pclog("DMA value (secondary): 0x%08X\n", val); mystique->dma.sec_header >>= 8; mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } break; case DMA_MODE_BLIT: { uint32_t val; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; @@ -2730,12 +3093,17 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } else { mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } } break; @@ -2744,6 +3112,9 @@ run_dma(mystique_t *mystique) fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); } break; + + default: + break; } } @@ -2751,9 +3122,9 @@ run_dma(mystique_t *mystique) } static void -fifo_thread(void *p) +fifo_thread(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; while (mystique->thread_run) { thread_set_event(mystique->fifo_not_full_event); @@ -2776,6 +3147,9 @@ fifo_thread(void *p) case FIFO_WRITE_ILOAD_LONG: mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); break; + + default: + break; } fifo->addr_type = FIFO_INVALID; @@ -2815,9 +3189,9 @@ wake_fifo_thread_now(mystique_t *mystique) } static void -mystique_wake_timer(void *p) +mystique_wake_timer(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -2837,9 +3211,9 @@ wait_fifo_idle(mystique_t *mystique) SOFTRAP IRQs and code reading the status register. Croc will get into an IRQ loop and triple fault if the ENDPRDMASTS flag is seen before the IRQ is taken*/ static void -mystique_softrap_pending_timer(void *p) +mystique_softrap_pending_timer(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); @@ -2848,12 +3222,14 @@ mystique_softrap_pending_timer(void *p) mystique->status |= STATUS_ENDPRDMASTS; } if (mystique->softrap_pending) { - mystique->softrap_pending = 0; - mystique->dma.secaddress = mystique->softrap_pending_val; mystique->status |= STATUS_SOFTRAPEN; + mystique->softrap_status_read = 0; + //pclog("softrapen\n"); mystique_update_irqs(mystique); + mystique->softrap_pending--; } + } static void @@ -2912,6 +3288,9 @@ bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) return dst | src; case BOP(0xf): return ~0; + + default: + break; } return 0; @@ -3268,6 +3647,9 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) case MACCESS_PWIDTH_32: min_size = 32; break; + + default: + break; } while (size >= min_size) { @@ -3825,10 +4207,10 @@ blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) } static void -blit_iload_iload_highv(mystique_t *mystique, uint32_t data, int size) +blit_iload_iload_highv(mystique_t *mystique, uint32_t data, UNUSED(int size)) { - uint8_t *src0; - uint8_t *src1; + const uint8_t *src0; + uint8_t *src1; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BUYUV: @@ -3903,21 +4285,43 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl } } +static int +z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +{ + switch (z_mode) { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); + + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } +} + static void -blit_line(mystique_t *mystique, int closed) +blit_line(mystique_t *mystique, int closed, int autoline) { svga_t *svga = &mystique->svga; - uint32_t src; + uint32_t src = 0; uint32_t dst; uint32_t old_dst; - int x; + int x = mystique->dwgreg.xdst; int z_write; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: - x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { + while (mystique->dwgreg.length >= 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -3925,8 +4329,16 @@ blit_line(mystique_t *mystique, int closed) dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_16: @@ -3934,17 +4346,33 @@ blit_line(mystique_t *mystique, int closed) dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + if (closed) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } break; case MACCESS_PWIDTH_24: - src = mystique->dwgreg.fcol; + src = mystique->dwgreg.fcol; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_32: @@ -3952,8 +4380,16 @@ blit_line(mystique_t *mystique, int closed) dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + if (closed) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && ((mystique->dwgreg.err > 0) || (mystique->dwgreg.err < 0)) && !autoline) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && (mystique->dwgreg.length > 0) && autoline) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } break; default: @@ -3961,19 +4397,26 @@ blit_line(mystique_t *mystique, int closed) } } + if (!mystique->dwgreg.length) + break; + if (mystique->dwgreg.sgn.sdydxl) x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else + else { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) + } + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; + if (mystique->dwgreg.sgn.sdydxl) { + mystique->dwgreg.ydst += (mystique->dwgreg.sgn.sdy ? -1 : 1); + mystique->dwgreg.ydst &= 0x7fffff; mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else + } else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; mystique->dwgreg.length--; } @@ -3982,21 +4425,32 @@ blit_line(mystique_t *mystique, int closed) case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - x = mystique->dwgreg.xdst; while (mystique->dwgreg.length > 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - uint16_t old_z = z_p[x]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t *z_p = (uint32_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 4 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint32_t old_z = z_p[x]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int r = 0; int g = 0; int b = 0; - if (z_write) - z_p[x] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_16: if (!(mystique->dwgreg.dr[4] & (1 << 23))) @@ -4022,32 +4476,46 @@ blit_line(mystique_t *mystique, int closed) else mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - if ((int32_t) mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if (mystique->dwgreg.err >= 0) { + mystique->dwgreg.err += mystique->dwgreg.k2; if (mystique->dwgreg.sgn.sdydxl) mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.err += mystique->dwgreg.k1; mystique->dwgreg.length--; } break; default: - /* pclog("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ +#if 0 + pclog("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#endif break; } @@ -4055,7 +4523,7 @@ blit_line(mystique_t *mystique, int closed) } static void -blit_autoline(mystique_t *mystique, int closed) +blit_line_start(mystique_t *mystique, int closed, int autoline) { int start_x = (int32_t) mystique->dwgreg.ar[5]; int start_y = (int32_t) mystique->dwgreg.ar[6]; @@ -4064,45 +4532,54 @@ blit_autoline(mystique_t *mystique, int closed) int dx = end_x - start_x; int dy = end_y - start_y; - if (ABS(dx) > ABS(dy)) { - mystique->dwgreg.sgn.sdydxl = 1; - mystique->dwgreg.ar[0] = 2 * ABS(dy); - mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); - mystique->dwgreg.length = ABS(end_x - start_x); + if (autoline) { + if (ABS(dx) > ABS(dy)) { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.k1 = 2 * ABS(dy); + mystique->dwgreg.err = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dy) - 2 * ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } else { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.k1 = 2 * ABS(dx); + mystique->dwgreg.err = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.k2 = 2 * ABS(dx) - 2 * ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; } else { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.ar[0] = 2 * ABS(dx); - mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); - mystique->dwgreg.length = ABS(end_y - start_y); + mystique->dwgreg.k1 = (int32_t) mystique->dwgreg.ar[0]; + mystique->dwgreg.err = (int32_t) mystique->dwgreg.ar[1]; + mystique->dwgreg.k2 = (int32_t) mystique->dwgreg.ar[2]; } - mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; - mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; - blit_line(mystique, closed); + blit_line(mystique, closed, autoline); - mystique->dwgreg.ar[5] = end_x; - mystique->dwgreg.xdst = end_x; - mystique->dwgreg.ar[6] = end_y; - mystique->dwgreg.ydst = end_y; - mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + if (autoline) { + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + } } static void blit_trap(mystique_t *mystique) { svga_t *svga = &mystique->svga; + uint64_t z_back_32; uint32_t z_back; uint32_t r_back; uint32_t g_back; uint32_t b_back; int z_write; int y; + int err_l = (int32_t)mystique->dwgreg.ar[1]; + int err_r = (int32_t)mystique->dwgreg.ar[4]; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: case DWGCTRL_ATYPE_RPL: @@ -4111,8 +4588,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4144,25 +4627,21 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } + len--; x_l++; - mystique->pixel_count++; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + err_l += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4178,8 +4657,14 @@ blit_trap(mystique_t *mystique) int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + int len; - while (x_l != x_r) { + if (x_l > x_r) + len = x_l - x_r; + else + len = x_r - x_l; + + while (len > 0) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { int xoff = (mystique->dwgreg.xoff + (x_l & 7)) & 15; int pattern = mystique->dwgreg.pattern[yoff][xoff]; @@ -4225,24 +4710,20 @@ blit_trap(mystique_t *mystique) } } x_l++; - mystique->pixel_count++; + len--; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((err_l < 0) && mystique->dwgreg.ar[0]) { + err_l += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + err_l += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((err_r < 0) && mystique->dwgreg.ar[6]) { + err_r += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + err_r += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4258,12 +4739,14 @@ blit_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + z_back_32 = mystique->dwgreg.extended_dr[0]; + z_back = mystique->dwgreg.dr[0]; r_back = mystique->dwgreg.dr[4]; g_back = mystique->dwgreg.dr[8]; @@ -4271,10 +4754,18 @@ blit_trap(mystique_t *mystique) while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { uint32_t dst = 0; uint32_t old_dst; int r = 0; @@ -4288,8 +4779,13 @@ blit_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -4320,16 +4816,30 @@ blit_trap(mystique_t *mystique) } } - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l++; - mystique->pixel_count++; + if (x_l > x_r) + x_l--; + else + x_l++; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; @@ -4347,7 +4857,13 @@ blit_trap(mystique_t *mystique) mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; @@ -4361,41 +4877,27 @@ blit_trap(mystique_t *mystique) break; default: - fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#if 0 + pclog("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#endif + break; } mystique->blitter_complete_refcount++; } -static int -texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *tex_a, int *atransp, int s, int t, int tex_pitch) { - svga_t *svga = &mystique->svga; - - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; - const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; - const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; - uint16_t src = 0; - int s; - int t; - - if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { - const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + svga_t* svga = &mystique->svga; + uint16_t src = 0x0; - s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; - t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; - } else { - const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8] /*>> 16*/) : 0; + int atransp_dummy = 0; - s = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift; /*((16+20)-12);*/ - t = (((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift; /*((16+20)-9);*/ - } + if (!atransp) + atransp = &atransp_dummy; if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { if (s < 0) @@ -4415,7 +4917,7 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { case TEXCTL_TEXFORMAT_TW4: - src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (((t * tex_pitch) + s) >> 1)) & mystique->vram_mask]; if (s & 1) src >>= 4; else @@ -4426,14 +4928,14 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra *atransp = 0; break; case TEXCTL_TEXFORMAT_TW8: - src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (t * tex_pitch) + s) & mystique->vram_mask]; *tex_r = mystique->lut[src].r; *tex_g = mystique->lut[src].g; *tex_b = mystique->lut[src].b; *atransp = 0; break; case TEXCTL_TEXFORMAT_TW15: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = ((src >> 10) & 0x1f) << 3; *tex_g = ((src >> 5) & 0x1f) << 3; *tex_b = (src & 0x1f) << 3; @@ -4442,8 +4944,22 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra else *atransp = 0; break; + case TEXCTL_TEXFORMAT_TW12: + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 8) & 0xf) << 4; + *tex_g = ((src >> 4) & 0xf) << 4; + *tex_b = (src & 0xf) << 4; + *tex_a = ((src >> 12) & 0xf) << 4; + if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { + *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; + } else { + uint8_t ta_mask = mystique->dwgreg.ta_mask ? 0xf : 0x0; + uint8_t ta_key = mystique->dwgreg.ta_key ? 0xf : 0x0; + *atransp = (((src >> 12) & 0xf) & ta_mask) == ta_key; + } + break; case TEXCTL_TEXFORMAT_TW16: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = (src >> 11) << 3; *tex_g = ((src >> 5) & 0x3f) << 2; *tex_b = (src & 0x1f) << 3; @@ -4453,6 +4969,111 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); break; } + return src; +} + +static double lerp(double v0, double v1, double t) { + return (1. - t) * v0 + t * v1; +} + +static int +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) +{ + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s; + int t; + int tex_pitch = 1 << tex_shift; + double s_frac = 0; + double t_frac = 0; + + *tex_a = 255; + + if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) + { + tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; + if (tex_pitch == 0) + tex_pitch = 2048; + } + + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + + s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; + s_frac = (((int32_t) mystique->dwgreg.tmr[6] >> s_shift) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int32_t) mystique->dwgreg.tmr[7] >> t_shift) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } else { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8]) : 0; + + s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) >> s_shift; + t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) >> t_shift; + s_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } else + s &= w_mask; + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } else + t &= h_mask; + + src = texture_texel_fetch(mystique, tex_r, tex_g, tex_b, tex_a, atransp, s, t, tex_pitch); + switch (mystique->dwgreg.texfilter & 3) + { + case 0: + s_frac = t_frac = 0; + break; + case 1: + case 2: + break; + case 3: + s_frac = t_frac = .25; + break; + } + if (s_frac && s != w_mask) + { + int s_tex_r = 0, s_tex_g = 0, s_tex_b = 0, s_tex_a = 255; + texture_texel_fetch(mystique, &s_tex_r, &s_tex_g, &s_tex_b, &s_tex_a, NULL, s + 1, t, tex_pitch); + *tex_r = (int)lerp(*tex_r, s_tex_r, s_frac); + *tex_g = (int)lerp(*tex_g, s_tex_g, s_frac); + *tex_b = (int)lerp(*tex_b, s_tex_b, s_frac); + *tex_a = (int)lerp(*tex_a, s_tex_a, s_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } + if (t_frac && t != h_mask) + { + int t_tex_r = 0, t_tex_g = 0, t_tex_b = 0, t_tex_a = 255; + texture_texel_fetch(mystique, &t_tex_r, &t_tex_g, &t_tex_b, &t_tex_a, NULL, s, t + 1, tex_pitch); + *tex_r = (int)lerp(*tex_r, t_tex_r, t_frac); + *tex_g = (int)lerp(*tex_g, t_tex_g, t_frac); + *tex_b = (int)lerp(*tex_b, t_tex_b, t_frac); + *tex_a = (int)lerp(*tex_a, t_tex_a, t_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } return ((src & tkmask) == tckey); } @@ -4466,8 +5087,6 @@ blit_texture_trap(mystique_t *mystique) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: @@ -4475,12 +5094,14 @@ blit_texture_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + uint64_t z_back_32 = mystique->dwgreg.extended_dr[0]; + uint32_t z_back = mystique->dwgreg.dr[0]; uint32_t r_back = mystique->dwgreg.dr[4]; uint32_t g_back = mystique->dwgreg.dr[8]; @@ -4488,21 +5109,35 @@ blit_texture_trap(mystique_t *mystique) uint32_t s_back = mystique->dwgreg.tmr[6]; uint32_t t_back = mystique->dwgreg.tmr[7]; uint32_t q_back = mystique->dwgreg.tmr[8]; + uint32_t a_back = mystique->dwgreg.alphastart; + uint32_t fog_back = mystique->dwgreg.fogstart; while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int tex_r = 0; int tex_g = 0; int tex_b = 0; + int tex_a = 255; int ctransp; int atransp = 0; int i_r = 0; int i_g = 0; int i_b = 0; + int i_a = 255; + int i_fog = 0; + uint8_t final_a = 255; if (!(mystique->dwgreg.dr[4] & (1 << 23))) i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; @@ -4511,7 +5146,43 @@ blit_texture_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + if (mystique->type >= MGA_G100) + { + if (!(mystique->dwgreg.alphastart & (1 << 23))) + i_a = (mystique->dwgreg.alphastart >> 15) & 0xff; + else + i_a = 0; + + if (!(mystique->dwgreg.fogstart & (1 << 23))) + i_fog = (mystique->dwgreg.fogstart >> 15) & 0xff; + else + i_fog = 0; + } + + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp, &tex_a); + + if (mystique->type >= MGA_G100) + { + uint8_t alpha_sel = (mystique->dwgreg.alphactrl >> 24) & 3; + + switch (alpha_sel) + { + case 0x0: /* alpha from texture */ + final_a = tex_a; + break; + default: + case 0x1: /* interpolated alpha */ + if ((mystique->dwgreg.alphactrl & (1 << 11))) + final_a = i_a; + break; + case 0x2: /* modulated alpha */ + if (!(mystique->dwgreg.alphactrl & (1 << 11))) + final_a = tex_a; + else + final_a = ((i_a * tex_a) >> 8) & 0xFF; + break; + } + } switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { case 0: @@ -4561,6 +5232,26 @@ blit_texture_trap(mystique_t *mystique) fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); } + if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN)) + { + tex_r = (tex_r * ((i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * ((255 - i_fog) / 255.); + tex_g = (tex_g * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * ((255 - i_fog) / 255.); + tex_b = (tex_b * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * ((255 - i_fog) / 255.); + } + + if (final_a != 255) + { + { + double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3]; + double final_a_frac = (final_a) / 255.; + if (final_a_frac >= threshold) { + final_a = 255; + } else { + goto skip_pixel; + } + } + } + if (dest32) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; @@ -4568,30 +5259,57 @@ blit_texture_trap(mystique_t *mystique) ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; } - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } } } skip_pixel: - x_l++; - mystique->pixel_count++; + if (x_l > x_r) + x_l--; + else + x_l++; - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; - mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; - mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.fogstart = fog_back + mystique->dwgreg.fogyinc; + mystique->dwgreg.alphastart = a_back + mystique->dwgreg.alphayinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; @@ -4606,13 +5324,23 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += dx * mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += dx * mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4644,6 +5372,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; for (y = 0; y < mystique->dwgreg.length; y++) { @@ -4652,7 +5381,7 @@ blit_bitblt(mystique_t *mystique) while (1) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); uint32_t old_dst; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { @@ -4705,9 +5434,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4745,6 +5479,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_RSTR: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); @@ -4756,7 +5491,7 @@ blit_bitblt(mystique_t *mystique) while (1) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; @@ -4812,9 +5547,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4895,9 +5635,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4922,7 +5667,9 @@ blit_bitblt(mystique_t *mystique) break; default: - /* pclog("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ +#if 0 + pclog("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#endif break; } @@ -4936,7 +5683,9 @@ blit_iload(mystique_t *mystique) case DWGCTRL_ATYPE_RPL: case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_BLK: - /* pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); */ +#if 0 + pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); +#endif switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BFCOL: case DWGCTRL_BLTMOD_BMONOLEF: @@ -4948,7 +5697,9 @@ blit_iload(mystique_t *mystique) mystique->dwgreg.iload_rem_data = 0; mystique->dwgreg.iload_rem_count = 0; mystique->busy = 1; - /* pclog("ILOAD busy\n"); */ +#if 0 + pclog("ILOAD busy\n"); +#endif mystique->dwgreg.words = 0; break; @@ -4976,7 +5727,9 @@ blit_idump(mystique_t *mystique) mystique->dwgreg.iload_rem_data = 0; mystique->dwgreg.idump_end_of_line = 0; mystique->busy = 1; - /* pclog("IDUMP ATYPE RPL busy\n"); */ +#if 0 + pclog("IDUMP ATYPE RPL busy\n"); +#endif break; default: @@ -5073,27 +5826,32 @@ blit_iload_highv(mystique_t *mystique) static void mystique_start_blit(mystique_t *mystique) { + svga_t *svga = &mystique->svga; uint64_t start_time = plat_timer_read(); uint64_t end_time; + /*Make sure we don't get any artifacts.*/ + svga->chain2_write = 0; + svga->chain2_read = 0; + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; mystique->maccess_running = mystique->maccess; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { case DWGCTRL_OPCODE_LINE_OPEN: - blit_line(mystique, 0); + blit_line_start(mystique, 0, 0); break; case DWGCTRL_OPCODE_AUTOLINE_OPEN: - blit_autoline(mystique, 0); + blit_line_start(mystique, 0, 1); break; case DWGCTRL_OPCODE_LINE_CLOSE: - blit_line(mystique, 1); + blit_line_start(mystique, 1, 0); break; case DWGCTRL_OPCODE_AUTOLINE_CLOSE: - blit_autoline(mystique, 1); + blit_line_start(mystique, 1, 1); break; case DWGCTRL_OPCODE_TRAP: @@ -5148,9 +5906,9 @@ mystique_start_blit(mystique_t *mystique) static void mystique_hwcursor_draw(svga_t *svga, int displine) { - mystique_t *mystique = (mystique_t *) svga->p; - uint64_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + const mystique_t *mystique = (mystique_t *) svga->priv; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -5162,15 +5920,18 @@ mystique_hwcursor_draw(svga_t *svga, int displine) case XCURCTRL_CURMODE_XGA: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); else if (dat[0] & (1ULL << 63)) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; + svga->monitor->target_buffer->line[displine][(offset + svga->x_add) & 2047] ^= 0xffffff; offset++; dat[0] <<= 1; dat[1] <<= 1; } break; + + default: + break; } if (svga->interlace && !svga->hwcursor_oddeven) @@ -5178,9 +5939,30 @@ mystique_hwcursor_draw(svga_t *svga, int displine) } static uint8_t -mystique_pci_read(int func, int addr, void *p) +mystique_tvp3026_gpio_read(uint8_t cntl, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; + + uint8_t ret = 0xff; + if (!i2c_gpio_get_scl(mystique->i2c_ddc)) + ret &= ~0x10; + if (!i2c_gpio_get_sda(mystique->i2c_ddc)) + ret &= ~0x04; + return ret; +} + +static void +mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; + + i2c_gpio_set(mystique->i2c_ddc, !(cntl & 0x10) || (data & 0x10), !(cntl & 0x04) || (data & 0x04)); +} + +static uint8_t +mystique_pci_read(UNUSED(int func), int addr, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) @@ -5195,10 +5977,16 @@ mystique_pci_read(int func, int addr, void *p) break; case 0x02: - ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a; + if (mystique->type == MGA_G100) + ret = 0x01; + else + ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); break; /*MGA*/ case 0x03: - ret = 0x05; + if (mystique->type == MGA_G100) + ret = 0x10; + else + ret = 0x05; break; case PCI_REG_COMMAND: @@ -5216,7 +6004,7 @@ mystique_pci_read(int func, int addr, void *p) break; /*Fast DEVSEL timing*/ case 0x08: - ret = 0; + ret = (mystique->type == MGA_1164SG) ? 3 : 0; break; /*Revision ID*/ case 0x09: ret = 0; @@ -5231,25 +6019,46 @@ mystique_pci_read(int func, int addr, void *p) case 0x10: ret = 0x00; - break; /*Control aperture*/ + break; /*Control aperture for Millennium and Mystique, LFB for Mystique 220 and later*/ case 0x11: - ret = (mystique->ctrl_base >> 8) & 0xc0; + if (mystique->type >= MGA_1164SG) + ret = 0x00; + else + ret = (mystique->ctrl_base >> 8) & 0xc0; break; case 0x12: - ret = mystique->ctrl_base >> 16; + if (mystique->type >= MGA_1164SG) + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); + else + ret = mystique->ctrl_base >> 16; break; case 0x13: - ret = mystique->ctrl_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->lfb_base >> 24; + else + ret = mystique->ctrl_base >> 24; break; case 0x14: ret = 0x00; - break; /*Linear frame buffer*/ + break; /*LFB for Millennium and Mystique, Control aperture for Mystique 220 and later*/ + case 0x15: + if (mystique->type >= MGA_1164SG) + ret = (mystique->ctrl_base >> 8) & 0xc0; + else + ret = 0x00; + break; case 0x16: - ret = (mystique->lfb_base >> 16) & 0x80; + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 16; + else + ret = (mystique->lfb_base >> 16) & 0x80; break; case 0x17: - ret = mystique->lfb_base >> 24; + if (mystique->type >= MGA_1164SG) + ret = mystique->ctrl_base >> 24; + else + ret = mystique->lfb_base >> 24; break; case 0x18: @@ -5288,6 +6097,10 @@ mystique_pci_read(int func, int addr, void *p) ret = mystique->pci_regs[0x33]; break; + case 0x34: + ret = (mystique->type == MGA_G100) ? 0xdc : 0x00; + break; + case 0x3c: ret = mystique->int_line; break; @@ -5322,15 +6135,71 @@ mystique_pci_read(int func, int addr, void *p) addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); ret = mystique_ctrl_read_b(addr, mystique); break; + + case 0xdc: + ret = 0x01; + break; + + case 0xdd: + ret = 0xf0; + break; + + case 0xde: + ret = 0x21; + break; + + /* No support for turning off the video adapter yet. */ + case 0xe0: + ret = 0x0; + break; + + case 0xf0: + ret = 0x02; + break; + + case 0xf1: + ret = 0x00; + break; + + case 0xf2: + ret = 0x10; + break; + + case 0xf4: + ret = 0x1; + break; + + case 0xf5: + ret = 0x2; + break; + + case 0xf7: + ret = 0x1; + break; + + case 0xf8: + ret = mystique->pci_regs[0xf8] & 0x7; + break; + + case 0xf9: + ret = mystique->pci_regs[0xf9] & 0x3; + break; + + case 0xfb: + ret = mystique->pci_regs[0xfb]; + break; + + default: + break; } return ret; } static void -mystique_pci_write(int func, int addr, uint8_t val, void *p) +mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; switch (addr) { case PCI_REG_COMMAND: @@ -5347,25 +6216,61 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x11: - mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) + break; + else { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } break; case 0x12: - mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + break; + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } break; case 0x13: - mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + if (mystique->type >= MGA_2164W) + mystique->lfb_base = val << 24; + else + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + + mystique_recalc_mapping(mystique); + } else { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; + case 0x15: + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + } + break; case 0x16: - mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + } break; case 0x17: - mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); - mystique_recalc_mapping(mystique); + if (mystique->type >= MGA_1164SG) { + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + } else { + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + } break; case 0x1a: @@ -5383,9 +6288,11 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) if (!(mystique->pci_regs[0x43] & 0x40)) return; mystique->pci_regs[addr] = val; + if (addr == 0x30) + mystique->pci_regs[addr] &= 1; if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -5408,12 +6315,12 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) if (addr == 0x43) { if (val & 0x40) { if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); } else - mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } break; @@ -5436,17 +6343,66 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) case 0x4a: case 0x4b: addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); - /* pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); */ +#if 0 + pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); +#endif mystique_ctrl_write_b(addr, val, mystique); break; + + case 0xf8: + mystique->pci_regs[0xf8] = val & 0x7; + break; + + case 0xf9: + mystique->pci_regs[0xf9] = val & 0x3; + break; + + case 0xfb: + mystique->pci_regs[0xfb] = val; + break; + + default: + break; } } +static uint32_t +mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + mystique_t *mystique = (mystique_t*)svga->priv; + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + if (mystique->xgenctrl & (1 << 2)) + color &= 0x7FFF; +#if 0 + uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); + uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); + uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); +#else + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 10]); +#endif + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; +} + static void * mystique_init(const device_t *info) { mystique_t *mystique = malloc(sizeof(mystique_t)); - char *romfn; + const char *romfn = NULL; memset(mystique, 0, sizeof(mystique_t)); @@ -5454,12 +6410,19 @@ mystique_init(const device_t *info) if (mystique->type == MGA_2064W) romfn = ROM_MILLENNIUM; + else if (mystique->type == MGA_2164W) + romfn = ROM_MILLENNIUM_II; else if (mystique->type == MGA_1064SG) romfn = ROM_MYSTIQUE; + else if (mystique->type == MGA_G100) + romfn = ROM_G100; else romfn = ROM_MYSTIQUE_220; - rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (mystique->type == MGA_G100) + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&mystique->bios_rom.mapping); mystique->vram_size = device_get_config_int("memory"); @@ -5469,8 +6432,8 @@ mystique_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); - if (mystique->type == MGA_2064W) { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, (mystique->type == MGA_2164W) ? &timing_matrox_mystique : &timing_matrox_millennium); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, mystique_in, mystique_out, @@ -5480,6 +6443,10 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + mystique->svga.conv_16to32 = tvp3026_conv_16to32; + if (mystique->type == MGA_2164W) + mystique->svga.decode_mask = 0xffffff; + tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, @@ -5489,6 +6456,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; + if (mystique->type == MGA_G100) + mystique->svga.decode_mask = 0xffffff; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); @@ -5501,7 +6470,7 @@ mystique_init(const device_t *info) mem_mapping_add(&mystique->lfb_mapping, 0, 0, mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, @@ -5510,7 +6479,10 @@ mystique_init(const device_t *info) NULL, 0, mystique); mem_mapping_disable(&mystique->iload_mapping); - mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + if (romfn == NULL) + pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); + else + pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); mystique->pci_regs[0x06] = 0x80; mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; @@ -5559,8 +6531,13 @@ mystique_init(const device_t *info) mystique->status = STATUS_ENDPRDMASTS; + mystique->softrap_status_read = 1; + mystique->svga.vsync_callback = mystique_vsync_callback; + if (mystique->type != MGA_2064W && mystique->type != MGA_2164W) + mystique->svga.conv_16to32 = mystique_conv_16to32; + mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); mystique->ddc = ddc_init(i2c_gpio_get_bus(mystique->i2c_ddc)); @@ -5569,9 +6546,9 @@ mystique_init(const device_t *info) } static void -mystique_close(void *p) +mystique_close(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; mystique->thread_run = 0; thread_set_event(mystique->wake_fifo_thread); @@ -5607,18 +6584,30 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } +static int +millennium_ii_available(void) +{ + return rom_present(ROM_MILLENNIUM_II); +} + +static int +matrox_g100_available(void) +{ + return rom_present(ROM_G100); +} + static void -mystique_speed_changed(void *p) +mystique_speed_changed(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; svga_recalctimings(&mystique->svga); } static void -mystique_force_redraw(void *p) +mystique_force_redraw(void *priv) { - mystique_t *mystique = (mystique_t *) p; + mystique_t *mystique = (mystique_t *) priv; mystique->svga.fullchange = changeframecount; } @@ -5655,6 +6644,38 @@ static const device_config_t mystique_config[] = { // clang-format on }; +static const device_config_t millennium_ii_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } + }, + .default_int = 8 + }, + { + .type = CONFIG_END + } + // clang-format on +}; + const device_t millennium_device = { .name = "Matrox Millennium", .internal_name = "millennium", @@ -5696,3 +6717,31 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; + +const device_t millennium_ii_device = { + .name = "Matrox Millennium II", + .internal_name = "millennium_ii", + .flags = DEVICE_PCI, + .local = MGA_2164W, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = millennium_ii_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = millennium_ii_config +}; + +const device_t productiva_g100_device = { + .name = "Matrox Productiva G100", + .internal_name = "productiva_g100", + .flags = DEVICE_AGP, + .local = MGA_G100, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = matrox_g100_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = millennium_ii_config +}; diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index 2d673393bb..32c103a8be 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -38,6 +38,7 @@ #include <86box/vid_cga.h> #include <86box/vid_nga.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> #define CGA_RGB 0 #define CGA_COMPOSITE 1 @@ -86,7 +87,7 @@ nga_in(uint16_t addr, void *priv) } void -nga_waitstates(void *p) +nga_waitstates(UNUSED(void *priv)) { int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; @@ -553,7 +554,7 @@ nga_speed_changed(void *priv) } void * -nga_init(const device_t *info) +nga_init(UNUSED(const device_t *info)) { int mem; uint8_t charset; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 4a3b229341..f5bc449e69 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -29,6 +29,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_unused.h> #define BIOS_037C_PATH "roms/video/oti/bios.bin" #define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN" @@ -37,11 +38,11 @@ #define BIOS_077_PATH "roms/video/oti/oti077.vbi" enum { - OTI_037C, - OTI_067 = 2, - OTI_067_AMA932J, - OTI_067_M300 = 4, - OTI_077 = 5 + OTI_037C = 0, + OTI_067 = 2, + OTI_067_AMA932J = 3, + OTI_067_M300 = 4, + OTI_077 = 5 }; typedef struct { @@ -64,9 +65,9 @@ typedef struct { static video_timings_t timing_oti = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; static void -oti_out(uint16_t addr, uint8_t val, void *p) +oti_out(uint16_t addr, uint8_t val, void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; svga_t *svga = &oti->svga; uint8_t old; uint8_t idx; @@ -83,9 +84,9 @@ oti_out(uint16_t addr, uint8_t val, void *p) if (!oti->chip_id) { oti->enable_register = val & 1; return; - } else - break; - break; + } + svga_out(addr, val, svga); + return; case 0x3c6: case 0x3c7: @@ -156,8 +157,8 @@ oti_out(uint16_t addr, uint8_t val, void *p) svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; switch ((val & 0xc0) >> 6) { - case 0x00: /* 256 kB of memory */ default: + case 0x00: /* 256 kB of memory */ enable = (oti->vram_size >= 256); if (val & 0x0c) svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff); @@ -191,17 +192,23 @@ oti_out(uint16_t addr, uint8_t val, void *p) svga->read_bank = (val & 0xf) * 65536; svga->write_bank = (val >> 4) * 65536; break; + + default: + break; } return; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -oti_in(uint16_t addr, void *p) +oti_in(uint16_t addr, void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; svga_t *svga = &oti->svga; uint8_t idx; uint8_t temp; @@ -290,6 +297,9 @@ oti_in(uint16_t addr, void *p) if (svga->attrregs[0x11] & 0x80) svga->cgastat |= 0x20; break; + + default: + break; } temp = svga->cgastat; break; @@ -319,9 +329,9 @@ oti_in(uint16_t addr, void *p) } static void -oti_pos_out(uint16_t addr, uint8_t val, void *p) +oti_pos_out(UNUSED(uint16_t addr), uint8_t val, void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; if ((val ^ oti->pos) & 8) { if (val & 8) @@ -336,9 +346,9 @@ oti_pos_out(uint16_t addr, uint8_t val, void *p) } static uint8_t -oti_pos_in(uint16_t addr, void *p) +oti_pos_in(UNUSED(uint16_t addr), void *priv) { - oti_t *oti = (oti_t *) p; + const oti_t *oti = (oti_t *) priv; return (oti->pos); } @@ -349,8 +359,8 @@ oti_getclock(int clock) float ret = 0.0; switch (clock) { - case 0: default: + case 0: ret = 25175000.0; break; case 1: @@ -373,8 +383,8 @@ oti_getclock(int clock) static void oti_recalctimings(svga_t *svga) { - oti_t *oti = (oti_t *) svga->p; - int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3); + const oti_t *oti = (oti_t *) svga->priv; + int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3); svga->clock = (cpuclock * (double) (1ULL << 32)) / oti_getclock(clk_sel); @@ -409,8 +419,8 @@ oti_recalctimings(svga_t *svga) static void * oti_init(const device_t *info) { - oti_t *oti = malloc(sizeof(oti_t)); - char *romfn = NULL; + oti_t *oti = malloc(sizeof(oti_t)); + const char *romfn = NULL; memset(oti, 0x00, sizeof(oti_t)); oti->chip_id = info->local; @@ -422,8 +432,10 @@ oti_init(const device_t *info) romfn = BIOS_037C_PATH; oti->vram_size = 256; oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ - /* io_sethandler(0x03c0, 32, - oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */ +#if 0 + io_sethandler(0x03c0, 32, + oti_in, NULL, NULL, oti_out, NULL, NULL, oti); +#endif break; case OTI_067_AMA932J: @@ -452,6 +464,9 @@ oti_init(const device_t *info) oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); break; + + default: + break; } if (romfn != NULL) { @@ -479,9 +494,9 @@ oti_init(const device_t *info) } static void -oti_close(void *p) +oti_close(void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; svga_close(&oti->svga); @@ -489,17 +504,17 @@ oti_close(void *p) } static void -oti_speed_changed(void *p) +oti_speed_changed(void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; svga_recalctimings(&oti->svga); } static void -oti_force_redraw(void *p) +oti_force_redraw(void *priv) { - oti_t *oti = (oti_t *) p; + oti_t *oti = (oti_t *) priv; oti->svga.fullchange = changeframecount; } diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index 20be41fade..c3073898df 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -39,6 +39,7 @@ #include <86box/vid_cga.h> #include <86box/vid_ogc.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> /* * Current bugs: @@ -83,9 +84,10 @@ ogc_out(uint16_t addr, uint8_t val, void *priv) { ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; - // } +#if 0 + if (addr >= 0x3c0 && addr <= 0x3cf) + addr = addr + 16; +#endif switch (addr) { case 0x3d4: @@ -101,6 +103,9 @@ ogc_out(uint16_t addr, uint8_t val, void *priv) /* select 1st or 2nd 16k vram block to be used */ ogc->base = (val & 0x08) ? 0x4000 : 0; break; + + default: + break; } } @@ -109,9 +114,10 @@ ogc_in(uint16_t addr, void *priv) { ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; - // } +#if 0 + if (addr >= 0x3c0 && addr <= 0x3cf) + addr = addr + 16; +#endif uint8_t ret = 0xff; @@ -132,15 +138,18 @@ ogc_in(uint16_t addr, void *priv) ret = ret | 0xe0; if (ogc->mono_display) ret = ret | 0x10; - break; } + break; + + default: + break; } return ret; } void -ogc_waitstates(void *p) +ogc_waitstates(UNUSED(void *priv)) { int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; @@ -512,7 +521,7 @@ ogc_poll(void *priv) if (ogc->cga.cgadispon) ogc->cga.cgastat &= ~1; - if ((ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1)))) + if (ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1))) ogc->cga.con = 1; } /* 80-columns */ @@ -572,9 +581,11 @@ ogc_mdaattr_rebuild(void) * - Optional EGC expansion board (which handles 640x400x16) not implemented */ void * -ogc_init(const device_t *info) +ogc_init(UNUSED(const device_t *info)) { - // int display_type; +#if 0 + int display_type; +#endif ogc_t *ogc = (ogc_t *) malloc(sizeof(ogc_t)); memset(ogc, 0x00, sizeof(ogc_t)); @@ -582,8 +593,10 @@ ogc_init(const device_t *info) loadfont("roms/video/ogc/ogc graphics board go380 258 pqbq.bin", 1); - /* composite is not working yet */ - // display_type = device_get_config_int("display_type"); + /* FIXME: composite is not working yet */ +#if 0 + display_type = device_get_config_int("display_type"); +#endif ogc->cga.composite = 0; // (display_type != CGA_RGB); ogc->cga.revision = device_get_config_int("composite_type"); ogc->cga.snow_enabled = device_get_config_int("snow_enabled"); diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 8971fe01ee..30666e82cc 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -51,7 +51,7 @@ typedef struct paradise_t { uint32_t read_bank[4], write_bank[4]; int interlace; - int check, check2; + int check; struct { uint8_t reg_block_ptr; @@ -75,10 +75,11 @@ static video_timings_t timing_paradise_wd90c = { .type = VIDEO_ISA, .write_b = void paradise_remap(paradise_t *paradise); uint8_t -paradise_in(uint16_t addr, void *p) +paradise_in(uint16_t addr, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; + uint8_t temp = 0; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -109,16 +110,20 @@ paradise_in(uint16_t addr, void *p) } switch (svga->gdcaddr) { case 0x0b: + temp = svga->gdcreg[0x0b]; if (paradise->type == WD90C30) { if (paradise->vram_mask == ((512 << 10) - 1)) { - svga->gdcreg[0x0b] |= 0xc0; - svga->gdcreg[0x0b] &= ~0x40; + temp &= ~0x40; + temp |= 0xc0; } } - return svga->gdcreg[0x0b]; + return temp; case 0x0f: return (svga->gdcreg[0x0f] & 0x17) | 0x80; + + default: + break; } break; @@ -130,14 +135,17 @@ paradise_in(uint16_t addr, void *p) if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) return 0xff; return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); } void -paradise_out(uint16_t addr, uint8_t val, void *p) +paradise_out(uint16_t addr, uint8_t val, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; uint8_t old; @@ -178,9 +186,10 @@ paradise_out(uint16_t addr, uint8_t val, void *p) return; } + old = svga->gdcreg[svga->gdcaddr]; switch (svga->gdcaddr) { case 6: - if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) { + if (old ^ (val & 0x0c)) { switch (val & 0x0c) { case 0x00: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -198,10 +207,13 @@ paradise_out(uint16_t addr, uint8_t val, void *p) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } + svga->gdcreg[6] = val; + paradise_remap(paradise); } - svga->gdcreg[6] = val; - paradise_remap(paradise); return; case 9: @@ -213,6 +225,13 @@ paradise_out(uint16_t addr, uint8_t val, void *p) svga->gdcreg[0x0b] = val; paradise_remap(paradise); return; + case 0x0e: + svga->gdcreg[0x0e] = val; + svga_recalctimings(svga); + return; + + default: + break; } break; @@ -246,13 +265,7 @@ paradise_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x46e8: - io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_disable(¶dise->svga.mapping); - if (val & 8) { - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_enable(¶dise->svga.mapping); - } + default: break; } @@ -263,6 +276,7 @@ void paradise_remap(paradise_t *paradise) { svga_t *svga = ¶dise->svga; + paradise->check = 0; if (svga->seqregs[0x11] & 0x80) { @@ -301,9 +315,7 @@ paradise_remap(paradise_t *paradise) void paradise_recalctimings(svga_t *svga) { - paradise_t *paradise = (paradise_t *) svga->p; - - svga->lowres = !(svga->gdcreg[0x0e] & 0x01); + const paradise_t *paradise = (paradise_t *) svga->priv; if (paradise->type == WD90C30) { if (svga->crtc[0x3e] & 0x01) @@ -319,43 +331,61 @@ paradise_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x2d] & 0x20); - if (!svga->interlace && svga->lowres && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to + if (!svga->interlace && !(svga->gdcreg[0x0e] & 0x01) && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to a windowed DOS box in Win3.x*/ svga->interlace = 1; } } if (paradise->type < WD90C30) { - if (svga->bpp >= 8 && !svga->lowres) { - svga->render = svga_render_8bpp_highres; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) { + svga->render = svga_render_8bpp_highres; + } } } else { - if (svga->bpp >= 8 && !svga->lowres) { - if (svga->bpp == 16) { - svga->render = svga_render_16bpp_highres; - svga->hdisp >>= 1; - } else if (svga->bpp == 15) { - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - } else { - svga->render = svga_render_8bpp_highres; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->bpp >= 8) && (svga->gdcreg[0x0e] & 0x01)) { + if (svga->bpp == 16) { + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + if (svga->hdisp == 788) + svga->hdisp += 12; + if (svga->hdisp == 800) + svga->ma_latch -= 3; + } else if (svga->bpp == 15) { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + if (svga->hdisp == 788) + svga->hdisp += 12; + if (svga->hdisp == 800) + svga->ma_latch -= 3; + } else { + svga->render = svga_render_8bpp_highres; + } } } } + svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask; } static void -paradise_write(uint32_t addr, uint8_t val, void *p) +paradise_write(uint32_t addr, uint8_t val, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + svga_write(addr, val, svga); + return; + } + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -390,21 +420,25 @@ paradise_write(uint32_t addr, uint8_t val, void *p) } } } - svga_write_linear(addr, val, svga); } static void -paradise_writew(uint32_t addr, uint16_t val, void *p) +paradise_writew(uint32_t addr, uint16_t val, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + svga_writew(addr, val, svga); + return; + } + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -439,22 +473,25 @@ paradise_writew(uint32_t addr, uint16_t val, void *p) } } } - svga_writew_linear(addr, val, svga); } static uint8_t -paradise_read(uint32_t addr, void *p) +paradise_read(uint32_t addr, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + return svga_read(addr, svga); + } + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -489,21 +526,24 @@ paradise_read(uint32_t addr, void *p) } } } - return svga_read_linear(addr, svga); } static uint16_t -paradise_readw(uint32_t addr, void *p) +paradise_readw(uint32_t addr, void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; uint32_t prev_addr; uint32_t prev_addr2; + if (!(svga->gdcreg[5] & 0x40)) { + return svga_readw(addr, svga); + } + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; /*Could be done in a better way but it works.*/ - if (!svga->lowres) { + if (svga->gdcreg[0x0e] & 0x01) { if (paradise->check) { prev_addr = addr & 3; prev_addr2 = addr & 0xfffc; @@ -538,7 +578,6 @@ paradise_readw(uint32_t addr, void *p) } } } - return svga_readw_linear(addr, svga); } @@ -583,6 +622,9 @@ paradise_init(const device_t *info, uint32_t memsize) svga->decode_mask = memsize - 1; svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ break; + + default: + break; } mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); @@ -601,12 +643,14 @@ paradise_init(const device_t *info, uint32_t memsize) case WD90C11: svga->crtc[0x36] = '1'; svga->crtc[0x37] = '1'; - io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); break; case WD90C30: svga->crtc[0x36] = '3'; svga->crtc[0x37] = '0'; break; + + default: + break; } svga->bpp = 8; @@ -728,9 +772,9 @@ paradise_wd90c30_standalone_available(void) } void -paradise_close(void *p) +paradise_close(void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_close(¶dise->svga); @@ -738,17 +782,17 @@ paradise_close(void *p) } void -paradise_speed_changed(void *p) +paradise_speed_changed(void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; svga_recalctimings(¶dise->svga); } void -paradise_force_redraw(void *p) +paradise_force_redraw(void *priv) { - paradise_t *paradise = (paradise_t *) p; + paradise_t *paradise = (paradise_t *) priv; paradise->svga.fullchange = changeframecount; } diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index d68850befb..354c7e2651 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -414,7 +414,7 @@ hndl_clbeg(pgc_t *dev) } static void -hndl_clend(pgc_t *dev) +hndl_clend(UNUSED(pgc_t *dev)) { /* Should not happen outside a CLBEG. */ } @@ -682,7 +682,7 @@ pgc_write_pixel(pgc_t *dev, uint16_t x, uint16_t y, uint8_t ink) uint8_t pgc_read_pixel(pgc_t *dev, uint16_t x, uint16_t y) { - uint8_t *vram; + const uint8_t *vram; /* Suppress out-of-range reads. */ if (x >= dev->maxw || y >= dev->maxh) @@ -747,7 +747,7 @@ pgc_plot(pgc_t *dev, uint16_t x, uint16_t y) * Draw a line (using raster coordinates). * * Bresenham's Algorithm from: - * + * * * The line pattern mask to use is passed in. Return value is the * line pattern mask, rotated by the number of points drawn. @@ -1035,7 +1035,7 @@ hndl_poly(pgc_t *dev) /* Parse but don't execute a POLY command (for adding to a command list) */ static int -parse_poly(pgc_t *dev, pgc_cl_t *cl, int c) +parse_poly(pgc_t *dev, pgc_cl_t *cl, UNUSED(int c)) { uint8_t count; @@ -1384,11 +1384,11 @@ hndl_window(pgc_t *dev) * core commands (listed below) and subclass commands (listed in the clone). * * Each row has five parameters: - * ASCII-mode command - * Hex-mode command - * Function that executes this command - * Function that parses this command when building a command list - * Parameter for the parse function + * ASCII-mode command + * Hex-mode command + * Function that executes this command + * Function that parses this command when building a command list + * Parameter for the parse function * * TODO: This list omits numerous commands present in a genuine PGC * (ARC, AREA, AREABC, BUFFER, CIRCLE etc etc). @@ -1898,7 +1898,6 @@ pgc_param_coord(pgc_t *dev, int32_t *value) pgc_error(dev, PGC_ERROR_MISSING); return err_digit(dev); } - break; /* Scientific notation. */ case 'd': @@ -2197,6 +2196,9 @@ pgc_out(uint16_t addr, uint8_t val, void *priv) case 0x03d9: /* CRTC Color Select register */ dev->mapram[0x03d9] = val; break; + + default: + break; } } @@ -2204,8 +2206,8 @@ pgc_out(uint16_t addr, uint8_t val, void *priv) uint8_t pgc_in(uint16_t addr, void *priv) { - pgc_t *dev = (pgc_t *) priv; - uint8_t ret = 0xff; + const pgc_t *dev = (pgc_t *) priv; + uint8_t ret = 0xff; switch (addr) { case 0x03d0: /* CRTC Index register */ @@ -2234,6 +2236,9 @@ pgc_in(uint16_t addr, void *priv) case 0x03da: /* CRTC Status register */ ret = dev->mapram[0x03da]; break; + + default: + break; } pgc_log("PGC: in(%04x) = %02x\n", addr, ret); @@ -2297,6 +2302,9 @@ pgc_write(uint32_t addr, uint8_t val, void *priv) case 0x3ff: /* reboot the PGC */ pgc_wake(dev); break; + + default: + break; } } } @@ -2311,8 +2319,8 @@ pgc_write(uint32_t addr, uint8_t val, void *priv) uint8_t pgc_read(uint32_t addr, void *priv) { - pgc_t *dev = (pgc_t *) priv; - uint8_t ret = 0xff; + const pgc_t *dev = (pgc_t *) priv; + uint8_t ret = 0xff; if (addr >= 0xc6000 && addr < 0xc6800) { addr &= 0x7ff; @@ -2329,17 +2337,17 @@ pgc_read(uint32_t addr, void *priv) void pgc_cga_text(pgc_t *dev, int w) { - uint8_t chr; - uint8_t attr; - int drawcursor = 0; - uint32_t cols[2]; - int pitch = (dev->mapram[0x3e9] + 1) * 2; - uint16_t sc = (dev->displine & 0x0f) % pitch; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; - uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff; - uint8_t *addr; - uint32_t val; - int cw = (w == 80) ? 8 : 16; + uint8_t chr; + uint8_t attr; + int drawcursor = 0; + uint32_t cols[2]; + int pitch = (dev->mapram[0x3e9] + 1) * 2; + uint16_t sc = (dev->displine & 0x0f) % pitch; + uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff; + const uint8_t *addr; + uint32_t val; + int cw = (w == 80) ? 8 : 16; addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe]; ma += (dev->displine / pitch) * w; @@ -2385,11 +2393,11 @@ pgc_cga_text(pgc_t *dev, int w) void pgc_cga_gfx40(pgc_t *dev) { - uint32_t cols[4]; - int col; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; - uint8_t *addr; - uint16_t dat; + uint32_t cols[4]; + int col; + uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + const uint8_t *addr; + uint16_t dat; cols[0] = (dev->mapram[0x3d9] & 15) + 16; col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16; @@ -2428,10 +2436,10 @@ pgc_cga_gfx40(pgc_t *dev) void pgc_cga_gfx80(pgc_t *dev) { - uint32_t cols[2]; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; - uint8_t *addr; - uint16_t dat; + uint32_t cols[2]; + uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + const uint8_t *addr; + uint16_t dat; cols[0] = 16; cols[1] = (dev->mapram[0x3d9] & 15) + 16; @@ -2728,7 +2736,7 @@ pgc_standalone_init(const device_t *info) } const device_t pgc_device = { - .name = "PGC", + .name = "IBM PGC", .internal_name = "pgc", .flags = DEVICE_ISA, .local = 0, diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index f643fd1e4d..e82763d15b 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -29,7 +29,8 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" +#define RTG_3105_BIOS_ROM_PATH "roms/video/rtg/RTG3105I.VBI" +#define RTG_3106_BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" typedef struct { const char *name; @@ -86,18 +87,18 @@ rtg_in(uint16_t addr, void *priv) return svga->crtcreg; case 0x3d5: - if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18)) - return 0xff; if (svga->crtcreg == 0x1a) return dev->type << 6; if (svga->crtcreg == 0x1e) { + ret = svga->crtc[0x1e]; + ret &= ~3; if (dev->vram_size == 1024) ret = 2; else if (dev->vram_size == 512) ret = 1; else ret = 0; - return svga->crtc[0x1e] | ret; + return ret; } return svga->crtc[svga->crtcreg]; @@ -106,6 +107,9 @@ rtg_in(uint16_t addr, void *priv) case 0x3d7: return dev->bank3d7; + + default: + break; } return svga_in(addr, svga); @@ -140,6 +144,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) case 0x0f: rtg_recalcbanking(dev); return; + + default: + break; } } break; @@ -163,6 +170,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = changeframecount; svga_recalctimings(svga); break; + + default: + break; } } @@ -188,6 +198,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) dev->bank3d7 = val; rtg_recalcbanking(dev); return; + + default: + break; } svga_out(addr, val, svga); @@ -196,13 +209,12 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) static void rtg_recalctimings(svga_t *svga) { - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + const rtg_t *dev = (rtg_t *) svga->priv; + svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); svga->interlace = (svga->crtc[0x19] & 1); - svga->lowres = svga->attrregs[0x10] & 0x40; - /*Clock table not available, currently a guesswork*/ switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) { case 0: @@ -226,6 +238,9 @@ rtg_recalctimings(svga_t *svga) case 7: svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; break; + + default: + break; } switch (svga->gdcreg[0x0c] & 3) { @@ -238,49 +253,46 @@ rtg_recalctimings(svga_t *svga) case 3: svga->clock /= 4; break; - } - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else { - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= 8; + default: + break; + } - if (svga->hdisp == 1280) - svga->rowoffset >>= 1; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else { + if (svga->hdisp == 1280) + svga->rowoffset >>= 1; + + svga->render = svga_render_4bpp_highres; + } + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: + if (svga->crtc[0x19] & 2) { + if (svga->hdisp == 1280) + svga->hdisp >>= 1; + else if (dev->type == 2) + svga->rowoffset <<= 1; - svga->render = svga_render_4bpp_highres; - } - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - if (svga->crtc[0x19] & 2) { - if (svga->hdisp == 1280) { - svga->hdisp >>= 1; + svga->render = svga_render_8bpp_highres; } else - svga->rowoffset <<= 1; - - svga->render = svga_render_8bpp_highres; - } else { - if (svga->lowres) svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - } - break; + break; + + default: + break; + } } } } @@ -295,18 +307,32 @@ rtg_init(const device_t *info) memset(dev, 0x00, sizeof(rtg_t)); dev->name = info->name; dev->type = info->local; - fn = BIOS_ROM_PATH; + fn = NULL; switch (dev->type) { + case 1: /* ISA RTG3105 */ + fn = RTG_3105_BIOS_ROM_PATH; + dev->vram_size = device_get_config_int("memory"); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); + svga_init(info, &dev->svga, dev, dev->vram_size << 10, + rtg_recalctimings, rtg_in, rtg_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev); + break; case 2: /* ISA RTG3106 */ - dev->vram_size = device_get_config_int("memory") << 10; + fn = RTG_3106_BIOS_ROM_PATH; + dev->vram_size = device_get_config_int("memory"); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, + svga_init(info, &dev->svga, dev, dev->vram_size << 10, rtg_recalctimings, rtg_in, rtg_out, NULL, NULL); io_sethandler(0x03c0, 32, rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev); break; + + default: + break; } dev->svga.bpp = 8; @@ -314,7 +340,7 @@ rtg_init(const device_t *info) dev->vram_mask = dev->vram_size - 1; - rom_init(&dev->bios_rom, (char *) fn, + rom_init(&dev->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return dev; @@ -347,12 +373,45 @@ rtg_force_redraw(void *priv) } static int -rtg_available(void) +rtg3105_available(void) +{ + return rom_present(RTG_3105_BIOS_ROM_PATH); +} + +static int +rtg3106_available(void) { - return rom_present(BIOS_ROM_PATH); + return rom_present(RTG_3106_BIOS_ROM_PATH); } -static const device_config_t rtg_config[] = { +static const device_config_t rtg3105_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { + .description = "256 KB", + .value = 256 + }, + { + .description = "512 KB", + .value = 512 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } + // clang-format on +}; + +static const device_config_t rtg3106_config[] = { // clang-format off { .name = "memory", @@ -383,16 +442,30 @@ static const device_config_t rtg_config[] = { // clang-format on }; +const device_t realtek_rtg3105_device = { + .name = "Realtek RTG3105 (ISA)", + .internal_name = "rtg3105", + .flags = DEVICE_ISA, + .local = 1, + .init = rtg_init, + .close = rtg_close, + .reset = NULL, + { .available = rtg3105_available }, + .speed_changed = rtg_speed_changed, + .force_redraw = rtg_force_redraw, + .config = rtg3105_config +}; + const device_t realtek_rtg3106_device = { .name = "Realtek RTG3106 (ISA)", .internal_name = "rtg3106", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA, .local = 2, .init = rtg_init, .close = rtg_close, .reset = NULL, - { .available = rtg_available }, + { .available = rtg3106_available }, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, - .config = rtg_config + .config = rtg3106_config }; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 453972402b..c526ecf624 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -16,6 +16,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> @@ -61,7 +63,9 @@ #define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" +#define ROM_STB_POWERGRAPH_64_VIDEO "roms/video/s3/VBIOS.BIN" #define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" +#define ROM_CARDEX_TRIO64VPLUS "roms/video/s3/S3T64VP.VBI" #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" #define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" #define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" @@ -77,6 +81,7 @@ enum { S3_PARADISE_BAHAMAS64, S3_DIAMOND_STEALTH64_964, S3_PHOENIX_TRIO32, + S3_PHOENIX_TRIO32_ONBOARD, S3_PHOENIX_TRIO64, S3_PHOENIX_TRIO64_ONBOARD, S3_PHOENIX_VISION864, @@ -90,8 +95,10 @@ enum { S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, + S3_STB_POWERGRAPH_64_VIDEO, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, + S3_CARDEX_TRIO64VPLUS, S3_DIAMOND_STEALTH_SE, S3_DIAMOND_STEALTH_VRAM, S3_ELSAWIN2KPROX_964, @@ -146,6 +153,7 @@ static video_timings_t timing_s3_trio32_vlb = { .type = VIDEO_BUS, .write_b = static video_timings_t timing_s3_trio32_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 3, .write_l = 5, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_s3_trio64_vlb = { .type = VIDEO_BUS, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; static video_timings_t timing_s3_trio64_pci = { .type = VIDEO_PCI, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; +static video_timings_t timing_s3_trio64vp_cardex_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 19, .read_w = 19, .read_l = 30 }; enum { VRAM_4MB = 0, @@ -209,7 +217,9 @@ typedef struct s3_t { uint32_t linear_base, linear_size; uint8_t pci_regs[256]; - int card; + + uint8_t pci_slot; + uint8_t irq_state; uint32_t vram_mask; uint8_t data_available; @@ -221,14 +231,14 @@ typedef struct s3_t { uint16_t subsys_cntl; uint16_t setup_md; uint8_t advfunc_cntl; - uint16_t cur_y, cur_y2, cur_y_bitres; - uint16_t cur_x, cur_x2, cur_x_bitres; + uint16_t cur_y, cur_y2; + uint16_t cur_x, cur_x2; uint16_t x2, ropmix; uint16_t pat_x, pat_y; int16_t desty_axstp, desty_axstp2; int16_t destx_distp; - int16_t err_term, err_term2; int16_t maj_axis_pcnt, maj_axis_pcnt2; + int16_t err_term, err_term2; uint16_t cmd, cmd2; uint16_t short_stroke; uint32_t pat_bg_color, pat_fg_color; @@ -244,10 +254,10 @@ typedef struct s3_t { uint8_t pix_trans[4]; int ssv_state; - int cx, cy; - int px, py; - int sx, sy; - int dx, dy; + int16_t cx, cy; + int16_t px, py; + int16_t sx, sy; + int16_t dx, dy; uint32_t src, dest, pattern; int poly_cx, poly_cx2; @@ -260,10 +270,21 @@ typedef struct s3_t { uint32_t dat_buf; int dat_count; int b2e8_pix, temp_cnt; - uint8_t cur_x_bit12, cur_y_bit12; int ssv_len; uint8_t ssv_dir; uint8_t ssv_draw; + uint8_t dat_buf_16bit; + uint8_t frgd_color_actual[2]; + uint8_t bkgd_color_actual[2]; + uint8_t wrt_mask_actual[2]; + uint8_t rd_mask_actual[2]; + uint8_t *pix_trans_ptr; + int pix_trans_ptr_cnt; + int pix_trans_x_count; + int pix_trans_x_count2; + int color_16bit_check; + int color_16bit_check_rectfill; + uint16_t minus, srcminus; /*For non-threaded FIFO*/ int setup_fifo_slot; @@ -361,6 +382,8 @@ typedef struct s3_t { void *i2c, *ddc; int vram; + + void (*accel_start)(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); } s3_t; #define INT_VSY (1 << 0) @@ -376,24 +399,42 @@ typedef struct s3_t { static void s3_updatemapping(s3_t *s3); -static void s3_accel_write(uint32_t addr, uint8_t val, void *p); -static void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); -static void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); -static uint8_t s3_accel_read(uint32_t addr, void *p); -static uint16_t s3_accel_read_w(uint32_t addr, void *p); -static uint32_t s3_accel_read_l(uint32_t addr, void *p); - -static void s3_out(uint16_t addr, uint8_t val, void *p); -static uint8_t s3_in(uint16_t addr, void *p); - -static void s3_accel_out(uint16_t port, uint8_t val, void *p); -static void s3_accel_out_w(uint16_t port, uint16_t val, void *p); -static void s3_accel_out_l(uint16_t port, uint32_t val, void *p); -static uint8_t s3_accel_in(uint16_t port, void *p); -static uint16_t s3_accel_in_w(uint16_t port, void *p); -static uint32_t s3_accel_in_l(uint16_t port, void *p); -static uint8_t s3_pci_read(int func, int addr, void *p); -static void s3_pci_write(int func, int addr, uint8_t val, void *p); +static void s3_accel_write(uint32_t addr, uint8_t val, void *priv); +static void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv); +static void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv); +static uint8_t s3_accel_read(uint32_t addr, void *priv); +static uint16_t s3_accel_read_w(uint32_t addr, void *priv); +static uint32_t s3_accel_read_l(uint32_t addr, void *priv); + +static void s3_out(uint16_t addr, uint8_t val, void *priv); +static uint8_t s3_in(uint16_t addr, void *priv); + +static void s3_accel_out(uint16_t port, uint8_t val, void *priv); +static void s3_accel_out_w(uint16_t port, uint16_t val, void *priv); +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); + +#ifdef ENABLE_S3_LOG +int s3_do_log = ENABLE_S3_LOG; + +static void +s3_log(const char *fmt, ...) +{ + va_list ap; + + if (s3_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define s3_log(fmt, ...) +#endif /*Remap address for chain-4/doubleword style layout. These will stay for convenience.*/ @@ -465,13 +506,13 @@ s3_update_irqs(s3_t *s3) return; if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) { - pci_set_irq(s3->card, PCI_INTA); + pci_set_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); } else { - pci_clear_irq(s3->card, PCI_INTA); + pci_clear_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); } } -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); @@ -492,21 +533,21 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); } #define READ_PIXTRANS_BYTE_IO(n) \ - s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n)) & s3->vram_mask]; + s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n - s3->accel.minus)) & s3->vram_mask]; #define READ_PIXTRANS_BYTE_MM \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; #define READ_PIXTRANS_WORD \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ } else { \ - temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ + temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & (s3->vram_mask >> 1)]; \ } #define READ_PIXTRANS_LONG \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ @@ -549,7 +590,7 @@ s3_cpu_dest(s3_t *s3) static int s3_enable_fifo(s3_t *s3) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_TRIO64V) || (s3->chip == S3_TRIO64V2) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) return 1; /* FIFO always enabled on these chips. */ @@ -560,23 +601,36 @@ s3_enable_fifo(s3_t *s3) static void s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; if (s3->accel.cmd & 0x100) { + s3_log("S3 PIXTRANS_W write: cmd=%03x, pixelcntl=%02x, frgdmix=%02x, bkgdmix=%02x, " + "curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], + s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, val | (val << 16), 0, s3); + s3->accel_start(8, 1, val | (val << 16), 0, s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + s3_log("Word: CPU data CMD=%04x, byte write=%02x, " + "cnt=%d, check=%d.\n", s3->accel.cmd, val & 0xff, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + } + } + break; + } + s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x200: @@ -584,11 +638,54 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + s3->accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } else { - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " + "totalptrcnt=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, + s3->accel.pix_trans_ptr_cnt); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; + } + } else { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " + "totalptrcnt=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, + s3->accel.pix_trans_ptr_cnt); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val & 0xff; + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2 + 1] = val >> 8; + s3->accel.pix_trans_x_count += 2; + } + if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { + for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { + s3_log("Transferring write count=%d, bytes=%08x.\n", i, + s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8) | + (s3->accel.pix_trans_ptr[i + 2] << 16) | + (s3->accel.pix_trans_ptr[i + 3] << 24)); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + } + + s3->accel.pix_trans_x_count2 = 0; + s3->accel.color_16bit_check_rectfill = 0; + if (s3->accel.pix_trans_ptr != NULL) { + free(s3->accel.pix_trans_ptr); + s3->accel.pix_trans_ptr = NULL; + } + } + } + break; + } + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x400: @@ -597,21 +694,21 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(32, 1, val | (val << 16), 0, s3); + s3->accel_start(32, 1, val | (val << 16), 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + s3->accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x600: @@ -620,12 +717,15 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3->accel_start(8, 1, val & 0xff, 0, s3); } } } break; + + default: + break; } } } @@ -640,15 +740,15 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); + s3->accel_start(8, 1, val, 0, s3); + s3->accel_start(8, 1, val >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, val, s3); + s3->accel_start(1, 1, 0xffffffff, val >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, val, s3); + s3->accel_start(1, 1, 0xffffffff, val >> 16, s3); } break; case 0x200: @@ -656,15 +756,15 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); + s3->accel_start(16, 1, val, 0, s3); + s3->accel_start(16, 1, val >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, val, s3); + s3->accel_start(2, 1, 0xffffffff, val >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, val, s3); + s3->accel_start(2, 1, 0xffffffff, val >> 16, s3); } break; case 0x400: @@ -672,11 +772,11 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); + s3->accel_start(32, 1, val, 0, s3); } else - s3_accel_start(4, 1, 0xffffffff, val, s3); + s3->accel_start(4, 1, 0xffffffff, val, s3); } else - s3_accel_start(4, 1, 0xffffffff, val, s3); + s3->accel_start(4, 1, 0xffffffff, val, s3); break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { @@ -684,14 +784,17 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3->accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3->accel_start(8, 1, val & 0xff, 0, s3); } } } break; + + default: + break; } } } @@ -699,20 +802,17 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; switch (port) { case 0x8148: case 0x82e8: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x8149: case 0x82e9: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_y_bit12 = val & 0x10; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: @@ -728,16 +828,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8548: case 0x86e8: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x8549: case 0x86e9: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_x_bit12 = val & 0x10; s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; @@ -810,7 +907,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x92e9: s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3->accel.err_term |= ~0x3fff; + s3->accel.err_term |= ~0x1fff; break; case 0x914a: case 0x92ea: @@ -820,7 +917,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x92eb: s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3->accel.err_term2 |= ~0x3fff; + s3->accel.err_term2 |= ~0x1fff; break; case 0x9548: @@ -830,8 +927,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x9459: case 0x96e9: s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt |= ~0x0fff; break; case 0x954a: case 0x96ea: @@ -840,8 +935,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x954b: case 0x96eb: s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt2 |= ~0x0fff; break; case 0x9948: @@ -854,8 +947,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x9ae9: s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; - s3_accel_start(-1, 0, 0xffffffff, 0, s3); - s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ + s3->accel_start(-1, 0, 0xffffffff, 0, s3); break; case 0x994a: @@ -876,15 +968,8 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; - - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + 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(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -897,23 +982,28 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa148: case 0xa2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; break; case 0xa149: case 0xa2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); else s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.bkgd_color_actual[1] = s3->accel.bkgd_color & 0xff; + else + s3->accel.bkgd_color_actual[0] = s3->accel.bkgd_color & 0xff; break; case 0xa14a: case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { if (s3->accel.multifunc[0xe] & 0x10) @@ -937,19 +1027,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa548: case 0xa6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; break; case 0xa549: case 0xa6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); else s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.frgd_color_actual[1] = s3->accel.frgd_color & 0xff; + else + s3->accel.frgd_color_actual[0] = s3->accel.frgd_color & 0xff; break; case 0xa54a: case 0xa6ea: @@ -977,19 +1072,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa948: case 0xaae8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; break; case 0xa949: case 0xaae9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); else s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + + if (s3->accel.color_16bit_check) + s3->accel.wrt_mask_actual[1] = s3->accel.wrt_mask & 0xff; + else + s3->accel.wrt_mask_actual[0] = s3->accel.wrt_mask & 0xff; break; case 0xa94a: case 0xaaea: @@ -1017,14 +1117,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xad48: case 0xaee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; break; case 0xad49: case 0xaee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); else s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); @@ -1057,14 +1157,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb148: case 0xb2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; break; case 0xb149: case 0xb2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); else s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); @@ -1125,14 +1225,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe548: case 0xe6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; break; case 0xe549: case 0xe6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); @@ -1180,14 +1280,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed48: case 0xeee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; break; case 0xed49: case 0xeee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); @@ -1229,16 +1329,55 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { + s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " + "check=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val; + s3->accel.pix_trans_x_count++; + s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; + } + } else { + if (s3->accel.pix_trans_x_count2 < s3->accel.pix_trans_ptr_cnt) { + s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " + "check=%d.\n", s3->accel.cmd, val, + s3->accel.pix_trans_x_count2, s3->accel.color_16bit_check); + s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val; + s3->accel.pix_trans_x_count2++; + } + s3_log("WriteCNT=%d, TotalCNT=%d.\n", s3->accel.pix_trans_x_count2, + s3->accel.pix_trans_ptr_cnt); + if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { + for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { + s3_log("Transferring write count=%d, bytes=%04x.\n", i, + s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8)); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | + (s3->accel.pix_trans_ptr[i + 1] << 8), s3); + } + + s3->accel.pix_trans_x_count2 = 0; + s3->accel.color_16bit_check_rectfill = 0; + if (s3->accel.pix_trans_ptr != NULL) { + free(s3->accel.pix_trans_ptr); + s3->accel.pix_trans_ptr = NULL; + } + } + } + break; + } + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } break; + + default: + break; } } break; @@ -1249,68 +1388,76 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[1] = val; if (s3->accel.cmd & 0x100) { + s3_log("S3 PIXTRANS_B write (E2E9): cmd=%03x, pixelcntl=%02x, frgdmix=%02x, " + "bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], + s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3->accel_start(8, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); + } else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: - /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928 ISA/VLB*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); } break; case 0x400: if (svga->crtc[0x53] & 0x08) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } } } break; + + default: + break; } + } break; case 0xe14a: @@ -1329,65 +1476,62 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x200: - /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928 ISA/VLB card*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } break; case 0x400: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } } } break; + + default: + break; } } break; + + default: + break; } } @@ -1405,15 +1549,8 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; - - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + 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(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1428,11 +1565,10 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port == 0xb2e8 || port == 0xb148) { + if (port == 0xb2e8 || port == 0xb148) s3->accel.b2e8_pix = 1; - } else { + else s3->accel.b2e8_pix = 0; - } s3_accel_out_pixtrans_l(s3, val); } @@ -1440,7 +1576,7 @@ s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; if (s3->packed_mmio) { int addr_lo = addr & 1; @@ -1591,6 +1727,9 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) case 0x816e: WRITE8(addr, s3->accel.pat_fg_color, val); return; + + default: + break; } addr |= addr_lo; } @@ -1600,11 +1739,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if (s3->accel.cmd & 0x100) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } else { switch (addr & 0x1ffff) { @@ -1681,7 +1820,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } } else { if (addr & 0x8000) { - if ((addr == 0xe2e8) || (addr == 0xe2e9)) { + if ((addr == 0xe2e8) || (addr == 0xe2e9) || (addr == 0xe2ea) || (addr == 0xe2eb)) { if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) goto mmio_byte_write; else @@ -1694,19 +1833,19 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + s3->accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } } @@ -1716,15 +1855,15 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; if (svga->crtc[0x53] & 0x08) { if ((addr & 0x1fffe) < 0x8000) { s3_accel_out_pixtrans_w(s3, val); } else { switch (addr & 0x1fffe) { - case 0x83d4: default: + case 0x83d4: s3_accel_write_fifo(s3, addr, val); s3_accel_write_fifo(s3, addr + 1, val >> 8); break; @@ -1957,7 +2096,7 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) } else { if (addr & 0x8000) { if (addr == 0xe2e8) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + if ((s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) s3_accel_out_pixtrans_l(s3, val); else { s3_accel_write_fifo(s3, addr, val); @@ -1980,7 +2119,7 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) static void s3_vblank_start(svga_t *svga) { - s3_t *s3 = (s3_t *) svga->p; + s3_t *s3 = (s3_t *) svga->priv; s3->subsys_stat |= INT_VSY; s3_update_irqs(s3); @@ -2003,16 +2142,16 @@ s3_hwcursor_convert_addr(svga_t *svga) static void s3_hwcursor_draw(svga_t *svga, int displine) { - s3_t *s3 = (s3_t *) svga->p; - int shift = 1; - int width = 16; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg; - uint32_t bg; - uint32_t real_addr; - uint32_t remapped_addr; + const s3_t *s3 = (s3_t *) svga->priv; + int shift = 1; + int width = 16; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg; + uint32_t bg; + uint32_t real_addr; + uint32_t remapped_addr; switch (svga->bpp) { case 15: @@ -2032,7 +2171,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) fg = video_16to32[s3->hwc_fg_col & 0xffff]; bg = video_16to32[s3->hwc_bg_col & 0xffff]; if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { - if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805)) { if (!(svga->crtc[0x45] & 0x04)) { shift = 2; width = 8; @@ -2046,8 +2185,13 @@ s3_hwcursor_draw(svga_t *svga, int displine) break; case 24: - fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; + if (s3->chip <= S3_86C805) { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } else { + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + } break; case 32: @@ -2332,17 +2476,17 @@ s3_hwcursor_draw(svga_t *svga, int displine) static void s3_trio64v_overlay_draw(svga_t *svga, int displine) { - s3_t *s3 = (s3_t *) svga->p; - int offset = (s3->streams.sec_x - s3->streams.pri_x) + 1; - int h_acc = s3->streams.dda_horiz_accumulator; - int r[8]; - int g[8]; - int b[8]; - int x_size; - int x_read = 4; - int x_write = 4; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + const s3_t *s3 = (s3_t *) svga->priv; + int offset = (s3->streams.sec_x - s3->streams.pri_x) + 1; + int h_acc = s3->streams.dda_horiz_accumulator; + int r[8]; + int g[8]; + int b[8]; + int x_size; + int x_read = 4; + int x_write = 4; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; p = &(buffer32->line[displine][offset + svga->x_add]); @@ -2449,7 +2593,7 @@ s3_io_remove(s3_t *s3) static void s3_io_set_alt(s3_t *s3) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; if (!s3->translate) return; @@ -2504,7 +2648,7 @@ s3_io_set_alt(s3_t *s3) static void s3_io_set(s3_t *s3) { - svga_t *svga = &s3->svga; + const svga_t *svga = &s3->svga; s3_io_remove(s3); @@ -2562,12 +2706,11 @@ s3_io_set(s3_t *s3) } static void -s3_out(uint16_t addr, uint8_t val, void *p) +s3_out(uint16_t addr, uint8_t val, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; uint8_t old; - uint8_t mask; int rs2; int rs3; @@ -2592,6 +2735,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x13: svga_recalctimings(svga); return; + + default: + break; } } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ @@ -2624,26 +2770,21 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x3C7: case 0x3C8: case 0x3C9: - if ((svga->crtc[0x55] & 0x03) == 0x00) - rs2 = !!(svga->crtc[0x43] & 0x02); - else - rs2 = (svga->crtc[0x55] & 0x01); + rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) svga_out(addr, val, svga); else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) - rs3 = !!(svga->crtc[0x55] & 0x02); - else - rs3 = 0; + rs3 = !!(svga->crtc[0x55] & 0x02); bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C924)) && + ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) { + else if (s3->chip == S3_86C911) { sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); } else if (s3->card_type == S3_NUMBER9_9FX_531) att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); @@ -2671,6 +2812,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) return; if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) return; + old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -2679,42 +2821,17 @@ s3_out(uint16_t addr, uint8_t val, void *p) s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); svga->force_dword_mode = !!(val & 0x08); break; - case 0x32: - if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) - svga->vram_display_mask = 0x3ffff; - else - svga->vram_display_mask = s3->vram_mask; - break; case 0x40: s3->enable_8514 = (val & 0x01); break; case 0x50: - mask = 0xc0; - if (s3->chip != S3_86C801) - mask |= 0x01; - switch (svga->crtc[0x50] & mask) { - case 0x00: - s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; - break; - case 0x01: - s3->width = 1152; - break; - case 0x40: - s3->width = 640; - break; - case 0x80: - s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; - break; - case 0x81: - s3->width = 1600; - break; - case 0xc0: - s3->width = 1280; - break; - } s3->bpp = (svga->crtc[0x50] >> 4) & 3; + if (s3->bpp == 3) { + if (!(s3->accel.multifunc[0xe] & 0x200)) /*On True Color mode change, reset bit 4 of Misc Index register*/ + s3->accel.multifunc[0xe] &= ~0x10; + } break; case 0x5c: @@ -2797,6 +2914,8 @@ s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.x >>= 1; } else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) svga->hwcursor.x /= 3; + else if ((s3->chip <= S3_86C805) && s3->color_16bit) + svga->hwcursor.x >>= 1; break; case 0x4a: @@ -2810,6 +2929,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 2: s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); break; + + default: + break; } s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; break; @@ -2824,6 +2946,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 2: s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); break; + + default: + break; } s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; break; @@ -2837,7 +2962,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x55: if (s3->chip == S3_86C928) { - if ((val & 0x08) || ((val & 0x20) == 0x20)) { + if (val & 0x28) { svga->hwcursor_draw = NULL; svga->dac_hwcursor_draw = bt48x_hwcursor_draw; } else { @@ -2856,6 +2981,21 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x43: if (s3->chip < S3_VISION964) { + if (s3->chip <= S3_86C805) { + s3->color_16bit = !!(val & 8); + if (s3->color_16bit) { + s3->width = 1024; + } else { + if (s3->chip <= S3_86C924) + s3->width = 1024; + else { + if (s3->accel.advfunc_cntl & 4) + s3->width = 1024; + else + s3->width = 640; + } + } + } s3_io_remove_alt(s3); s3->translate = !!(val & 0x10); s3_io_set_alt(s3); @@ -2888,6 +3028,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -2903,14 +3046,17 @@ s3_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -s3_in(uint16_t addr, void *p) +s3_in(uint16_t addr, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; int rs2; int rs3; @@ -2935,7 +3081,9 @@ s3_in(uint16_t addr, void *p) temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ - if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) + if (((s3->card_type == S3_STB_POWERGRAPH_64_VIDEO) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || + (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; } @@ -2949,16 +3097,21 @@ s3_in(uint16_t addr, void *p) if (s3->chip >= S3_TRIO32) return svga_in(addr, svga); else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + if (s3->chip == S3_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + else + rs3 = !!(svga->crtc[0x55] & 0x02); + temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + return temp; } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { + else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C924)) && + ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) + else if (s3->chip == S3_86C911) return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->card_type == S3_NUMBER9_9FX_531) return att498_ramdac_in(addr, rs2, svga->ramdac, svga); @@ -2966,7 +3119,6 @@ s3_in(uint16_t addr, void *p) return sc1502x_ramdac_in(addr, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; case 0x3d4: return svga->crtcreg; @@ -2976,8 +3128,15 @@ s3_in(uint16_t addr, void *p) return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ + case 0x2f: switch (s3->chip) { /*Revision level*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } + break; case 0x30: return s3->id; /*Chip ID*/ case 0x31: @@ -2986,7 +3145,7 @@ s3_in(uint16_t addr, void *p) return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x45: s3->hwc_col_stack_pos = 0; - break; + return svga->crtc[0x45]; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x5c: /* General Output Port Register */ @@ -3027,8 +3186,14 @@ s3_in(uint16_t addr, void *p) } else return svga->crtc[0x6c]; break; + + default: + break; } return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); } @@ -3036,26 +3201,30 @@ s3_in(uint16_t addr, void *p) static void s3_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *) svga->p; + s3_t *s3 = (s3_t *) svga->priv; int clk_sel = (svga->miscout >> 2) & 3; + uint8_t mask = 0xc0; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - } + if (svga->crtc[0x33] & 0x20) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } else { + if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } } + svga->hdisp = svga->hdisp_old; svga->ma_latch |= (s3->ma_ext << 16); - if (s3->chip >= S3_86C928) { - svga->hdisp = svga->hdisp_old; + if (s3->chip >= S3_86C928) { if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp |= (0x100 * svga->dots_per_clock); } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3063,6 +3232,8 @@ s3_recalctimings(svga_t *svga) svga->dispend |= 0x400; if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; + else + svga->vblankstart = svga->dispend; if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; if (svga->crtc[0x5e] & 0x40) @@ -3073,24 +3244,27 @@ s3_recalctimings(svga_t *svga) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; - } + } else if (svga->crtc[0x43] & 0x04) + svga->rowoffset |= 0x100; if (!svga->rowoffset) - svga->rowoffset = 256; + svga->rowoffset = 0x100; if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { if (s3->card_type == S3_ELSAWIN2KPROX_964) ibm_rgb528_recalctimings(svga->ramdac, svga); - else + else { bt48x_recalctimings(svga->ramdac, svga); + svga->interlace |= (!!(svga->crtc[0x42] & 0x20)); + } } else if (s3->chip == S3_VISION968) { - if (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968) + if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) tvp3026_recalctimings(svga->ramdac, svga); else ibm_rgb528_recalctimings(svga->ramdac, svga); } else svga->interlace = !!(svga->crtc[0x42] & 0x20); - if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) + if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip < S3_TRIO32)) clk_sel = svga->crtc[0x42] & 0x0f; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); @@ -3101,15 +3275,76 @@ s3_recalctimings(svga_t *svga) case 7: svga->clock /= 2; break; + + default: + break; + } + + svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); + + if (s3->chip != S3_86C801) + mask |= 0x01; + switch (svga->crtc[0x50] & mask) { + case 0x00: + if (s3->color_16bit) + s3->width = 1024; + else + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + + default: + break; } - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if (svga->crtc[0x33] & 0x20) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3) + 1*/; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + + if (s3->chip >= S3_VISION964) + svga->hblank_end_mask = 0x7f; + } else if (s3->chip >= S3_86C801) { + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; + + if (s3->chip >= S3_VISION964) { + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; + } + } +#ifdef OLD_CODE_REFERENCE if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { if (!(svga->crtc[0x5e] & 0x04)) svga->vblankstart = svga->dispend; if (svga->bpp != 32) { - if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ + if (svga->crtc[0x31] & 2) s3->width = 2048; else { if (s3->card_type == S3_MIROCRYSTAL10SD_805) { @@ -3120,7 +3355,7 @@ s3_recalctimings(svga_t *svga) } } else { if (s3->card_type == S3_NUMBER9_9FX_531) { - if (svga->hdisp == 1600 && s3->width == 1600) + if ((svga->hdisp == 1600) && (s3->width == 1600)) s3->width = 800; } } @@ -3130,24 +3365,117 @@ s3_recalctimings(svga_t *svga) s3->width = 1024; } } - - if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) { - s3->color_16bit = 1; - s3->width = 1024; - } else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) { - s3->color_16bit = 0; - if (s3->chip <= S3_86C924) { - if (s3->accel.advfunc_cntl & 4) - s3->width = 1024; - else - s3->width = 640; - } - } - - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { +#endif + + if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { + svga->vram_display_mask = s3->vram_mask; + s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " + "attr=%02x.\n", svga->bpp, s3->width, svga->crtc[0x50], + svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, + svga->attrregs[0x10] & 0x40); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; + switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + switch (s3->width) { + case 1280: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + case 2048: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + default: + break; + } + break; + + default: + break; + } + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if (s3->chip != S3_VISION868) { if (s3->chip == S3_86C928) { if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) { @@ -3165,54 +3493,179 @@ s3_recalctimings(svga_t *svga) } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; + } } else if (s3->card_type == S3_NUMBER9_9FX_771) svga->hdisp <<= 1; + } +#endif + break; + case 15: + svga->render = svga_render_15bpp_highres; + switch (s3->chip) { + case S3_86C911: + case S3_86C924: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp != 1408) - svga->hdisp = s3->width; - if (s3->card_type == S3_MIROCRYSTAL20SD_864) { - if (s3->width == 2048 || s3->width == 1600 || s3->width == 800) { - switch (svga->dispend) { - case 400: - case 480: - svga->hdisp = 640; - break; - - case 576: - svga->hdisp = 768; - break; - - case 600: - if (s3->width == 1600) - s3->width = 800; - svga->hdisp = 800; - break; + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; - case 768: - svga->hdisp = 1024; + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_86C805_ONBOARD: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + case S3_SPEA_MIRAGE_86C805: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + switch (s3->width) { + case 800: + case 1024: + if (svga->hdisp == 400) { + /*SPEA specific drivers + its VBE RAM BIOS...*/ + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: break; + } + break; - case 864: - svga->hdisp = 1152; + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + if (!s3->color_16bit) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + switch (svga->hdisp) { /*This might be a driver issue*/ + case 800: + s3->width = 1024; + break; + case 1280: + s3->width = 2048; break; + default: + break; + } + break; - case 1024: - if (svga->vtotal == 1066) - svga->hdisp = 1280; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + default: break; } - } + break; + + default: + break; } - } - if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL8S_805) { - if (svga->rowoffset == 256 && (((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04)))) - svga->rowoffset >>= 1; - } + break; + case S3_VISION864: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + /* TODO: Is this still needed? */ + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + default: + break; } - break; - case 15: - svga->render = svga_render_15bpp_highres; +#ifdef OLD_CODE_REFERENCE if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) svga->hdisp <<= 1; @@ -3234,9 +3687,173 @@ s3_recalctimings(svga_t *svga) if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; +#endif break; case 16: svga->render = svga_render_16bpp_highres; + switch (s3->chip) { + case S3_86C911: + case S3_86C924: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_86C805_ONBOARD: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + case S3_SPEA_MIRAGE_86C805: + svga->hdisp >>= 1; + switch (s3->width) { + case 800: + case 1024: + if (svga->hdisp == 400) { + /*SPEA specific drivers + its VBE RAM BIOS...*/ + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + switch (svga->hdisp) { /*This might be a driver issue*/ + case 800: + s3->width = 1024; + break; + case 1280: + s3->width = 2048; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + switch (s3->width) { + case 640: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION864: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + /* TODO: Is this still needed? */ + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + + default: + break; + } + +#ifdef OLD_CODE_REFERENCE if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp <<= 1; @@ -3255,7 +3872,7 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; } if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp == (1408 * 2)) + if (svga->hdisp == (1408 << 1)) svga->hdisp >>= 1; else svga->hdisp = s3->width; @@ -3263,9 +3880,74 @@ s3_recalctimings(svga_t *svga) if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; +#endif break; case 24: svga->render = svga_render_24bpp_highres; + switch (s3->chip) { + case S3_86C924: + switch (s3->card_type) { + case S3_AMI_86C924: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + /* TODO: Is this still needed? */ + if (svga->hdisp == 645) + svga->hdisp -= 5; + break; + default: + break; + } + break; + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + case S3_SPEA_MIRAGE_86C801: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + break; + default: + break; + } + break; + case S3_86C805: + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + case S3_PHOENIX_86C805: + case S3_SPEA_MIRAGE_86C805: + case S3_86C805_ONBOARD: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + break; + default: + break; + } + break; + case S3_VISION864: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp /= 3; + svga->dots_per_clock /= 3; + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if (s3->chip != S3_VISION968) { if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805) svga->hdisp /= 3; @@ -3273,20 +3955,105 @@ s3_recalctimings(svga_t *svga) svga->hdisp = (svga->hdisp * 2) / 3; if (s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { - if (s3->width == 2048) + if (s3->width == 2048) { switch (svga->dispend) { case 480: svga->hdisp = 640; break; + + default: + break; } + } + } else if (s3->chip == S3_86C924) { + if (svga->dispend == 480) + svga->hdisp = 640; } } else { - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) + if ((s3->card_type == S3_MIROVIDEO40SV_ERGO_968) || + (s3->card_type == S3_PHOENIX_VISION968) || (s3->card_type == S3_SPEA_MERCURY_P64V)) svga->hdisp = s3->width; } +#endif break; case 32: svga->render = svga_render_32bpp_highres; + switch (s3->chip) { + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SV_964: + switch (s3->width) { + case 800: + case 1024: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; + default: + break; + } + break; + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + case S3_SPEA_MERCURY_P64V: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + /* TODO: Is this still needed? */ + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + default: + break; + } +#ifdef OLD_CODE_REFERENCE if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { if (s3->chip == S3_VISION868) svga->hdisp >>= 1; @@ -3320,48 +4087,64 @@ s3_recalctimings(svga_t *svga) s3->width = 800; svga->hdisp = 800; break; + + default: + break; } } } } +#endif + break; + + default: break; } } else { - if (!svga->scrblank && svga->attr_palette_enable) { + svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { + if (svga->crtc[0x31] & 0x08) { + svga->vram_display_mask = s3->vram_mask; if (svga->bpp == 8) { - svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ - if (svga->hdisp <= 1024) - s3->width = 1024; + /*Enhanced 4bpp mode, just like the 8bpp mode per the spec. */ + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; } } - } else { - if (s3->chip <= S3_86C924) - s3->width = 1024; } } } + + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64)) + svga->hoverride = 1; + else + svga->hoverride = 0; } static void s3_trio64v_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *) svga->p; - int clk_sel = (svga->miscout >> 2) & 3; + s3_t *s3 = (s3_t *) svga->priv; + int clk_sel = (svga->miscout >> 2) & 3; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - } + if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } + + if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp |= 0x100 * svga->dots_per_clock; } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3377,6 +4160,53 @@ s3_trio64v_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); + switch (svga->crtc[0x50] & 0xc1) { + case 0x00: + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = (s3->accel.advfunc_cntl & 4) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + + default: + break; + } + + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } else { + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; + + /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? + The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, + and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868, + and Vision968. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; + } + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (s3->ma_ext << 16); @@ -3387,9 +4217,10 @@ s3_trio64v_recalctimings(svga_t *svga) if (!svga->rowoffset) svga->rowoffset = 256; - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { + svga->vram_display_mask = s3->vram_mask; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3397,20 +4228,28 @@ s3_trio64v_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; break; case 16: svga->render = svga_render_16bpp_highres; svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; break; case 24: svga->render = svga_render_24bpp_highres; svga->hdisp /= 3; + svga->dots_per_clock /= 3; break; case 32: svga->render = svga_render_32bpp_highres; break; + + default: + break; } - } + } else + svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; + } else /*Streams mode*/ { if (s3->streams.buffer_ctrl & 1) @@ -3435,16 +4274,17 @@ s3_trio64v_recalctimings(svga_t *svga) svga->overlay.v_acc = s3->streams.dda_vert_accumulator; svga->rowoffset = s3->streams.pri_stride >> 3; + svga->vram_display_mask = s3->vram_mask; switch ((s3->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ @@ -3453,8 +4293,13 @@ s3_trio64v_recalctimings(svga_t *svga) case 7: /*XRGB-32 (X.8.8.8)*/ svga->render = svga_render_32bpp_highres; break; + + default: + break; } } + + svga->hoverride = 1; } static void @@ -3477,8 +4322,7 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } else - switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ - { + switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -3495,6 +4339,9 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } if (s3->chip >= S3_86C928) { @@ -3535,6 +4382,9 @@ s3_updatemapping(s3_t *s3) break; } break; + + default: + break; } s3->linear_base &= ~(s3->linear_size - 1); if (s3->linear_base == 0xa0000) { @@ -3544,11 +4394,10 @@ s3_updatemapping(s3_t *s3) svga->banked_mask = 0xffff; } } else { - if (s3->chip >= S3_TRIO64V) { + if (s3->chip >= S3_TRIO64V) s3->linear_base &= 0xfc000000; - } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) s3->linear_base &= 0xfe000000; - } mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } @@ -3581,14 +4430,15 @@ s3_updatemapping(s3_t *s3) } static float -s3_trio64_getclock(int clock, void *p) +s3_trio64_getclock(int clock, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; - float t; - int m; - int n1; - int n2; + const s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; + float t; + int m; + int n1; + int n2; + if (clock == 0) return 25175000.0; if (clock == 1) @@ -3601,9 +4451,9 @@ s3_trio64_getclock(int clock, void *p) } static void -s3_accel_out(uint16_t port, uint8_t val, void *p) +s3_accel_out(uint16_t port, uint8_t val, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; if (port >= 0x8000) { @@ -3641,17 +4491,19 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } - if (s3->chip > S3_86C924) - s3_updatemapping(s3); + s3_updatemapping(s3); + break; + + default: break; } } } static void -s3_accel_out_w(uint16_t port, uint16_t val, void *p) +s3_accel_out_w(uint16_t port, uint16_t val, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; if (!s3->enable_8514) return; @@ -3663,9 +4515,9 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *p) } static void -s3_accel_out_l(uint16_t port, uint32_t val, void *p) +s3_accel_out_l(uint16_t port, uint32_t val, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; if (!s3->enable_8514) return; @@ -3677,11 +4529,12 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *p) } static uint8_t -s3_accel_in(uint16_t port, void *p) +s3_accel_in(uint16_t port, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; int temp; + uint8_t temp2; if (!s3->enable_8514) return 0xff; @@ -3799,6 +4652,7 @@ s3_accel_in(uint16_t port, void *p) temp |= 0x02; /*Hardware busy*/ else temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; if (s3->chip >= S3_VISION964) { @@ -3811,9 +4665,30 @@ s3_accel_in(uint16_t port, void *p) s3->data_available = 0; } } else { - if (s3->force_busy) { + 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!*/ + case 0: + if (!s3->accel.ssv_len) + temp |= 0x04; + break; + case 1: + if (!s3->accel.sy) + temp |= 0x04; + break; + case 2: + case 6: + case 7: + if (s3->accel.sy < 0) + temp |= 0x04; + break; + + default: + break; + } } + s3->force_busy = 0; if (s3->data_available) { temp |= 0x01; /*Read Data available*/ @@ -3844,7 +4719,12 @@ s3_accel_in(uint16_t port, void *p) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 16; + else + temp2 = s3->accel.bkgd_color & 0xff; + + return temp2; } break; case 0xa149: @@ -3852,26 +4732,49 @@ s3_accel_in(uint16_t port, void *p) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 24; + else + temp2 = s3->accel.bkgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa14a: case 0xa2ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color & 0xff; + else + temp2 = s3->accel.bkgd_color >> 16; + + return temp2; case 0xa14b: case 0xa2eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 8; + else + temp2 = s3->accel.bkgd_color >> 24; + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xa548: case 0xa6e8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 16; + else + temp2 = s3->accel.frgd_color & 0xff; + + return temp2; } break; case 0xa549: @@ -3879,26 +4782,50 @@ s3_accel_in(uint16_t port, void *p) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 24; + else + temp2 = s3->accel.frgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa54a: case 0xa6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color & 0xff; + else + temp2 = s3->accel.frgd_color >> 16; + + return temp2; case 0xa54b: case 0xa6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 8; + else + temp2 = s3->accel.frgd_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xa948: case 0xaae8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 16; + else + temp2 = s3->accel.wrt_mask & 0xff; + + return temp2; } break; case 0xa949: @@ -3906,50 +4833,101 @@ s3_accel_in(uint16_t port, void *p) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 24; + else + temp2 = s3->accel.wrt_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa94a: case 0xaaea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask & 0xff; + else + temp2 = s3->accel.wrt_mask >> 16; + + return temp2; case 0xa94b: case 0xaaeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 8; + else + temp2 = s3->accel.wrt_mask >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xad48: case 0xaee8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 16; + else + temp2 = s3->accel.rd_mask & 0xff; + + return temp2; } break; case 0xad49: case 0xaee9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 8; + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 24; + else + temp2 = s3->accel.rd_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; + } + break; case 0xad4a: case 0xaeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask & 0xff; + else + temp2 = s3->accel.rd_mask >> 16; + + return temp2; case 0xad4b: case 0xaeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 8; + else + temp2 = s3->accel.rd_mask >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xb148: case 0xb2e8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 16; + else + temp2 = s3->accel.color_cmp & 0xff; + + return temp2; } break; case 0xb149: @@ -3957,19 +4935,38 @@ s3_accel_in(uint16_t port, void *p) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 24; + else + temp2 = s3->accel.color_cmp >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xb14a: case 0xb2ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp & 0xff; + else + temp2 = s3->accel.color_cmp >> 16; + + return temp2; case 0xb14b: case 0xb2eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 8; + else + temp2 = s3->accel.color_cmp >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xb548: case 0xb6e8: @@ -4018,6 +5015,9 @@ s3_accel_in(uint16_t port, void *p) return s3->accel.setup_md & 0xff; case 0xa: return s3->accel.multifunc[0xd] & 0xff; + + default: + break; } return 0xff; } @@ -4052,6 +5052,9 @@ s3_accel_in(uint16_t port, void *p) return (s3->accel.setup_md >> 8) & ~0xf000; case 0xa: return s3->accel.multifunc[0xd] >> 8; + + default: + break; } return 0xff; } @@ -4073,25 +5076,49 @@ s3_accel_in(uint16_t port, void *p) case 0xe6e8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 16; + else + temp2 = s3->accel.pat_bg_color & 0xff; + + return temp2; case 0xe549: case 0xe6e9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 24; + else + temp2 = s3->accel.pat_bg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe54a: case 0xe6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color & 0xff; + else + temp2 = s3->accel.pat_bg_color >> 16; + + return temp2; case 0xe54b: case 0xe6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 8; + else + temp2 = s3->accel.pat_bg_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe948: case 0xeae8: @@ -4121,25 +5148,49 @@ s3_accel_in(uint16_t port, void *p) case 0xeee8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 16; + else + temp2 = s3->accel.pat_fg_color & 0xff; + + return temp2; case 0xed49: case 0xeee9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 24; + else + temp2 = s3->accel.pat_fg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xed4a: case 0xeeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color & 0xff; + else + temp2 = s3->accel.pat_fg_color >> 16; + + return temp2; case 0xed4b: case 0xeeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 8; + else + temp2 = s3->accel.pat_fg_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe148: case 0xe2e8: @@ -4151,21 +5202,23 @@ s3_accel_in(uint16_t port, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else { - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + break; + + default: break; } } @@ -4181,32 +5234,35 @@ s3_accel_in(uint16_t port, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } } else { if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } break; + + default: + break; } } return s3->accel.pix_trans[1]; @@ -4228,20 +5284,23 @@ s3_accel_in(uint16_t port, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + s3->accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + break; + + default: break; } } @@ -4255,18 +5314,21 @@ s3_accel_in(uint16_t port, void *p) if ((s3->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(s3->i2c)) temp |= SERIAL_PORT_SDR; return temp; + + default: + break; } return 0xff; } static uint16_t -s3_accel_in_w(uint16_t port, void *p) +s3_accel_in_w(uint16_t port, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; - uint16_t temp = 0x0000; - uint16_t *vram_w = (uint16_t *) svga->vram; + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + uint16_t temp = 0x0000; + const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) return 0xffff; @@ -4281,30 +5343,27 @@ s3_accel_in_w(uint16_t port, void *p) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } else { - if (s3->color_16bit) { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } + s3->accel_start(8, 1, temp | (temp << 16), 0, s3); + } else + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + s3->accel_start(16, 1, temp | (temp << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } break; + + default: + break; } } } else { @@ -4317,12 +5376,12 @@ s3_accel_in_w(uint16_t port, void *p) } static uint32_t -s3_accel_in_l(uint16_t port, void *p) +s3_accel_in_l(UNUSED(uint16_t port), void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; - uint32_t temp = 0x00000000; - uint16_t *vram_w = (uint16_t *) svga->vram; + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + uint32_t temp = 0x00000000; + const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) return 0xffffffff; @@ -4336,15 +5395,15 @@ s3_accel_in_l(uint16_t port, void *p) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); + s3->accel_start(8, 1, temp, 0, s3); + s3->accel_start(8, 1, temp >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } break; case 0x200: @@ -4352,17 +5411,20 @@ s3_accel_in_l(uint16_t port, void *p) if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); + s3->accel_start(16, 1, temp, 0, s3); + s3->accel_start(16, 1, temp >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } break; + + default: + break; } } @@ -4370,10 +5432,10 @@ s3_accel_in_l(uint16_t port, void *p) } static void -s3_accel_write(uint32_t addr, uint8_t val, void *p) +s3_accel_write(uint32_t addr, uint8_t val, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4388,10 +5450,10 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p) } static void -s3_accel_write_w(uint32_t addr, uint16_t val, void *p) +s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4406,10 +5468,10 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p) } static void -s3_accel_write_l(uint32_t addr, uint32_t val, void *p) +s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4424,9 +5486,9 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p) } static uint8_t -s3_accel_read(uint32_t addr, void *p) +s3_accel_read(uint32_t addr, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; uint8_t temp = 0x00; @@ -4491,12 +5553,12 @@ s3_accel_read(uint32_t addr, void *p) case 0x8505: return s3->subsys_cntl; default: - return s3_accel_in(addr & 0xffff, p); + return s3_accel_in(addr & 0xffff, priv); } return 0xff; } else { if (addr & 0x8000) { - temp = s3_accel_in(addr & 0xffff, p); + temp = s3_accel_in(addr & 0xffff, priv); } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_BYTE_MM @@ -4504,20 +5566,23 @@ s3_accel_read(uint32_t addr, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + s3->accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + s3->accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + break; + + default: break; } } @@ -4527,12 +5592,12 @@ s3_accel_read(uint32_t addr, void *p) } static uint16_t -s3_accel_read_w(uint32_t addr, void *p) +s3_accel_read_w(uint32_t addr, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; - uint16_t temp = 0x0000; - uint16_t *vram_w = (uint16_t *) svga->vram; + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + uint16_t temp = 0x0000; + const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) return 0xffff; @@ -4545,7 +5610,7 @@ s3_accel_read_w(uint32_t addr, void *p) return s3->accel.short_stroke; default: - return s3_accel_read(addr, p) | s3_accel_read(addr + 1, p) << 8; + return s3_accel_read(addr, priv) | s3_accel_read(addr + 1, priv) << 8; } return 0xffff; } else { @@ -4555,8 +5620,8 @@ s3_accel_read_w(uint32_t addr, void *p) s3_wait_fifo_idle(s3); temp = s3->accel.short_stroke; } else { - temp = s3_accel_read((addr & 0xfffe), p); - temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; + temp = s3_accel_read((addr & 0xfffe), priv); + temp |= s3_accel_read((addr & 0xfffe) + 1, priv) << 8; } } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD @@ -4565,20 +5630,23 @@ s3_accel_read_w(uint32_t addr, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); + s3->accel_start(8, 1, temp | (temp << 16), 0, s3); else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + s3->accel_start(16, 1, temp | (temp << 16), 0, s3); else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + break; + + default: break; } } @@ -4588,12 +5656,12 @@ s3_accel_read_w(uint32_t addr, void *p) } static uint32_t -s3_accel_read_l(uint32_t addr, void *p) +s3_accel_read_l(uint32_t addr, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; - uint32_t temp = 0x00000000; - uint16_t *vram_w = (uint16_t *) svga->vram; + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + uint32_t temp = 0x00000000; + const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) return 0xffffffff; @@ -4720,15 +5788,15 @@ s3_accel_read_l(uint32_t addr, void *p) break; default: - temp = s3_accel_read_w(addr, p) | (s3_accel_read_w(addr + 2, p) << 16); + temp = s3_accel_read_w(addr, priv) | (s3_accel_read_w(addr + 2, priv) << 16); break; } } else { if (addr & 0x8000) { - temp = s3_accel_read((addr & 0xfffc), p); - temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; - temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; - temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; + temp = s3_accel_read((addr & 0xfffc), priv); + temp |= s3_accel_read((addr & 0xfffc) + 1, priv) << 8; + temp |= s3_accel_read((addr & 0xfffc) + 2, priv) << 16; + temp |= s3_accel_read((addr & 0xfffc) + 3, priv) << 24; } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG @@ -4736,31 +5804,34 @@ s3_accel_read_l(uint32_t addr, void *p) case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); + s3->accel_start(8, 1, temp, 0, s3); + s3->accel_start(8, 1, temp >> 16, 0, s3); } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(1, 1, 0xffffffff, temp, s3); + s3->accel_start(1, 1, 0xffffffff, temp >> 16, s3); } break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); + s3->accel_start(16, 1, temp, 0, s3); + s3->accel_start(16, 1, temp >> 16, 0, s3); } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + s3->accel_start(2, 1, 0xffffffff, temp, s3); + s3->accel_start(2, 1, 0xffffffff, temp >> 16, s3); } break; + + default: + break; } } } @@ -4808,13 +5879,15 @@ polygon_setup(s3_t *s3) } #define READ(addr, dat) \ - if (s3->bpp == 0 && !s3->color_16bit) \ + if ((s3->bpp == 0) && !s3->color_16bit) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if (s3->bpp == 1 || s3->color_16bit) \ + else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) \ dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ - else if (s3->bpp == 2) \ + else if (s3->bpp == 2) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else \ + else if (s3->color_16bit && (svga->bpp == 24)) { \ + dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ + } else \ dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; #define MIX_READ \ @@ -4875,7 +5948,7 @@ polygon_setup(s3_t *s3) { \ old_dest_dat = dest_dat; \ MIX_READ \ - dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); \ } #define ROPMIX_READ(D, P, S) \ @@ -5660,15 +6733,18 @@ polygon_setup(s3_t *s3) } #define WRITE(addr, dat) \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (s3->bpp == 1 || s3->color_16bit) { \ + } else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) { \ vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ - } else if (s3->bpp == 2) { \ + } else if (s3->bpp == 2) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ + } else if (s3->color_16bit && (svga->bpp == 24)) { \ + vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ + svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else { \ vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ @@ -5755,6 +6831,9 @@ convert_to_rgb32(int idf, int is_yuv, uint32_t val, uint8_t *r, uint8_t *g, uint dg = (dg / 31.0) * 255.0; db = (db / 31.0) * 255.0; break; + + default: + break; } *r = (uint8_t) round(dr); @@ -5847,6 +6926,9 @@ convert_from_rgb32(int idf, int odf, int is_yuv, uint32_t *val, uint8_t r, uint8 db = (db / 255.0) * 31.0; *val = (((uint32_t) round(dr)) << 10) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); break; + + default: + break; } } @@ -6050,30 +7132,13 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } void -s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) -{ - if (!cpu_input) { - s3->accel.ssv_len = ssv & 0x0f; - s3->accel.ssv_dir = ssv & 0xe0; - s3->accel.ssv_draw = ssv & 0x10; - - if (s3_cpu_src(s3)) { - return; /*Wait for data from CPU*/ - } - } - - s3_accel_start(count, cpu_input, mix_dat, cpu_dat, s3); -} - -void -s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) +s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) { - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *)priv; + svga_t *svga = &s3->svga; uint32_t src_dat = 0; uint32_t dest_dat; uint32_t old_dest_dat; - uint32_t out; - uint32_t pat_dat = 0; int frgd_mix; int bkgd_mix; int clip_t = s3->accel.multifunc[1] & 0xfff; @@ -6081,92 +7146,34 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ int clip_b = s3->accel.multifunc[3] & 0xfff; int clip_r = s3->accel.multifunc[4] & 0xfff; int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask = 0; + uint32_t mix_mask = (s3->accel.cmd & 0x200) ? 0x8000 : 0x80; uint16_t *vram_w = (uint16_t *) svga->vram; uint32_t *vram_l = (uint32_t *) svga->vram; - uint32_t compare = s3->accel.color_cmp; - uint8_t rop = s3->accel.ropmix & 0xff; - int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; uint32_t rd_mask = s3->accel.rd_mask; + uint32_t wrt_mask = s3->accel.wrt_mask; + uint32_t frgd_color = s3->accel.frgd_color; + uint32_t bkgd_color = s3->accel.bkgd_color; int cmd = s3->accel.cmd >> 13; - uint32_t srcbase; - uint32_t dstbase; - - if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) { - cmd |= 8; - } - - // SRC-BASE/DST-BASE - if ((s3->accel.multifunc[0xd] >> 4) & 7) { - srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); - } else { - srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); - } - if ((s3->accel.multifunc[0xd] >> 0) & 7) { - dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); - } else { - dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); - } - if (s3->bpp == 1) { - srcbase >>= 1; - dstbase >>= 1; - } else if (s3->bpp == 3) { - srcbase >>= 2; - dstbase >>= 2; - } - if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) { + if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) s3->force_busy = 1; - } - - if (!cpu_input) - s3->accel.dat_count = 0; if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { - if ((s3->bpp == 3) && count == 2) { - if (s3->accel.dat_count) { - cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; - count = 4; - s3->accel.dat_count = 0; - } else { - s3->accel.dat_buf = cpu_dat & 0xffff; - s3->accel.dat_count = 1; - } + if (s3->color_16bit) { + if (count > 1) + count >>= 1; } - if (s3->bpp == 1 || s3->color_16bit) - count >>= 1; - if (s3->bpp == 3) - count >>= 2; } - if (s3->bpp == 0 && !s3->color_16bit) - rd_mask &= 0xff; - else if (s3->bpp == 1 || s3->color_16bit) + if (s3->color_16bit) rd_mask &= 0xffff; - - if (s3->bpp == 0 && !s3->color_16bit) - compare &= 0xff; - if (s3->bpp == 1 || s3->color_16bit) - compare &= 0xffff; - - switch (s3->accel.cmd & 0x600) { - case 0x000: - mix_mask = 0x80; - break; - case 0x200: - mix_mask = 0x8000; - break; - case 0x400: - mix_mask = 0x80000000; - break; - case 0x600: - mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; - break; - } + else + rd_mask &= 0xff; /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (s3->accel.ssv_state == 0) @@ -6175,16 +7182,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - if (s3->accel.cmd & 8) /*Radial*/ - { + if (s3->accel.cmd & 8) { /*Radial*/ while (count-- && s3->accel.ssv_len >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6192,17 +7198,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; + + default: + break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - MIX + MIX - if (s3->accel.ssv_draw) - { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } + if (s3->accel.ssv_draw) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -6212,6 +7218,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ cpu_dat >>= 8; else cpu_dat >>= 16; + if (!s3->accel.ssv_len) break; @@ -6244,9 +7251,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx++; s3->accel.cy++; break; + + default: + break; } s3->accel.ssv_len--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; } s3->accel.cur_x = s3->accel.cx; @@ -6256,35 +7268,59 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.sy = s3->accel.maj_axis_pcnt & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.wrt_mask != 0xffff) { + if (s3->accel.cur_x & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + } else { + if (s3->accel.cur_x & 0x400) + s3->accel.color_16bit_check = 1; + else + s3->accel.color_16bit_check = 0; - s3->accel.sy = s3->accel.maj_axis_pcnt; + s3->accel.minus = 0; + } + } else { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0; + } - if (s3_cpu_src(s3)) { + if (s3_cpu_src(s3)) return; /*Wait for data from CPU*/ - } } + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - if (s3->accel.cmd & 8) /*Radial*/ - { + if (s3->accel.cmd & 8) { /*Radial*/ + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.color_16bit_check) + return; + if (s3->accel.wrt_mask != 0xffff) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + } + while (count-- && s3->accel.sy >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24)) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24)) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); break; case 2: src_dat = cpu_dat; @@ -6292,28 +7328,27 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; + + default: + break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - MIX + MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); } mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } - if (!s3->accel.sy) { + if (!s3->accel.sy) break; - } switch (s3->accel.cmd & 0xe0) { case 0x00: @@ -6344,31 +7379,58 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx++; s3->accel.cy++; break; + + default: + break; } s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; } s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; - } else /*Bresenham*/ - { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + } else { /*Bresenham*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; } + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + else + return; + } + } + + s3_log("CMD=%04x, curx=%d, lwrtmask=%04x, actual wrtmask=%04x, frgdmix=%d, " + "bkgdmix=%d, input=%d, cnt=%d.\n", s3->accel.cmd, s3->accel.cur_x, + wrt_mask, s3->accel.wrt_mask, frgd_mix, bkgd_mix, cpu_input, count); while (count-- && s3->accel.sy >= 0) { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; s3->accel.temp_cnt = 16; } - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | + (s3->accel.bkgd_color_actual[1] << 8); + } break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | + (s3->accel.frgd_color_actual[1] << 8); + } break; case 2: src_dat = cpu_dat; @@ -6376,14 +7438,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; + + default: + break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - MIX + MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); } } @@ -6397,80 +7462,822 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; } - if (s3->bpp == 0 && !s3->color_16bit) - cpu_dat >>= 8; - else { + + if (s3->color_16bit) cpu_dat >>= 16; - } + else + cpu_dat >>= 8; - if (!s3->accel.sy) { + if (!s3->accel.sy) break; - } - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cy--; - break; - case 0x20: - s3->accel.cy--; - break; - case 0x40: - s3->accel.cx--; - break; - case 0x60: + if (s3->accel.cmd & 0x40) { + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x20) s3->accel.cx++; - break; - case 0x80: + else + s3->accel.cx--; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } else { + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x80) s3->accel.cy++; + else + s3->accel.cy--; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } + + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 2: /*Rectangle fill*/ + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.pix_trans_x_count = 0; + + s3->accel.dest = s3->accel.cy * s3->width; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.cur_x & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + + if (s3->accel.color_16bit_check) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x00) && !(s3->accel.cmd & 2)) + s3->accel.color_16bit_check_rectfill = !!s3_cpu_src(s3); + else + s3->accel.color_16bit_check_rectfill = 0; + } + + if (s3->accel.color_16bit_check_rectfill) { + if (s3->accel.color_16bit_check) { + s3->accel.pix_trans_ptr = (uint8_t *) calloc(1, (s3->accel.sx + 1) << 1); + s3->accel.pix_trans_ptr_cnt = (s3->accel.sx + 1) << 1; + } + } else + s3->accel.pix_trans_x_count = 0; + } else { + s3->accel.pix_trans_x_count = 0; + s3->accel.color_16bit_check = 0; + s3->accel.color_16bit_check_rectfill = 0; + s3->accel.minus = 0; + } + + if (s3_cpu_src(s3)) { + s3->data_available = 0; + return; /*Wait for data from CPU*/ + } else if (s3_cpu_dest(s3)) { + s3->data_available = 1; + return; + } + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.b2e8_pix) { + if (!s3->accel.color_16bit_check) { + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + } else if (s3->accel.color_16bit_check && (s3->accel.cmd == 0x40f3)) + return; + } + } + + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + } else if (s3_cpu_dest(s3) && vram_mask) { + /* Mix data = current video memory value. */ + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + + if (s3_cpu_dest(s3)) { + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, src_dat); + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + } else { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + } break; - case 0xa0: - s3->accel.cy++; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + } break; - case 0xc0: - s3->accel.cx--; + case 2: + src_dat = cpu_dat; break; - case 0xe0: - s3->accel.cx++; + case 3: + src_dat = 0; + break; + + default: break; } + } + + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (s3->color_16bit) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + s3->accel.cx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + else + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + + s3->accel.cy &= 0xfff; + s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.sy--; + + if (cpu_input) { + if (s3->accel.b2e8_pix) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + return; + } + if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + return; + } + } + } + break; + + case 6: /*BitBlt*/ + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (s3->accel.destx_distp & 0x400) { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.color_16bit_check = 1; + s3->accel.minus = 0; + } + s3->accel.srcminus = 0x400; + } else { + s3->accel.color_16bit_check = 0; + s3->accel.minus = 0; + s3->accel.srcminus = 0; + } + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) { + return; /*Wait for data from CPU*/ + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); + else + return; + } + + if (!cpu_input && (frgd_mix == 3) && !vram_mask && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { + while (1) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + } + + s3->accel.cx++; + s3->accel.dx++; + s3->accel.sx--; + s3->accel.dx &= 0xfff; + if (s3->accel.sx < 0) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cy++; + s3->accel.dy++; + + s3->accel.dy &= 0xfff; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; + return; + } + } + } + } else { + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && ((s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { + if (vram_mask && (s3->accel.cmd & 0x10)) { + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); + } + break; + case 1: + src_dat = frgd_color; + if (s3->color_16bit && (svga->bpp < 24)) { + if (!s3->accel.color_16bit_check) + src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); + } + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); + if (vram_mask && (s3->accel.cmd & 0x10)) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + + default: + break; + } + + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + + MIX + + if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->color_16bit) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx++; + s3->accel.dx++; + } else { + s3->accel.cx--; + s3->accel.dx--; + } + s3->accel.dx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + } else { + s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy++; + s3->accel.dy++; + } else { + s3->accel.cy--; + s3->accel.dy--; + } + s3->accel.dy &= 0xfff; + s3->accel.src = s3->accel.cy * s3->width; + s3->accel.dest = s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; + return; + } + } + } + } + break; + + default: + break; + } +} + +void +s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) +{ + if (!cpu_input) { + s3->accel.ssv_len = ssv & 0x0f; + s3->accel.ssv_dir = ssv & 0xe0; + s3->accel.ssv_draw = ssv & 0x10; + + if (s3_cpu_src(s3)) { + return; /*Wait for data from CPU*/ + } + } + + s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3); +} + +void +s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) +{ + s3_t *s3 = (s3_t *)priv; + svga_t *svga = &s3->svga; + uint32_t src_dat = 0; + uint32_t dest_dat; + uint32_t old_dest_dat; + uint32_t out; + uint32_t pat_dat = 0; + int frgd_mix; + int bkgd_mix; + int clip_t = s3->accel.multifunc[1] & 0xfff; + int clip_l = s3->accel.multifunc[2] & 0xfff; + int clip_b = s3->accel.multifunc[3] & 0xfff; + int clip_r = s3->accel.multifunc[4] & 0xfff; + int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; + uint32_t mix_mask = 0; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint32_t compare = s3->accel.color_cmp; + uint8_t rop = s3->accel.ropmix & 0xff; + int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; + uint32_t rd_mask = s3->accel.rd_mask; + uint32_t wrt_mask = s3->accel.wrt_mask; + uint32_t frgd_color = s3->accel.frgd_color; + uint32_t bkgd_color = s3->accel.bkgd_color; + int cmd = s3->accel.cmd >> 13; + uint32_t srcbase; + uint32_t dstbase; + + s3->accel.srcminus = 0; + s3->accel.minus = 0; + + if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) + cmd |= 8; + + // SRC-BASE/DST-BASE + if ((s3->accel.multifunc[0xd] >> 4) & 7) + srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); + else + srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); + + if ((s3->accel.multifunc[0xd] >> 0) & 7) + dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); + else + dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); + + if ((s3->bpp == 1) || s3->color_16bit) { + srcbase >>= 1; + dstbase >>= 1; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; + } + + if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) + s3->force_busy = 1; + + if (!cpu_input) + s3->accel.dat_count = 0; + + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { + if ((s3->bpp == 3) && (count == 2)) { + if (s3->accel.dat_count) { + cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; + count = 4; + s3->accel.dat_count = 0; + } else { + s3->accel.dat_buf = cpu_dat & 0xffff; + s3->accel.dat_count = 1; + } + } + if ((s3->bpp == 1) || s3->color_16bit) + count >>= 1; + else if (s3->bpp == 3) + count >>= 2; + } + + if ((s3->bpp == 0) && !s3->color_16bit) + rd_mask &= 0xff; + else if ((s3->bpp == 1) || s3->color_16bit) + rd_mask &= 0xffff; + + if (s3->bpp == 0) + compare &= 0xff; + else if (s3->bpp == 1) + compare &= 0xffff; + + switch (s3->accel.cmd & 0x600) { + case 0x000: + mix_mask = 0x80; + break; + case 0x200: + mix_mask = 0x8000; + break; + case 0x400: + mix_mask = 0x80000000; + break; + case 0x600: + mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; + break; + + default: + break; + } + + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. + When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on + the NOP command)*/ + switch (cmd) { + case 0: /*NOP (Short Stroke Vectors)*/ + if (s3->accel.ssv_state == 0) + break; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) /*Radial*/ + { + while (count-- && s3->accel.ssv_len >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + 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; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.ssv_draw) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (!s3->accel.ssv_len) + break; + + switch (s3->accel.ssv_dir & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + + default: + break; + } + + s3->accel.ssv_len--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; + } + break; + + case 1: /*Draw line*/ + if (!cpu_input) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.sy = s3->accel.maj_axis_pcnt; + + if (s3_cpu_src(s3)) + return; /*Wait for data from CPU*/ + } + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) { /*Radial*/ + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + 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; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if ((s3->bpp == 0) && !s3->color_16bit) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (!s3->accel.sy) + break; + + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + + default: + break; + } + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; + } else { /*Bresenham*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + 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; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } } else { - s3->accel.err_term += s3->accel.desty_axstp; + mix_dat <<= 1; + mix_dat |= 1; } - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cx--; - break; - case 0x20: - s3->accel.cx++; - break; - case 0x40: - s3->accel.cy--; - break; - case 0x60: + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (!s3->accel.sy) + break; + + if (s3->accel.cmd & 0x40) { + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } else { + if (s3->accel.cmd & 0x20) s3->accel.cx++; - break; - case 0xc0: - s3->accel.cy++; - break; - case 0xe0: - s3->accel.cy++; - break; + else + s3->accel.cx--; + + if (s3->accel.err_term >= 0) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + } else + s3->accel.err_term += s3->accel.desty_axstp; } + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; } break; @@ -6479,15 +8286,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; - - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -6528,13 +8328,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ READ(s3->accel.dest + s3->accel.cx, src_dat); if (vram_mask) src_dat = ((src_dat & rd_mask) == rd_mask); - } else + } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6542,15 +8342,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; + + default: + break; } + } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.cx, dest_dat); MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.cx, dest_dat); } } @@ -6569,28 +8372,29 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (s3->accel.cmd & 0x20) s3->accel.cx++; else s3->accel.cx--; + s3->accel.cx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; + s3->accel.cy &= 0xfff; s3->accel.dest = dstbase + s3->accel.cy * s3->width; s3->accel.sy--; @@ -6649,6 +8453,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; /*Not supported?*/ break; + + default: + break; } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { @@ -6656,8 +8463,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); } } @@ -6692,27 +8498,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ break; case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { + if (!cpu_input) { /*!cpu_input is trigger to start operation*/ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.dx = s3->accel.destx_distp & 0x7ff; - if (s3->accel.destx_distp & 0x800) - s3->accel.dx |= ~0x7ff; - s3->accel.dy = s3->accel.desty_axstp & 0x7ff; - if (s3->accel.desty_axstp & 0x800) - s3->accel.dy |= ~0x7ff; - - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -6731,16 +8525,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ READ(s3->accel.src + s3->accel.cx, src_dat); READ(s3->accel.dest + s3->accel.dx, dest_dat); - dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); - } + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); } s3->accel.cx++; s3->accel.dx++; s3->accel.sx--; + s3->accel.dx &= 0xfff; if (s3->accel.sx < 0) { s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; @@ -6749,20 +8542,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy++; s3->accel.dy++; + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } } } else { while (count-- && s3->accel.sy >= 0) { - /*This is almost required by OS/2's software cursor or we will risk writing/reading garbage around it.*/ - if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && ((s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b)) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && ((s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { if (vram_mask && (s3->accel.cmd & 0x10)) { READ(s3->accel.src + s3->accel.cx, mix_dat); mix_dat = ((mix_dat & rd_mask) == rd_mask); @@ -6770,10 +8565,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -6783,16 +8578,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (vram_mask && (s3->accel.cmd & 0x10)) src_dat = ((src_dat & rd_mask) == rd_mask); break; - } - if ((((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2))) { + default: + break; + } + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); MIX - if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) - { + if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { WRITE(s3->accel.dest + s3->accel.dx, dest_dat); } } @@ -6803,9 +8599,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (s3->accel.cmd & 0x20) { s3->accel.cx++; @@ -6814,16 +8609,16 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx--; s3->accel.dx--; } + s3->accel.dx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } else { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; if (s3->accel.cmd & 0x80) { @@ -6833,17 +8628,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy--; s3->accel.dy--; } - + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; - if (cpu_input) { + if (cpu_input) return; - } if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -6858,18 +8654,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; @@ -6910,15 +8698,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (vram_mask) src_dat = ((src_dat & rd_mask) == rd_mask); break; + + default: + break; } - if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, dest_dat); } } @@ -6926,7 +8716,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0) + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -6938,14 +8728,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); s3->accel.dx--; } + s3->accel.dx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { - s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx = ((s3->accel.cx - (((s3->accel.maj_axis_pcnt & 0xfff) + 1))) & 7) | (s3->accel.cx & ~7); + s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } else { - s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx = ((s3->accel.cx + (((s3->accel.maj_axis_pcnt & 0xfff) + 1))) & 7) | (s3->accel.cx & ~7); + s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; @@ -6957,6 +8748,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; } + s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -6966,6 +8758,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ return; } if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -6987,12 +8781,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; } if ((s3->accel.cmd & 0x100) && !cpu_input) @@ -7009,8 +8799,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -7023,12 +8812,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy++; else s3->accel.cy--; - } + s3->accel.cy &= 0xfff; + } if (s3->accel.destx_distp > s3->accel.cur_x) s3->accel.cx++; else s3->accel.cx--; + + s3->accel.cx &= 0xfff; } } else { error = s3->accel.dy / 2; @@ -7036,13 +8828,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { src_dat = s3->accel.frgd_color; - if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -7055,11 +8846,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx++; else s3->accel.cx--; + + s3->accel.cx &= 0xfff; } if (s3->accel.desty_axstp > s3->accel.cur_y) s3->accel.cy++; else s3->accel.cy--; + + s3->accel.cy &= 0xfff; } } s3->accel.cur_x = s3->accel.cx; @@ -7117,15 +8912,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (vram_mask) src_dat = ((src_dat & rd_mask) == rd_mask); break; + + default: + break; } - if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.poly_x, dest_dat); MIX - if (s3->accel.cmd & 0x10) - { + if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); } } @@ -7179,18 +8976,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; s3->accel.px = s3->accel.pat_x & 0xfff; - if (s3->accel.pat_x & 0x1000) - s3->accel.px |= ~0xfff; s3->accel.py = s3->accel.pat_y & 0xfff; - if (s3->accel.pat_y & 0x1000) - s3->accel.py |= ~0xfff; s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); @@ -7218,6 +9007,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; + + default: + break; } if (s3->accel.ropmix & 0x100) { @@ -7234,6 +9026,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: READ(s3->accel.pattern + s3->accel.px, pat_dat); break; + + default: + break; } } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -7249,10 +9044,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: READ(s3->accel.pattern + s3->accel.px, pat_dat); break; + + default: + break; } } - if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX @@ -7282,13 +9080,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.px -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.px -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } else { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.px += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); + s3->accel.px += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); } s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; @@ -7301,7 +9099,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; s3->accel.py--; } - s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); @@ -7316,14 +9113,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } } break; + + default: + break; } } static uint8_t -s3_pci_read(int func, int addr, void *p) +s3_pci_read(UNUSED(int func), int addr, void *priv) { - s3_t *s3 = (s3_t *) p; - svga_t *svga = &s3->svga; + const s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; switch (addr) { case 0x00: @@ -7341,13 +9141,20 @@ s3_pci_read(int func, int addr, void *p) return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ else return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - break; + break; case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ - case 0x08: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ + case 0x08: switch (s3->chip) { /*Revision ID*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } + break; case 0x09: return 0; /*Programming interface*/ @@ -7356,17 +9163,14 @@ s3_pci_read(int func, int addr, void *p) return 0x00; /*Supports VGA interface*/ else return 0x01; - break; case 0x0b: if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) return 0x03; else return 0x00; - break; case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; - break; case 0x10: return 0x00; /*Linear frame buffer address*/ @@ -7403,18 +9207,19 @@ s3_pci_read(int func, int addr, void *p) case 0x3e: return (s3->chip == S3_TRIO64V2) ? 0x04 : 0x00; - break; case 0x3f: return (s3->chip == S3_TRIO64V2) ? 0xff : 0x00; + + default: break; } return 0; } static void -s3_pci_write(int func, int addr, uint8_t val, void *p) +s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; switch (addr) { @@ -7489,6 +9294,9 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) case 0x3c: s3->int_line = val; return; + + default: + break; } } @@ -7527,6 +9335,9 @@ fifo_thread(void *param) case FIFO_OUT_DWORD: s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); break; + + default: + break; } s3->fifo_read_idx++; @@ -7596,6 +9407,11 @@ s3_reset(void *priv) s3->pci_regs[0x32] = 0x0c; s3->pci_regs[0x33] = 0x00; + if (s3->chip <= S3_86C924) + s3->accel_start = s3_911_accel_start; + else + s3->accel_start = s3_accel_start; + switch (s3->card_type) { case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: @@ -7665,12 +9481,14 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: + case S3_CARDEX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: case S3_NUMBER9_9FX: - if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) + if (s3->chip == S3_TRIO64V) svga->crtc[0x53] = 0x08; break; @@ -7686,6 +9504,9 @@ s3_reset(void *priv) s3->pci_regs[0x3e] = 4; s3->pci_regs[0x3f] = 0xff; break; + + default: + break; } if (s3->has_bios) { @@ -7867,6 +9688,14 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); break; + case S3_PHOENIX_TRIO32_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO32; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); + break; case S3_DIAMOND_STEALTH_SE: bios_fn = ROM_DIAMOND_STEALTH_SE; chip = S3_TRIO32; @@ -7896,6 +9725,14 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_STB_POWERGRAPH_64_VIDEO: + bios_fn = ROM_STB_POWERGRAPH_64_VIDEO; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; case S3_PHOENIX_TRIO64VPLUS: bios_fn = ROM_PHOENIX_TRIO64VPLUS; chip = S3_TRIO64V; @@ -7912,6 +9749,11 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_CARDEX_TRIO64VPLUS: + bios_fn = ROM_CARDEX_TRIO64VPLUS; + chip = S3_TRIO64V; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64vp_cardex_pci); + break; case S3_DIAMOND_STEALTH64_764: bios_fn = ROM_DIAMOND_STEALTH64_764; chip = S3_TRIO64; @@ -7956,7 +9798,7 @@ s3_init(const device_t *info) s3->has_bios = (bios_fn != NULL); if (s3->has_bios) { - rom_init(&s3->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (info->flags & DEVICE_PCI) mem_mapping_disable(&s3->bios_rom.mapping); } @@ -8010,18 +9852,40 @@ s3_init(const device_t *info) svga->hwcursor.cur_ysize = 64; - if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771))) - svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; - else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) - svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; + switch (chip) { + case S3_VISION964: + switch (info->local) { + case S3_ELSAWIN2KPROX_964: + svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + break; + default: + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + break; + } + break; + + case S3_VISION968: + switch (info->local) { + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + case S3_NUMBER9_9FX_771: + svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + break; + case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; + break; + default: + break; + } + break; + } if (chip >= S3_VISION964) { switch (vram) { case 0: /* 512 kB */ svga->vram_mask = (1 << 19) - 1; - svga->vram_max = 2 << 20; + svga->vram_max = 1 << 19; break; case 1: /* 1 MB */ /* VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus. @@ -8029,7 +9893,7 @@ s3_init(const device_t *info) This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference? */ svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 2 << 20; + svga->vram_max = 1 << 20; break; case 2: default: /*2 MB */ @@ -8085,6 +9949,11 @@ s3_init(const device_t *info) svga->force_old_addr = 1; + if (s3->chip <= S3_86C924) + s3->accel_start = s3_911_accel_start; + else + s3->accel_start = s3_accel_start; + switch (s3->card_type) { case S3_ORCHID_86C911: case S3_DIAMOND_STEALTH_VRAM: @@ -8110,7 +9979,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; s3->width = 1024; - svga->ramdac = device_add(&sc11487_ramdac_device); + svga->ramdac = device_add(&att490_ramdac_device); svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -8176,7 +10045,7 @@ s3_init(const device_t *info) case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; - stepping = 0x91; /*86C928*/ + stepping = 0x91; /*86C928D*/ s3->id = stepping; s3->id_ext = stepping; s3->id_ext_pci = 0; @@ -8204,7 +10073,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION864: case S3_MIROCRYSTAL20SD_864: /*BIOS 3.xx has a SDAC ramdac.*/ svga->decode_mask = (8 << 20) - 1; - if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) + if (info->local == S3_PARADISE_BAHAMAS64) stepping = 0xc0; /*Vision864*/ else stepping = 0xc1; /*Vision864P*/ @@ -8227,13 +10096,18 @@ s3_init(const device_t *info) s3->packed_mmio = 1; svga->crtc[0x5a] = 0x0a; - if (info->local == S3_ELSAWIN2KPROX_964) - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - else - svga->ramdac = device_add(&bt485_ramdac_device); - - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; + switch (info->local) { + case S3_ELSAWIN2KPROX_964: + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + default: + svga->ramdac = device_add(&bt485_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + } break; case S3_ELSAWIN2KPROX: @@ -8257,14 +10131,20 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; } - if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771) { - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - } else { - svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = tvp3026_getclock; + switch (info->local) { + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + case S3_NUMBER9_9FX_771: + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; + default: + svga->ramdac = device_add(&tvp3026_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + svga->conv_16to32 = tvp3026_conv_16to32; + break; } break; @@ -8299,6 +10179,7 @@ s3_init(const device_t *info) break; case S3_PHOENIX_TRIO32: + case S3_PHOENIX_TRIO32_ONBOARD: case S3_DIAMOND_STEALTH_SE: svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Trio32*/ @@ -8312,23 +10193,24 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_STB_POWERGRAPH_64_VIDEO: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_CARDEX_TRIO64VPLUS: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: if (device_get_config_int("memory") == 1) svga->vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ /* Fall over. */ - + fallthrough; case S3_NUMBER9_9FX: svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; - if (info->local == S3_PHOENIX_TRIO64VPLUS || info->local == S3_PHOENIX_TRIO64VPLUS_ONBOARD) { + if (s3->chip == S3_TRIO64V) svga->crtc[0x53] = 0x08; - } svga->clock_gen = s3; svga->getclock = s3_trio64_getclock; @@ -8359,8 +10241,12 @@ s3_init(const device_t *info) return NULL; } - if (s3->pci) - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + if (s3->pci) { + if (bios_fn == NULL) + pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3, &s3->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, s3_pci_read, s3_pci_write, s3, &s3->pci_slot); + } s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); @@ -8547,12 +10433,24 @@ s3_phoenix_trio64_available(void) return rom_present(ROM_PHOENIX_TRIO64); } +static int +s3_stb_powergraph_64_video_available(void) +{ + return rom_present(ROM_STB_POWERGRAPH_64_VIDEO); +} + static int s3_phoenix_trio64vplus_available(void) { return rom_present(ROM_PHOENIX_TRIO64VPLUS); } +static int +s3_cardex_trio64vplus_available(void) +{ + return rom_present(ROM_PHOENIX_TRIO64VPLUS); +} + static int s3_diamond_stealth64_764_available(void) { @@ -8566,9 +10464,9 @@ s3_trio64v2_dx_available(void) } static void -s3_close(void *p) +s3_close(void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; s3->fifo_thread_run = 0; thread_set_event(s3->wake_fifo_thread); @@ -8585,17 +10483,17 @@ s3_close(void *p) } static void -s3_speed_changed(void *p) +s3_speed_changed(void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; svga_recalctimings(&s3->svga); } static void -s3_force_redraw(void *p) +s3_force_redraw(void *priv) { - s3_t *s3 = (s3_t *) p; + s3_t *s3 = (s3_t *) priv; s3->svga.fullchange = s3->svga.monitor->mon_changeframecount; } @@ -8859,7 +10757,7 @@ const device_t s3_spea_mercury_lite_86c928_pci_device = { { .available = s3_spea_mercury_lite_pci_available }, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, - .config = s3_standard_config + .config = s3_orchid_86c911_config }; const device_t s3_mirocrystal_20sd_864_vlb_device = { @@ -9058,6 +10956,20 @@ const device_t s3_9fx_pci_device = { .config = s3_9fx_config }; +const device_t s3_phoenix_trio32_onboard_vlb_device = { + .name = "S3 Trio32 VLB On-Board (Phoenix)", + .internal_name = "px_trio32_onboard_vlb", + .flags = DEVICE_VLB, + .local = S3_PHOENIX_TRIO32_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = NULL }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config +}; + const device_t s3_phoenix_trio32_vlb_device = { .name = "S3 Trio32 VLB (Phoenix)", .internal_name = "px_trio32_vlb", @@ -9072,6 +10984,20 @@ const device_t s3_phoenix_trio32_vlb_device = { .config = s3_phoenix_trio32_config }; +const device_t s3_phoenix_trio32_onboard_pci_device = { + .name = "S3 Trio32 PCI On-Board (Phoenix)", + .internal_name = "px_trio32_onboard_pci", + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO32_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = NULL }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config +}; + const device_t s3_phoenix_trio32_pci_device = { .name = "S3 Trio32 PCI (Phoenix)", .internal_name = "px_trio32_pci", @@ -9156,6 +11082,20 @@ const device_t s3_phoenix_trio64_pci_device = { .config = s3_standard_config }; +const device_t s3_stb_powergraph_64_video_vlb_device = { + .name = "S3 Trio64V+ (STB PowerGraph 64 Video) VLB", + .internal_name = "stb_trio64vplus_vlb", + .flags = DEVICE_VLB, + .local = S3_STB_POWERGRAPH_64_VIDEO, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_stb_powergraph_64_video_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_trio64vplus_onboard_pci_device = { .name = "S3 Trio64V+ PCI On-Board (Phoenix)", .internal_name = "px_trio64vplus_onboard_pci", @@ -9184,6 +11124,20 @@ const device_t s3_phoenix_trio64vplus_pci_device = { .config = s3_standard_config }; +const device_t s3_cardex_trio64vplus_pci_device = { + .name = "S3 Trio64V+ PCI (Cardex)", + .internal_name = "cardex_trio64vplus_pci", + .flags = DEVICE_PCI, + .local = S3_CARDEX_TRIO64VPLUS, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_cardex_trio64vplus_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_vision864_vlb_device = { .name = "S3 Vision864 VLB (Phoenix)", .internal_name = "px_vision864_vlb", diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index feaba7fe87..a4cec9c09b 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -172,7 +172,9 @@ typedef struct virge_t { uint32_t linear_base, linear_size; uint8_t pci_regs[256]; - int card; + + uint8_t pci_slot; + uint8_t irq_state; int pci; int chip; @@ -278,7 +280,7 @@ typedef struct virge_t { uint32_t cmd_dma_base; uint32_t dma_ptr; uint64_t blitter_time; - volatile int fifo_slot; + int fifo_slots_num; pc_timer_t tri_timer; @@ -307,12 +309,12 @@ static void s3_virge_updatemapping(virge_t *virge); static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); -static uint8_t s3_virge_mmio_read(uint32_t addr, void *p); -static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p); -static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p); -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p); -static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); -static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); +static uint8_t s3_virge_mmio_read(uint32_t addr, void *priv); +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *rivp); +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv); +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv); +static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv); +static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv); enum { CMD_SET_AE = 1, @@ -387,9 +389,9 @@ s3_virge_log(const char *fmt, ...) #endif static void -s3_virge_tri_timer(void *p) +s3_virge_tri_timer(void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; thread_set_event(virge->wake_render_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -418,9 +420,9 @@ static void s3_virge_update_irqs(virge_t *virge) { if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK))) - pci_set_irq(virge->card, PCI_INTA); + pci_set_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); else - pci_clear_irq(virge->card, PCI_INTA); + pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); } static void @@ -447,9 +449,9 @@ render_thread(void *param) } static void -s3_virge_out(uint16_t addr, uint8_t val, void *p) +s3_virge_out(uint16_t addr, uint8_t val, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; uint8_t old; uint32_t cursoraddr; @@ -573,6 +575,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *p) case 2: virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); break; + + default: + break; } virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; @@ -587,6 +592,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *p) case 2: virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); break; + + default: + break; } virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; @@ -633,6 +641,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0xaa: i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); break; + + default: + break; } if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -648,14 +659,17 @@ s3_virge_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -s3_virge_in(uint16_t addr, void *p) +s3_virge_in(uint16_t addr, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; uint8_t ret; @@ -760,15 +774,26 @@ s3_virge_in(uint16_t addr, void *p) static void s3_virge_recalctimings(svga_t *svga) { - virge_t *virge = (virge_t *) svga->p; + const virge_t *virge = (virge_t *) svga->priv; svga->hdisp = svga->hdisp_old; + if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + } + + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + } + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + svga->hdisp += 0x100 * svga->dots_per_clock; } if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; @@ -799,6 +824,26 @@ s3_virge_recalctimings(svga_t *svga) svga->clock = (cpuclock * (float) (1ULL << 32)) / freq; } + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { + /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3) + 1*/; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + video_force_resize_set_monitor(1, svga->monitor_index); + } else { + svga->hblankstart = (((svga->crtc[0x5d] & 0x04) >> 2) << 8) + svga->crtc[2]; + + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x5d] & 0x08) >> 3) << 6); + svga->hblank_end_mask = 0x7f; + } + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); @@ -818,15 +863,21 @@ s3_virge_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; } break; case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; } break; case 24: @@ -837,9 +888,13 @@ s3_virge_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; break; + + default: + break; } } svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; + svga->overlay.ena = 0; s3_virge_log("VGA mode\n"); } else /*Streams mode*/ { @@ -865,16 +920,30 @@ s3_virge_recalctimings(svga_t *svga) svga->overlay.v_acc = virge->streams.dda_vert_accumulator; svga->rowoffset = virge->streams.pri_stride >> 3; + if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { + svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { + /* 0x20 = Secondary Stream enabled */ + /* 0x2000 = Primary Stream enabled */ + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20); + } + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ @@ -883,11 +952,35 @@ s3_virge_recalctimings(svga_t *svga) case 7: /*XRGB-32 (X.8.8.8)*/ svga->render = svga_render_32bpp_highres; break; + + default: + break; } svga->vram_display_mask = virge->vram_mask; } } +static void +s3_virge_update_buffer(virge_t *virge) +{ + svga_t *svga = &virge->svga; + + if ((svga->crtc[0x67] & 0xc) != 0xc) + return; + + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->rowoffset = virge->streams.pri_stride >> 3; +} + static void s3_virge_updatemapping(virge_t *virge) { @@ -920,6 +1013,9 @@ s3_virge_updatemapping(virge_t *virge) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); @@ -945,6 +1041,9 @@ s3_virge_updatemapping(virge_t *virge) case 7: virge->linear_size = 0x800000; break; + + default: + break; } virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); @@ -988,7 +1087,7 @@ s3_virge_updatemapping(virge_t *virge) static void s3_virge_vblank_start(svga_t *svga) { - virge_t *virge = (virge_t *) svga->p; + virge_t *virge = (virge_t *) svga->priv; virge->subsys_stat |= INT_VSY; s3_virge_update_irqs(virge); @@ -997,13 +1096,16 @@ s3_virge_vblank_start(svga_t *svga) static void s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) { - if ((addr & 0xffff) < 0x8000) { + if ((addr & 0xffff) < 0x8000) s3_virge_bitblt(virge, 8, val); - } else { + else { switch (addr & 0xffff) { case 0x859c: virge->cmd_dma = val; break; + + default: + break; } } } @@ -1031,7 +1133,6 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) else s3_virge_bitblt(virge, 32, val); } else { - virge->fifo_slot++; switch (addr & 0xfffc) { case 0x8590: virge->cmd_dma_base = val; @@ -1466,28 +1567,40 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) queue_triangle(virge); } break; + + default: + break; } } } static uint8_t -s3_virge_mmio_read(uint32_t addr, void *p) +s3_virge_mmio_read(uint32_t addr, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; uint8_t ret = 0xff; s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff); switch (addr & 0xffff) { + case 0x8504: + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); + ret = virge->subsys_stat; + s3_virge_update_irqs(virge); + return ret; case 0x8505: - ret = 0; - if (virge->s3d_busy || virge->fifo_slot) { - ret = 0x10; - } else { - ret = 0x30; - } - if (virge->fifo_slot) - virge->fifo_slot--; + ret = 0xd0; + if (!virge->s3d_busy) + ret |= 0x20; + return ret; + + case 0x850c: + ret = virge->advfunc_cntl & 0x3f; + ret |= virge->fifo_slots_num << 6; + ret &= 0xff; + return ret; + case 0x850d: + ret = virge->fifo_slots_num >> 2; return ret; case 0x83b0: @@ -1551,28 +1664,35 @@ s3_virge_mmio_read(uint32_t addr, void *p) if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) ret |= SERIAL_PORT_SDR; return ret; + + default: + break; } return 0xff; } static uint16_t -s3_virge_mmio_read_w(uint32_t addr, void *p) +s3_virge_mmio_read_w(uint32_t addr, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; uint16_t ret = 0xffff; s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); switch (addr & 0xfffe) { case 0x8504: - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; + ret = 0xd000; + if (!virge->s3d_busy) + ret |= 0x2000; + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= 0x30; /*A bit of a workaround at the moment.*/ s3_virge_update_irqs(virge); return ret; + case 0x850c: + ret = virge->advfunc_cntl & 0x3f; + ret |= virge->fifo_slots_num << 6; + return ret; + case 0x859c: return virge->cmd_dma; @@ -1584,9 +1704,9 @@ s3_virge_mmio_read_w(uint32_t addr, void *p) } static uint32_t -s3_virge_mmio_read_l(uint32_t addr, void *p) +s3_virge_mmio_read_l(uint32_t addr, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; uint32_t ret = 0xffffffff; s3_virge_log("[%04X:%08X]: MMIO ReadL addr = %04x\n", CS, cpu_state.pc, addr & 0xfffc); @@ -1660,21 +1780,19 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) break; case 0x8504: - if (virge->s3d_busy || virge->fifo_slot) { - ret = (0x10 << 8); - } else { - ret = (0x10 << 8) | (1 << 13); - if (!virge->s3d_busy) - virge->subsys_stat |= INT_3DF_EMP; - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; - } + ret = 0x0000d000; + if (!virge->s3d_busy) + ret |= 0x00002000; + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; s3_virge_update_irqs(virge); break; + case 0x850c: + ret = virge->advfunc_cntl & 0x3f; + ret |= virge->fifo_slots_num << 6; + break; + case 0x8590: ret = virge->cmd_dma_base; break; @@ -1745,9 +1863,9 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) } static void -s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) +s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); if (((addr & 0xffff) >= 0x8590) || ((addr & 0xffff) < 0x8000)) { if ((addr & 0xffff) == 0xff20) { @@ -1807,14 +1925,17 @@ s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) case 0x83df: s3_virge_out(addr & 0x3ff, val, virge); break; + + default: + break; } } } static void -s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) +s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; s3_virge_log("[%04X:%08X]: MMIO WriteW addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffe, val); if (((addr & 0xfffe) >= 0x8590) || ((addr & 0xfffe) < 0x8000)) if ((addr & 0xfffe) == 0xff20) @@ -1830,9 +1951,9 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) } static void -s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) +s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); @@ -1873,40 +1994,40 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) break; case 0x81a0: virge->streams.blend_ctrl = val; + svga_recalctimings(svga); break; case 0x81c0: virge->streams.pri_fb0 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c4: virge->streams.pri_fb1 = val & 0x7fffff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81c8: virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81cc: virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d0: virge->streams.sec_fb0 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d4: virge->streams.sec_fb1 = val; - svga_recalctimings(svga); + s3_virge_update_buffer(virge); svga->fullchange = changeframecount; break; case 0x81d8: virge->streams.sec_stride = val; - svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81dc: @@ -1969,6 +2090,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->advfunc_cntl = val & 0xff; s3_virge_updatemapping(virge); break; + + default: + break; } } } @@ -2035,25 +2159,25 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; - uint32_t mono_pattern[64]; - int count_mask; - int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; - int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp; - int x_mul; - int cpu_dat_shift; - uint32_t *pattern_data; - uint32_t src_fg_clr; - uint32_t src_bg_clr; - uint32_t src_addr; - uint32_t dest_addr; - uint32_t source = 0; - uint32_t dest = 0; - uint32_t pattern; - uint32_t out = 0; - int update; + svga_t *svga = &virge->svga; + uint8_t *vram = virge->svga.vram; + uint32_t mono_pattern[64]; + int count_mask; + int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; + int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; + int bpp; + int x_mul; + int cpu_dat_shift; + const uint32_t *pattern_data; + uint32_t src_fg_clr; + uint32_t src_bg_clr; + uint32_t src_addr; + uint32_t dest_addr; + uint32_t source = 0; + uint32_t dest = 0; + uint32_t pattern; + uint32_t out = 0; + int update; switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { case CMD_SET_FORMAT_8: @@ -2185,6 +2309,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) cpu_dat <<= 1; count--; break; + + default: + break; } CLIP(virge->s3d.dest_x, virge->s3d.dest_y); @@ -2221,6 +2348,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) cpu_dat <<= (count - (count & count_mask)); count &= count_mask; break; + + default: + break; } if (!virge->s3d.h) { return; @@ -2393,6 +2523,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) case CMD_SET_COMMAND_NOP: break; + + default: + break; } } @@ -3024,7 +3157,10 @@ dest_pixel_lit_texture_reflection(s3d_state_t *state) static void dest_pixel_lit_texture_modulate(s3d_state_t *state) { - int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; + int r = state->r >> 7; + int g = state->g >> 7; + int b = state->b >> 7; + int a = state->a >> 7; tex_sample(state); @@ -3042,7 +3178,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { svga_t *svga = &virge->svga; - uint8_t *vram = (uint8_t *) svga->vram; + uint8_t *vram = svga->vram; int x_dir = s3d_tri->tlr ? 1 : -1; @@ -3236,6 +3372,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int case 7: src_z = (z >> 16); break; + + default: + break; } } @@ -3254,7 +3393,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { switch (bpp) { case 0: /*8 bpp*/ - /*Not implemented yet*/ + /*TODO: Not implemented yet*/ break; case 1: /*16 bpp*/ src_col = *(uint16_t *) &vram[dest_addr & virge->vram_mask]; @@ -3264,6 +3403,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int src_col = (*(uint32_t *) &vram[dest_addr & virge->vram_mask]) & 0xffffff; RGB24_TO_24(src_col, src_r, src_g, src_b); break; + + default: + break; } state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; @@ -3273,7 +3415,7 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int switch (bpp) { case 0: /*8 bpp*/ - /*Not implemented yet*/ + /*TODO: Not implemented yet*/ break; case 1: /*16 bpp*/ RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); @@ -3287,6 +3429,9 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int *(uint8_t *) &vram[(dest_addr + 2) & virge->vram_mask] = (dest_col >> 16) & 0xff; svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; break; + + default: + break; } } @@ -3372,7 +3517,7 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_w = s3d_tri->tws; tex_base = s3d_tri->tex_base; - for (uint8_t c = 9; c >= 0; c--) { + for (int c = 9; c >= 0; c--) { state.texture[c] = (uint16_t *) &virge->svga.vram[tex_base]; if (c <= state.max_d) tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; @@ -3453,6 +3598,9 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) else tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; break; + + default: + break; } switch ((s3d_tri->cmd_set >> 5) & 7) { @@ -3486,38 +3634,47 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) static void s3_virge_hwcursor_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *) svga->p; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg; - uint32_t bg; - uint32_t vram_mask = virge->vram_mask; + const virge_t *virge = (virge_t *) svga->priv; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg; + uint32_t bg; + uint32_t vram_mask = virge->vram_mask; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; switch (svga->bpp) { + default: + if (virge->chip != S3_VIRGEGX2) { + fg = svga->pallook[virge->hwc_fg_col & 0xff]; + bg = svga->pallook[virge->hwc_bg_col & 0xff]; + break; + } + fallthrough; + case 15: - fg = video_15to32[virge->hwc_fg_col & 0xffff]; - bg = video_15to32[virge->hwc_bg_col & 0xffff]; - break; + if (virge->chip != S3_VIRGEGX2) { + fg = video_15to32[virge->hwc_fg_col & 0xffff]; + bg = video_15to32[virge->hwc_bg_col & 0xffff]; + break; + } + fallthrough; case 16: - fg = video_16to32[virge->hwc_fg_col & 0xffff]; - bg = video_16to32[virge->hwc_bg_col & 0xffff]; - break; + if (virge->chip != S3_VIRGEGX2) { + fg = video_16to32[virge->hwc_fg_col & 0xffff]; + bg = video_16to32[virge->hwc_bg_col & 0xffff]; + break; + } + fallthrough; case 24: case 32: fg = virge->hwc_fg_col; bg = virge->hwc_bg_col; break; - - default: - fg = svga->pallook[virge->hwc_fg_col & 0xff]; - bg = svga->pallook[virge->hwc_bg_col & 0xff]; - break; } for (uint8_t x = 0; x < 64; x += 16) { @@ -3527,6 +3684,9 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) /*X11*/ for (xx = 0; xx < 16; xx++) { if (offset >= 0) { + if (virge->chip == S3_VIRGEGX2) + dat[0] ^= 0x8000; + if (dat[0] & 0x8000) buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; } @@ -3771,17 +3931,17 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) static void s3_virge_overlay_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *) svga->p; - int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; - int h_acc = virge->streams.dda_horiz_accumulator; - int r[8]; - int g[8]; - int b[8]; - int x_size; - int x_read = 4; - int x_write = 4; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + const virge_t *virge = (virge_t *) svga->priv; + int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; + int h_acc = virge->streams.dda_horiz_accumulator; + int r[8]; + int g[8]; + int b[8]; + int x_size; + int x_read = 4; + int x_write = 4; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; p = &(buffer32->line[displine][offset + svga->x_add]); @@ -3813,11 +3973,11 @@ s3_virge_overlay_draw(svga_t *svga, int displine) } static uint8_t -s3_virge_pci_read(int func, int addr, void *p) +s3_virge_pci_read(UNUSED(int func), int addr, void *priv) { - virge_t *virge = (virge_t *) p; - svga_t *svga = &virge->svga; - uint8_t ret = 0; + const virge_t *virge = (virge_t *) priv; + const svga_t *svga = &virge->svga; + uint8_t ret = 0; switch (addr) { case 0x00: @@ -3970,14 +4130,17 @@ s3_virge_pci_read(int func, int addr, void *p) case 0xe3: ret = virge->pci_regs[0xe3]; break; + + default: + break; } return ret; } static void -s3_virge_pci_write(int func, int addr, uint8_t val, void *p) +s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; switch (addr) { case 0x00: @@ -4053,6 +4216,9 @@ s3_virge_pci_write(int func, int addr, uint8_t val, void *p) case 0xe2: virge->pci_regs[0xe2] = val & 0xc0; return; + + default: + break; } } @@ -4086,24 +4252,29 @@ s3_virge_reset(void *priv) switch (virge->local) { case S3_VIRGE_325: case S3_DIAMOND_STEALTH3D_2000: + virge->fifo_slots_num = 8; virge->svga.crtc[0x59] = 0x70; break; case S3_DIAMOND_STEALTH3D_3000: case S3_STB_VELOCITY_3D: + virge->fifo_slots_num = 8; virge->svga.crtc[0x59] = 0x70; break; case S3_VIRGE_GX2: case S3_DIAMOND_STEALTH3D_4000: + virge->fifo_slots_num = 16; virge->svga.crtc[0x6c] = 1; virge->svga.crtc[0x59] = 0x70; break; case S3_TRIO_3D2X: + virge->fifo_slots_num = 16; virge->svga.crtc[0x6c] = 1; virge->svga.crtc[0x59] = 0x70; break; default: + virge->fifo_slots_num = 8; virge->svga.crtc[0x6c] = 1; virge->svga.crtc[0x59] = 0x70; break; @@ -4133,6 +4304,9 @@ s3_virge_reset(void *priv) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; + + default: + break; } if (virge->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); @@ -4209,9 +4383,9 @@ s3_virge_init(const device_t *info) if (bios_fn != NULL) { if (info->local == S3_VIRGE_GX2) - rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else - rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); } mem_mapping_disable(&virge->bios_rom.mapping); @@ -4262,6 +4436,7 @@ s3_virge_init(const device_t *info) switch (info->local) { case S3_VIRGE_325: case S3_DIAMOND_STEALTH3D_2000: + virge->fifo_slots_num = 8; virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x56; virge->virge_id_low = 0x31; @@ -4271,6 +4446,7 @@ s3_virge_init(const device_t *info) break; case S3_DIAMOND_STEALTH3D_3000: case S3_STB_VELOCITY_3D: + virge->fifo_slots_num = 8; virge->svga.decode_mask = (8 << 20) - 1; virge->virge_id_high = 0x88; virge->virge_id_low = 0x3d; @@ -4280,6 +4456,7 @@ s3_virge_init(const device_t *info) break; case S3_VIRGE_GX2: case S3_DIAMOND_STEALTH3D_4000: + virge->fifo_slots_num = 16; virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x10; @@ -4291,6 +4468,7 @@ s3_virge_init(const device_t *info) break; case S3_TRIO_3D2X: + virge->fifo_slots_num = 16; virge->svga.decode_mask = (8 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x13; @@ -4304,8 +4482,10 @@ s3_virge_init(const device_t *info) case S3_VIRGE_GX: virge->virge_rev = 0x01; - /*FALLTHROUGH*/ + fallthrough; + default: + virge->fifo_slots_num = 8; virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x01; @@ -4353,6 +4533,9 @@ s3_virge_init(const device_t *info) else virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; + + default: + break; } if (info->local == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); @@ -4361,7 +4544,10 @@ s3_virge_init(const device_t *info) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); + if (bios_fn == NULL) + pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot); + else + pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot); virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); @@ -4382,9 +4568,9 @@ s3_virge_init(const device_t *info) } static void -s3_virge_close(void *p) +s3_virge_close(void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; virge->render_thread_run = 0; thread_set_event(virge->wake_render_thread); @@ -4462,17 +4648,17 @@ s3_trio3d2x_available(void) } static void -s3_virge_speed_changed(void *p) +s3_virge_speed_changed(void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; svga_recalctimings(&virge->svga); } static void -s3_virge_force_redraw(void *p) +s3_virge_force_redraw(void *priv) { - virge_t *virge = (virge_t *) p; + virge_t *virge = (virge_t *) priv; virge->svga.fullchange = changeframecount; } diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index ee75d192d3..24ca4aeec0 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -28,8 +28,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct sc1148x_ramdac_t { int type; int state; int rs2; @@ -37,9 +36,9 @@ typedef struct } sc1148x_ramdac_t; void -sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); int oldbpp = 0; @@ -72,6 +71,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } else if (val == 0x00) svga->bpp = 8; break; + + default: + break; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -90,9 +92,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } uint8_t -sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; uint8_t ret = 0xff; uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 3a3b3a8638..7315c65add 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -29,86 +29,138 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct sc1502x_ramdac_t { int state; uint8_t ctrl; + uint8_t idx; + uint8_t regs[256]; + uint32_t pixel_mask; + uint8_t enable_ext; } sc1502x_ramdac_t; +static void +sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +{ + int oldbpp = 0; + if (val == 0xff) + return; + ramdac->ctrl = val; + oldbpp = svga->bpp; + switch ((val & 1) | ((val & 0xc0) >> 5)) { + case 0: + svga->bpp = 8; + break; + case 2: + case 3: + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + svga->bpp = 24; + break; + + default: + break; + } + break; + case 4: + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + if (val & 4) { + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + svga->bpp = 24; + break; + + default: + break; + } + } else + svga->bpp = 16; + break; + + default: + break; + } + if (oldbpp != svga->bpp) + svga_recalctimings(svga); +} + void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; - int oldbpp = 0; + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; switch (addr) { case 0x3C6: + if (ramdac->state == 0) + ramdac->enable_ext = (val == 0x10); + if (ramdac->state == 4) { ramdac->state = 0; - if (val == 0xFF) - break; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val & 1) | ((val & 0xc0) >> 5)) { - case 0: - svga->bpp = 8; - break; - case 2: - case 3: - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - } - break; - } else { - svga->bpp = 16; - break; - } - break; - } - if (oldbpp != svga->bpp) - svga_recalctimings(svga); + sc1502x_ramdac_bpp(val, ramdac, svga); return; } ramdac->state = 0; break; case 0x3C7: + if (ramdac->enable_ext) { + ramdac->idx = val; + return; + } + ramdac->state = 0; + break; case 0x3C8: + if (ramdac->enable_ext) { + switch (ramdac->idx) { + case 8: + ramdac->regs[ramdac->idx] = val; + svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; + case 0x0d: + ramdac->pixel_mask = val & svga->dac_mask; + break; + case 0x0e: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 8); + break; + case 0x0f: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); + break; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + return; + } + ramdac->state = 0; + break; case 0x3C9: + if (ramdac->enable_ext) + return; ramdac->state = 0; break; - } + default: + break; + } svga_out(addr, val, svga); } uint8_t -sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) +sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) { - sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; uint8_t temp = svga_in(addr, svga); switch (addr) { @@ -121,9 +173,47 @@ sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) ramdac->state++; break; case 0x3C7: + ramdac->state = 0; + break; case 0x3C8: + if (ramdac->enable_ext) { + switch (ramdac->idx) { + case 9: + temp = 0x53; + break; + case 0x0a: + temp = 0x3a; + break; + case 0x0b: + temp = 0xb1; + break; + case 0x0c: + temp = 0x41; + break; + case 0x0d: + temp = ramdac->pixel_mask & 0xff; + break; + case 0x0e: + temp = ramdac->pixel_mask >> 8; + break; + case 0x0f: + temp = ramdac->pixel_mask >> 16; + break; + default: + temp = ramdac->regs[ramdac->idx]; + break; + } + } else + ramdac->state = 0; + break; case 0x3C9: - ramdac->state = 0; + if (ramdac->enable_ext) + temp = ramdac->idx; + else + ramdac->state = 0; + break; + + default: break; } @@ -131,11 +221,14 @@ sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) } static void * -sc1502x_ramdac_init(const device_t *info) +sc1502x_ramdac_init(UNUSED(const device_t *info)) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); + ramdac->ctrl = 0; + ramdac->pixel_mask = 0xffffff; + return ramdac; } diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 1587bf0e03..83796506e2 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -44,10 +44,13 @@ enum { typedef struct sdac_ramdac_t { uint16_t regs[256]; - int magic_count, - windex, rindex, - reg_ff, rs2; - uint8_t type, command; + int magic_count; + int windex; + int rindex; + int reg_ff; + int rs2; + uint8_t type; + uint8_t command; } sdac_ramdac_t; static void @@ -59,8 +62,8 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) case ICS_5300: case ICS_5301: switch (val >> 5) { - case 0x00: default: + case 0x00: svga->bpp = 8; break; case 0x01: @@ -82,9 +85,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) case ICS_5341: case ICS_5342: switch (val >> 4) { + default: case 0x00: case 0x01: /* This is actually 8bpp with two pixels read at a time. */ - default: svga->bpp = 8; break; case 0x02: @@ -108,6 +111,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) break; } break; + + default: + break; } svga_recalctimings(svga); @@ -144,9 +150,9 @@ sdac_reg_read(sdac_ramdac_t *ramdac, int reg) } void -sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -184,13 +190,16 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) ramdac->rindex = val; ramdac->reg_ff = 0; break; + + default: + break; } } uint8_t -sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -237,19 +246,22 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) case 0x07: temp = ramdac->rindex; break; + + default: + break; } return temp; } float -sdac_getclock(int clock, void *p) +sdac_getclock(int clock, void *priv) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; - float t; - int m; - int n1; - int n2; + const sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; + float t; + int m; + int n1; + int n2; if (ramdac->regs[0xe] & (1 << 5)) clock = ramdac->regs[0xe] & 7; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 148dcc81c5..56f8b99aa6 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -29,6 +29,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/plat_unused.h> #define ROM_SIGMA_FONT "roms/video/sigma/sigma400_font.rom" #define ROM_SIGMA_BIOS "roms/video/sigma/sigma400_bios.rom" @@ -109,8 +110,8 @@ * 0x2DC: On write: Resets the NMI. * 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either: * - * > ROM: A 128 character 8x16 font for use in graphics modes - * > RAM: Use by the video BIOS to hold its settings. + * > ROM: A 128 character 8x16 font for use in graphics modes + * > RAM: Use by the video BIOS to hold its settings. * * Reading port 2DD switches to ROM. Bit 7 of the value read gives the * previous paging state: bit 7 set if ROM was paged, clear if RAM was @@ -192,9 +193,9 @@ static video_timings_t timing_sigma = { .type = VIDEO_ISA, .write_b = 8, .write_ static void sigma_recalctimings(sigma_t *cga); static void -sigma_out(uint16_t addr, uint8_t val, void *p) +sigma_out(uint16_t addr, uint8_t val, void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; uint8_t old; if (addr >= 0x3D0 && addr < 0x3E0) { @@ -256,14 +257,17 @@ sigma_out(uint16_t addr, uint8_t val, void *p) else sigma->plane = val & 3; return; + + default: + break; } } static uint8_t -sigma_in(uint16_t addr, void *p) +sigma_in(uint16_t addr, void *priv) { uint8_t result = 0xFF; - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; switch (addr) { case 0x2D0: @@ -326,33 +330,37 @@ sigma_in(uint16_t addr, void *p) result = sigma->fake_stat; } break; + + default: + break; } return result; } static void -sigma_write(uint32_t addr, uint8_t val, void *p) +sigma_write(uint32_t addr, uint8_t val, void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val; cycles -= 4; } static uint8_t -sigma_read(uint32_t addr, void *p) +sigma_read(uint32_t addr, void *priv) { - sigma_t *sigma = (sigma_t *) p; + const sigma_t *sigma = (sigma_t *) priv; cycles -= 4; + return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; } static void -sigma_bwrite(uint32_t addr, uint8_t val, void *p) +sigma_bwrite(uint32_t addr, uint8_t val, void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; addr &= 0x3FFF; if ((addr < 0x1800) || sigma->rom_paged || (addr >= 0x2000)) @@ -362,10 +370,10 @@ sigma_bwrite(uint32_t addr, uint8_t val, void *p) } static uint8_t -sigma_bread(uint32_t addr, void *p) +sigma_bread(uint32_t addr, void *priv) { - sigma_t *sigma = (sigma_t *) p; - uint8_t result; + const sigma_t *sigma = (sigma_t *) priv; + uint8_t result; addr &= 0x3FFF; if (addr >= 0x2000) @@ -404,13 +412,13 @@ sigma_recalctimings(sigma_t *sigma) static void sigma_text80(sigma_t *sigma) { - uint8_t chr; - uint8_t attr; - uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; - uint32_t cols[4]; - uint8_t *vram = sigma->vram + (ma << 1); + uint8_t chr; + uint8_t attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + const uint8_t *vram = sigma->vram + (ma << 1); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) @@ -459,13 +467,13 @@ sigma_text80(sigma_t *sigma) static void sigma_text40(sigma_t *sigma) { - uint8_t chr; - uint8_t attr; - uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; - uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + uint8_t chr; + uint8_t attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + const uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) @@ -508,7 +516,7 @@ sigma_text40(sigma_t *sigma) static void sigma_gfx400(sigma_t *sigma) { - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000]; + const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000]; uint8_t plane[4]; uint8_t col; @@ -536,7 +544,7 @@ sigma_gfx400(sigma_t *sigma) static void sigma_gfx200(sigma_t *sigma) { - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; uint8_t plane[4]; uint8_t col; @@ -561,7 +569,7 @@ sigma_gfx200(sigma_t *sigma) static void sigma_gfx4col(sigma_t *sigma) { - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; uint8_t plane[4]; uint8_t mask; uint8_t col; @@ -589,9 +597,9 @@ sigma_gfx4col(sigma_t *sigma) } static void -sigma_poll(void *p) +sigma_poll(void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; int x; int c; int oldvc; @@ -772,12 +780,12 @@ sigma_poll(void *p) } } -static void - * - sigma_init(const device_t *info) +static void * +sigma_init(UNUSED(const device_t *info)) { int bios_addr; sigma_t *sigma = malloc(sizeof(sigma_t)); + memset(sigma, 0, sizeof(sigma_t)); bios_addr = device_get_config_hex20("bios_addr"); @@ -833,18 +841,18 @@ sigma_available(void) } static void -sigma_close(void *p) +sigma_close(void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; free(sigma->vram); free(sigma); } void -sigma_speed_changed(void *p) +sigma_speed_changed(void *priv) { - sigma_t *sigma = (sigma_t *) p; + sigma_t *sigma = (sigma_t *) priv; sigma_recalctimings(sigma); } diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index d235477c92..187139b3ba 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -27,6 +27,7 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> typedef struct stg_ramdac_t { int magic_count, index; @@ -45,10 +46,10 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { if (ramdac->command & 0x8) { switch (ramdac->regs[3]) { + default: case 0: case 5: case 7: - default: svga->bpp = 8; break; case 1: @@ -67,8 +68,8 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) } } else { switch (ramdac->command >> 5) { - case 0: default: + case 0: svga->bpp = 8; break; case 5: @@ -87,9 +88,9 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) } void -stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +stg_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - stg_ramdac_t *ramdac = (stg_ramdac_t *) p; + stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; int didwrite; int old; @@ -125,6 +126,9 @@ stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) stg_ramdac_set_bpp(svga, ramdac); ramdac->index++; break; + + default: + break; } didwrite = (ramdac->magic_count >= 4); ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; @@ -136,15 +140,18 @@ stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x3c9: ramdac->magic_count = 0; break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) +stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga) { - stg_ramdac_t *ramdac = (stg_ramdac_t *) p; + stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; uint8_t temp = 0xff; switch (addr) { @@ -185,6 +192,9 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) } ramdac->index++; break; + + default: + break; } ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; return temp; @@ -193,20 +203,23 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) case 0x3c9: ramdac->magic_count = 0; break; + + default: + break; } return svga_in(addr, svga); } float -stg_getclock(int clock, void *p) +stg_getclock(int clock, void *priv) { - stg_ramdac_t *ramdac = (stg_ramdac_t *) p; - float t; - int m; - int n; - int n2; - uint16_t *c; + stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; + float t; + int m; + int n; + int n2; + const uint16_t *c; if (clock == 0) return 25175000.0; @@ -225,7 +238,7 @@ stg_getclock(int clock, void *p) } static void * -stg_ramdac_init(const device_t *info) +stg_ramdac_init(UNUSED(const device_t *info)) { stg_ramdac_t *ramdac = (stg_ramdac_t *) malloc(sizeof(stg_ramdac_t)); memset(ramdac, 0, sizeof(stg_ramdac_t)); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d8829eb2f7..b203646898 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -39,8 +39,11 @@ #include <86box/plat.h> #include <86box/ui.h> #include <86box/video.h> +#include <86box/vid_8514a.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_xga_device.h> void svga_doblit(int wx, int wy, svga_t *svga); @@ -55,7 +58,6 @@ uint8_t svga_rotate[8][256]; only SVGA device.*/ static svga_t *svga_pri; int vga_on; -int ibm8514_on; #ifdef ENABLE_SVGA_LOG int svga_do_log = ENABLE_SVGA_LOG; @@ -90,12 +92,10 @@ svga_set_override(svga_t *svga, int val) if (!val) { /* Override turned off, restore overscan X and Y per the CRTC. */ - if (enable_overscan) { - svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; + svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; - if (svga->monitor->mon_overscan_y < 16) - svga->monitor->mon_overscan_y = 16; - } + if (svga->monitor->mon_overscan_y < 16) + svga->monitor->mon_overscan_y = 16; svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; @@ -107,17 +107,62 @@ svga_set_override(svga_t *svga, int val) } void -svga_out(uint16_t addr, uint8_t val, void *p) +svga_out(uint16_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - uint8_t o; - uint8_t index; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; + uint8_t o; + uint8_t index; + uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; + + if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) + return; switch (addr) { + case 0x2ea: + dev->dac_mask = val; + break; + case 0x2eb: + case 0x2ec: + dev->dac_pos = 0; + dev->dac_status = addr & 0x03; + dev->dac_addr = (val + (addr & 0x01)) & 0xff; + break; + case 0x2ed: + svga->fullchange = svga->monitor->mon_changeframecount; + switch (dev->dac_pos) { + case 0: + dev->dac_r = val; + dev->dac_pos++; + break; + case 1: + dev->dac_g = val; + dev->dac_pos++; + break; + case 2: + index = dev->dac_addr & 0xff; + dev->dac_b = val; + svga->vgapal[index].r = dev->dac_r; + svga->vgapal[index].g = dev->dac_g; + svga->vgapal[index].b = dev->dac_b; + if (svga->ramdac_type == RAMDAC_8BIT) + dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + else + dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + dev->dac_pos = 0; + dev->dac_addr = (dev->dac_addr + 1) & 0xff; + break; + + default: + break; + } + break; + case 0x3c0: case 0x3c1: if (!svga->attrff) { - svga->attraddr = val & 31; + svga->attraddr = val & 0x1f; if ((val & 0x20) != svga->attr_palette_enable) { svga->fullchange = 3; svga->attr_palette_enable = val & 0x20; @@ -126,17 +171,19 @@ svga_out(uint16_t addr, uint8_t val, void *p) } else { if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) svga->fullchange = svga->monitor->mon_changeframecount; - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) + o = svga->attrregs[svga->attraddr & 0x1f]; + svga->attrregs[svga->attraddr & 0x1f] = val; + if (svga->attraddr < 0x10) svga->fullchange = svga->monitor->mon_changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (uint8_t c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) { + + if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) { + for (int c = 0; c < 0x10; c++) { + if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - } else { + else if (svga->ati_4color) + svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)]; + else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } } svga->fullchange = svga->monitor->mon_changeframecount; } @@ -160,9 +207,21 @@ svga_out(uint16_t addr, uint8_t val, void *p) case 0x3c2: svga->miscout = val; svga->vidclock = val & 4; - io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); + svga_recalctimings(svga); + break; + case 0x3c3: + if (xga_active && xga) + xga->on = (val & 0x01) ? 0 : 1; + if (ibm8514_active && dev) { + dev->on[0] = (val & 0x01) ? 0 : 1; + dev->on[1] = dev->on[0]; + } + + svga_log("3C3: VGA ON = %d.\n", val & 0x01); + vga_on = val & 0x01; svga_recalctimings(svga); break; case 0x3c4: @@ -195,24 +254,23 @@ svga_out(uint16_t addr, uint8_t val, void *p) break; case 4: svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; + svga->chain4 = (svga->chain4 & ~8) | (val & 8); svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); break; + + default: + break; } break; - case 0x2ea: case 0x3c6: svga->dac_mask = val; break; - case 0x2eb: - case 0x2ec: case 0x3c7: case 0x3c8: svga->dac_pos = 0; svga->dac_status = addr & 0x03; svga->dac_addr = (val + (addr & 0x01)) & 255; break; - case 0x2ed: case 0x3c9: if (svga->adv_flags & FLAG_RAMDAC_SHIFT) val <<= 2; @@ -228,9 +286,10 @@ svga_out(uint16_t addr, uint8_t val, void *p) break; case 2: index = svga->dac_addr & 255; + svga->dac_b = val; svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; - svga->vgapal[index].b = val; + svga->vgapal[index].b = svga->dac_b; if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); else @@ -238,6 +297,9 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga->dac_pos = 0; svga->dac_addr = (svga->dac_addr + 1) & 255; break; + + default: + break; } break; case 0x3ce: @@ -276,29 +338,85 @@ svga_out(uint16_t addr, uint8_t val, void *p) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } break; case 7: svga->colournocare = val; break; + + default: + break; } svga->gdcreg[svga->gdcaddr & 15] = val; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); break; + case 0x3da: + svga->fcr = val; + break; + + default: + break; } } uint8_t -svga_in(uint16_t addr, void *p) +svga_in(uint16_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - uint8_t index; - uint8_t ret = 0xff; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t index; + uint8_t ret = 0xff; + + if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) + return ret; switch (addr) { + case 0x2ea: + ret = dev->dac_mask; + break; + case 0x2eb: + ret = dev->dac_status; + break; + case 0x2ec: + ret = dev->dac_addr; + break; + case 0x2ed: + index = (dev->dac_addr - 1) & 0xff; + switch (dev->dac_pos) { + case 0: + dev->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].r; + else + ret = svga->vgapal[index].r & 0x3f; + break; + case 1: + dev->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].g; + else + ret = svga->vgapal[index].g & 0x3f; + break; + case 2: + dev->dac_pos = 0; + dev->dac_addr = (dev->dac_addr + 1) & 0xff; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].b; + else + ret = svga->vgapal[index].b & 0x3f; + break; + + default: + break; + } + break; + case 0x3c0: ret = svga->attraddr | svga->attr_palette_enable; break; @@ -311,25 +429,24 @@ svga_in(uint16_t addr, void *p) else ret = 0x10; break; + case 0x3c3: + ret = vga_on; + break; case 0x3c4: ret = svga->seqaddr; break; case 0x3c5: ret = svga->seqregs[svga->seqaddr & 0x0f]; break; - case 0x2ea: case 0x3c6: ret = svga->dac_mask; break; - case 0x2eb: case 0x3c7: ret = svga->dac_status; break; - case 0x2ec: case 0x3c8: ret = svga->dac_addr; break; - case 0x2ed: case 0x3c9: index = (svga->dac_addr - 1) & 255; switch (svga->dac_pos) { @@ -355,10 +472,16 @@ svga_in(uint16_t addr, void *p) else ret = svga->vgapal[index].b & 0x3f; break; + + default: + break; } if (svga->adv_flags & FLAG_RAMDAC_SHIFT) ret >>= 2; break; + case 0x3ca: + ret = svga->fcr; + break; case 0x3cc: ret = svga->miscout; break; @@ -395,6 +518,11 @@ svga_in(uint16_t addr, void *p) ret = svga->cgastat; + if ((svga->fcr & 0x08) && svga->dispon) + ret |= 0x08; + break; + + default: break; } @@ -404,10 +532,29 @@ svga_in(uint16_t addr, void *p) void svga_set_ramdac_type(svga_t *svga, int type) { + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; + if (svga->ramdac_type != type) { svga->ramdac_type = type; - for (uint16_t c = 0; c < 256; c++) { + for (int c = 0; c < 256; c++) { + if (ibm8514_active && dev) { + if (svga->ramdac_type == RAMDAC_8BIT) + dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } + if (xga_active && xga) { + if (svga->ramdac_type == RAMDAC_8BIT) + xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + xga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else @@ -421,10 +568,23 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - double crtcconst; - double _dispontime; - double _dispofftime; - double disptime; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + double crtcconst; + double _dispontime; + double _dispofftime; + double disptime; + double crtcconst8514 = 0.0; + double _dispontime8514 = 0.0; + double _dispofftime8514 = 0.0; + double disptime8514 = 0.0; +#ifdef ENABLE_SVGA_LOG + int vsyncend; + int vblankend; + int hdispstart; + int hdispend; + int hsyncstart; + int hsyncend; +#endif svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -462,100 +622,114 @@ svga_recalctimings(svga_t *svga) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp = svga->crtc[1]; svga->hdisp++; svga->htotal = svga->crtc[0]; /* +5 has been verified by Sergi to be correct - +6 must have been an off by one error. */ - svga->htotal += 5; /*+6 is required for Tyrian*/ + svga->htotal += 5; /*+5 is required for Tyrian*/ svga->rowoffset = svga->crtc[0x13]; svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; - svga->lowres = svga->attrregs[0x10] & 0x40; + svga->lowres = !!(svga->attrregs[0x10] & 0x40); svga->interlace = 0; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; + svga->rowcount = svga->crtc[9] & 0x1f; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + if (svga->seqregs[1] & 8) + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } else { + if (svga->seqregs[1] & 8) + svga->hdisp *= 16; + else + svga->hdisp *= 8; + } + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - /* Character clock is off by 1 now in 40-line modes, on all cards. */ - svga->ma_latch--; - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; } else { svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; } svga->hdisp_old = svga->hdisp; } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - switch (svga->gdcreg[5] & 0x60) { - case 0x00: + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { + if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ + } else if ((svga->gdcreg[5] & 0x60) == 0x20) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_2bpp_lowres; else svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 17: - if (svga->lowres) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_mix_highres; - break; - case 24: - if (svga->lowres) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; + } else { + svga->map8 = svga->pallook; + if (svga->lowres) /*Low res (320)*/ + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + } + } else { + switch (svga->gdcreg[5] & 0x60) { + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 17: + if (svga->lowres) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_mix_highres; + break; + case 24: + if (svga->lowres) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; + + default: + break; + } + break; + + default: + break; + } } } } @@ -563,12 +737,10 @@ svga_recalctimings(svga_t *svga) svga->linedbl = svga->crtc[9] & 0x80; svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; - if (enable_overscan) { - svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; + svga->monitor->mon_overscan_y = (svga->rowcount + 1) << 1; - if (svga->monitor->mon_overscan_y < 16) - svga->monitor->mon_overscan_y = 16; - } + if (svga->monitor->mon_overscan_y < 16) + svga->monitor->mon_overscan_y = 16; if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { svga->monitor->mon_overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; @@ -578,28 +750,160 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - if (vga_on) { - if (svga->recalctimings_ex) { - svga->recalctimings_ex(svga); + svga->hblankstart = svga->crtc[2]; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); + svga->hblank_end_mask = 0x0000003f; + + svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", + svga->htotal, svga->hblankstart, svga->hblank_end_val); + + if (!svga->scrblank && svga->attr_palette_enable) { + /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + if (svga->seqregs[1] & 8) + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); + else + svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9); + } else { + if (svga->seqregs[1] & 8) + svga->dots_per_clock = 16; + else + svga->dots_per_clock = 8; } - } else { - if (ibm8514_enabled) + } else + svga->dots_per_clock = 1; + + svga->multiplier = 1.0; + + if (svga->recalctimings_ex) + svga->recalctimings_ex(svga); + + if (ibm8514_active && (svga->dev8514 != NULL)) { + if ((dev->local & 0xff) == 0x00) ibm8514_recalctimings(svga); - if (xga_enabled) - xga_recalctimings(svga); } - svga->y_add = (svga->monitor->mon_overscan_y >> 1) - (svga->crtc[8] & 0x1f); + if (xga_active && (svga->xga != NULL)) + xga_recalctimings(svga); + + if (!svga->hoverride) { + uint32_t dot = svga->hblankstart; + uint32_t adj_dot = svga->hblankstart; + /* Verified with both the Voodoo 3 and the S3 cards: compare 7 bits if bit 7 is set, + otherwise compare 6 bits. */ + uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f; + svga->hblank_sub = 0; + + svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, svga->hblankstart, svga->hblank_end_val, + svga->htotal, eff_mask, adj_dot); + + while (adj_dot < (svga->htotal << 1)) { + if (dot == svga->htotal) + dot = 0; + + if (adj_dot >= svga->htotal) + svga->hblank_sub++; + + svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, svga->hblank_end_val); + if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask)) + break; + + dot++; + adj_dot++; + } + + svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + } + +#ifdef TBD + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; + + while (adj_dot8514 < (dev->h_total << 1)) { + if (dot8514 == dev->h_total) + dot8514 = 0; + + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; + + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; + + dot8514++; + adj_dot8514++; + } + + dev->h_disp -= dev->hblank_sub; + } + } +#endif + + if (svga->hdisp >= 2048) + svga->monitor->mon_overscan_x = 0; + + svga->y_add = (svga->monitor->mon_overscan_y >> 1); svga->x_add = (svga->monitor->mon_overscan_x >> 1); if (svga->vblankstart < svga->dispend) svga->dispend = svga->vblankstart; crtcconst = svga->clock * svga->char_width; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) + crtcconst8514 = svga->clock8514; + } + +#ifdef ENABLE_SVGA_LOG + vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); + if (vsyncend <= svga->vsyncstart) + vsyncend += 0x00000010; + vblankend = (svga->vblankstart & 0xffffff80) | (svga->crtc[0x16] & 0x7f); + if (vblankend <= svga->vblankstart) + vblankend += 0x00000080; + + hdispstart = ((svga->crtc[3] >> 5) & 3); + hdispend = svga->crtc[1] + 1; + hsyncstart = svga->crtc[4] + ((svga->crtc[5] >> 5) & 3) + 1; + hsyncend = (hsyncstart & 0xffffffe0) | (svga->crtc[5] & 0x1f); + if (hsyncend <= hsyncstart) + hsyncend += 0x00000020; +#endif - disptime = svga->htotal; + svga_log("Last scanline in the vertical period: %i\n" + "First scanline after the last of active display: %i\n" + "First scanline with vertical retrace asserted: %i\n" + "First scanline after the last with vertical retrace asserted: %i\n" + "First scanline of blanking: %i\n" + "First scanline after the last of blanking: %i\n" + "\n" + "Last character in the horizontal period: %i\n" + "First character of active display: %i\n" + "First character after the last of active display: %i\n" + "First character with horizontal retrace asserted: %i\n" + "First character after the last with horizontal retrace asserted: %i\n" + "First character of blanking: %i\n" + "First character after the last of blanking: %i\n" + "\n" + "\n", + svga->vtotal, svga->dispend, svga->vsyncstart, vsyncend, + svga->vblankstart, vblankend, + svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, + svga->hblankstart, svga->hblankend); + + disptime = svga->htotal * svga->multiplier; _dispontime = svga->hdisp_time; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC; + _dispontime8514 = dev->hdisped; + } + } + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; @@ -616,12 +920,42 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on[0] || dev->on[1]) { + _dispofftime8514 = disptime8514 - _dispontime8514; + _dispontime8514 *= crtcconst8514; + _dispofftime8514 *= crtcconst8514; + + dev->dispontime = (uint64_t) (_dispontime8514); + dev->dispofftime = (uint64_t) (_dispofftime8514); + if (dev->dispontime < TIMER_USEC) + dev->dispontime = TIMER_USEC; + if (dev->dispofftime < TIMER_USEC) + dev->dispofftime = TIMER_USEC; + + timer_disable(&svga->timer); + timer_set_delay_u64(&svga->timer8514, TIMER_USEC); + } else { + timer_disable(&svga->timer8514); + timer_set_delay_u64(&svga->timer, TIMER_USEC); + } + } + if (!svga->force_old_addr) svga_recalc_remap_func(svga); /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { if (!svga->dpms_ui) { + /* Make sure to black out the entire screen to avoid lingering image. */ + int y_add = enable_overscan ? svga->monitor->mon_overscan_y : 0; + int x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; + int y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); + int x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); + video_wait_for_buffer_monitor(svga->monitor_index); + memset(svga->monitor->target_buffer->dat, 0, svga->monitor->target_buffer->w * svga->monitor->target_buffer->h * 4); + video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); + video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; ui_sb_set_text_w(plat_get_string(IDS_2143)); } @@ -659,7 +993,7 @@ svga_do_render(svga_t *svga) if (svga->dac_hwcursor_on) { if (!svga->override && svga->dac_hwcursor_draw) - svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); + svga->dac_hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->dac_hwcursor_latch.y >= 0) ? 0 : svga->dac_hwcursor_latch.y)) & 2047); svga->dac_hwcursor_on--; if (svga->dac_hwcursor_on && svga->interlace) svga->dac_hwcursor_on--; @@ -667,7 +1001,7 @@ svga_do_render(svga_t *svga) if (svga->hwcursor_on) { if (!svga->override && svga->hwcursor_draw) - svga->hwcursor_draw(svga, svga->displine + svga->y_add); + svga->hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->hwcursor_latch.y >= 0) ? 0 : svga->hwcursor_latch.y)) & 2047); svga->hwcursor_on--; if (svga->hwcursor_on && svga->interlace) svga->hwcursor_on--; @@ -675,42 +1009,44 @@ svga_do_render(svga_t *svga) } void -svga_poll(void *p) +svga_poll(void *priv) { - svga_t *svga = (svga_t *) p; - uint32_t x; - uint32_t blink_delay; - int wx; - int wy; - int ret; - int old_ma; - - if (!vga_on && ibm8514_enabled && ibm8514_on) { - ibm8514_poll(&svga->dev8514, svga); - return; - } else if (!vga_on && xga_enabled && svga->xga.on) { - xga_poll(&svga->xga, svga); - return; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint32_t x; + uint32_t blink_delay; + int wx; + int wy; + int ret; + int old_ma; + + if (!svga->override) { + if (xga_active && xga && xga->on) { + if ((xga->disp_cntl_2 & 7) >= 2) { + xga_poll(xga, svga); + return; + } + } } if (!svga->linepos) { - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff; + if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) { + svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff; svga->hwcursor_oddeven = 0; } - if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1); + if (svga->displine == (((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) + 1) && svga->hwcursor_latch.ena && svga->interlace) { + svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1); svga->hwcursor_oddeven = 1; } - if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff; + if (svga->displine == ((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) && svga->dac_hwcursor_latch.ena) { + svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff; svga->dac_hwcursor_oddeven = 0; } - if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); + if (svga->displine == (((svga->dac_hwcursor_latch.y < 0) ? 0 : svga->dac_hwcursor_latch.y) + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { + svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); svga->dac_hwcursor_oddeven = 1; } @@ -770,7 +1106,7 @@ svga_poll(void *p) if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) svga->cgastat &= ~8; svga->vslines++; - if (svga->displine > 1500) + if (svga->displine > 2000) svga->displine = 0; } else { timer_advance_u64(&svga->timer, svga->dispontime); @@ -783,6 +1119,8 @@ svga_poll(void *p) if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) svga->con = 0; if (svga->dispon) { + /* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll + - S3 Trio64V2/DX: sc == rowcount, wrapping 5-bit counter. */ if (svga->linedbl && !svga->linecountff) { svga->linecountff = 1; svga->ma = svga->maback; @@ -793,23 +1131,24 @@ svga_poll(void *p) svga->maback += (svga->rowoffset << 3); if (svga->interlace) svga->maback += (svga->rowoffset << 3); + svga->maback &= svga->vram_display_mask; svga->ma = svga->maback; } else { svga->linecountff = 0; svga->sc++; - svga->sc &= 31; + svga->sc &= 0x1f; svga->ma = svga->maback; } } - svga->hsync_divisor = !svga->hsync_divisor; + svga->hsync_divisor ^= 1; if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) return; svga->vc++; - svga->vc &= 2047; + svga->vc &= 0x7ff; if (svga->vc == svga->split) { ret = 1; @@ -819,9 +1158,9 @@ svga_poll(void *p) if (ret) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = svga->hblank_sub; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -835,6 +1174,7 @@ svga_poll(void *p) if (svga->vc == svga->dispend) { if (svga->vblank_start) svga->vblank_start(svga); + svga->dispon = 0; blink_delay = (svga->crtc[11] & 0x60) >> 5; if (svga->crtc[10] & 0x20) @@ -844,8 +1184,9 @@ svga_poll(void *p) else svga->cursoron = svga->blink & (16 + (16 * blink_delay)); - if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) + if (!(svga->blink & 15)) svga->fullchange = 2; + svga->blink = (svga->blink + 1) & 0x7f; for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { @@ -886,14 +1227,14 @@ svga_poll(void *p) svga->oddeven ^= 1; svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2; - svga->vslines = 0; + svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; + svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); svga->ca = (svga->ca << 2); @@ -901,30 +1242,31 @@ svga_poll(void *p) if (svga->vsync_callback) svga->vsync_callback(svga); } +#if 0 + if (svga->vc == lines_num) { +#endif if (svga->vc == svga->vtotal) { svga->vc = 0; - svga->sc = 0; + svga->sc = (svga->crtc[0x8] & 0x1f); svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - if (!ibm8514_on) { - svga->scrollcache = (svga->attrregs[0x13] & 0x0f); - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 1) - svga->scrollcache &= 0x07; - else { - svga->scrollcache++; - if (svga->scrollcache > 8) - svga->scrollcache = 0; - } - } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) svga->scrollcache &= 0x07; - else - svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + svga->scrollcache &= 0x07; + else + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) - svga->scrollcache <<= 1; - } + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache; @@ -944,23 +1286,29 @@ svga_poll(void *p) } } +uint32_t +svga_conv_16to32(struct svga_t *svga, uint16_t color, uint8_t bpp) +{ + return (bpp == 15) ? video_15to32[color] : video_16to32[color]; +} + int -svga_init(const device_t *info, svga_t *svga, void *p, int memsize, +svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in)(uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), + uint8_t (*video_in)(uint16_t addr, void *priv), + void (*video_out)(uint16_t addr, uint8_t val, void *priv), void (*hwcursor_draw)(struct svga_t *svga, int displine), void (*overlay_draw)(struct svga_t *svga, int displine)) { int e; - svga->p = p; + svga->priv = priv; svga->monitor_index = monitor_index_global; - svga->monitor = &monitors[svga->monitor_index]; + svga->monitor = &monitors[svga->monitor_index]; - for (uint16_t c = 0; c < 256; c++) { + for (int c = 0; c < 256; c++) { e = c; - for (uint8_t d = 0; d < 8; d++) { + for (int d = 0; d < 8; d++) { svga_rotate[d][c] = e; e = (e >> 1) | ((e & 1) ? 0x80 : 0); } @@ -970,10 +1318,10 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->attrregs[0x11] = 0; svga->overscan_color = 0x000000; - svga->monitor->mon_overscan_x = 16; - svga->monitor->mon_overscan_y = 32; - svga->x_add = 8; - svga->y_add = 16; + svga->monitor->mon_overscan_x = 16; + svga->monitor->mon_overscan_y = 32; + svga->x_add = 8; + svga->y_add = 16; svga->crtc[0] = 63; svga->crtc[6] = 255; @@ -990,6 +1338,7 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->video_out = video_out; svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; + svga->conv_16to32 = svga_conv_16to32; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; @@ -1023,7 +1372,7 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->ramdac_type = RAMDAC_6BIT; - svga->map8 = svga->pallook; + svga->map8 = svga->pallook; return 0; } @@ -1068,28 +1417,24 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - else { - if (write) - addr += svga->write_bank; - else - addr += svga->read_bank; - } + if (write) + addr += svga->write_bank; + else + addr += svga->read_bank; } return addr; } static __inline void -svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) +svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; - + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; int writemask2 = svga->writemask; - int reset_wm = 0; + int reset_wm = 0; latch_t vall; - uint8_t wm = svga->writemask; + uint8_t wm = svga->writemask; uint8_t count; uint8_t i; @@ -1099,24 +1444,38 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) cycles -= svga->monitor->mon_video_timing_write_b; if (!linear) { - if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ - svga->xga.test = val; - svga->xga.a5_test = 1; + xga->test = val; + if (addr == 0xa0001) + xga->a5_test = 1; + else if (addr == 0xafffe) + xga->a5_test = 2; + + xga->on = 0; + vga_on = 1; + xga->disp_cntl_2 = 0; + svga_log("XGA test1 addr = %05x.\n", addr); return; } else if (val == 0x5a) { - svga->xga.test = val; + xga->test = val; + xga->on = 0; + vga_on = 1; + xga->disp_cntl_2 = 0; + svga_log("XGA test2 addr = %05x.\n", addr); return; - } else if (val == 0x12 || val == 0x34) { - addr += svga->xga.write_bank; - svga->xga.vram[addr & svga->xga.vram_mask] = val; - svga->xga.linear_endian_reverse = 1; + } else if ((addr == 0xa0000) || (addr == 0xa0010)) { + addr += xga->write_bank; + xga->vram[addr & xga->vram_mask] = val; + svga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x.\n", val, addr, svga->banked_mask); + if (!xga->a5_test) + xga->linear_endian_reverse = 1; return; } } else { - svga->xga.on = 0; - vga_on = !svga->xga.on; + xga->on = 0; + vga_on = 1; } } addr = svga_decode_addr(svga, addr, 1); @@ -1152,7 +1511,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) addr &= svga->decode_mask; if (svga->translate_address) - addr = svga->translate_address(addr, p); + addr = svga->translate_address(addr, priv); if (addr >= svga->vram_max) return; @@ -1280,6 +1639,9 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) } } break; + + default: + break; } if (reset_wm) @@ -1287,9 +1649,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) } static __inline uint8_t -svga_read_common(uint32_t addr, uint8_t linear, void *p) +svga_read_common(uint32_t addr, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint32_t latch_addr = 0; int readplane = svga->readplane; uint8_t count; @@ -1302,23 +1665,37 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) cycles -= svga->monitor->mon_video_timing_read_b; if (!linear) { - if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { - if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ - svga->xga.on = 1; - vga_on = !svga->xga.on; - return svga->xga.test; - } else if (svga->xga.test == 0x5a) { - svga->xga.on = 1; - vga_on = !svga->xga.on; - return svga->xga.test; - } else if (addr == 0xa0000 || addr == 0xa0010) { - addr += svga->xga.read_bank; - return svga->xga.vram[addr & svga->xga.vram_mask]; + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { + if (xga->test == 0xa5) { /*Memory size test of XGA*/ + if (addr == 0xa0001) { + ret = xga->test; + xga->on = 1; + vga_on = 0; + } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ + svga_log("A5 test bank = %x.\n", addr); + addr += xga->read_bank; + ret = xga->vram[addr & xga->vram_mask]; + } else { + ret = xga->test; + xga->on = 1; + vga_on = 0; + } + svga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test); + return ret; + } else if (xga->test == 0x5a) { + ret = xga->test; + xga->on = 1; + vga_on = 0; + svga_log("5A read: XGA ON = %d.\n", xga->on); + return ret; + } else if ((addr == 0xa0000) || (addr == 0xa0010)) { + addr += xga->read_bank; + return xga->vram[addr & xga->vram_mask]; } } else { - svga->xga.on = 0; - vga_on = !svga->xga.on; + xga->on = 0; + vga_on = 1; } } addr = svga_decode_addr(svga, addr, 0); @@ -1341,7 +1718,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) else if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { addr &= svga->decode_mask; if (svga->translate_address) - addr = svga->translate_address(addr, p); + addr = svga->translate_address(addr, priv); if (addr >= svga->vram_max) return 0xff; latch_addr = (addr & svga->vram_mask) & ~3; @@ -1359,9 +1736,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr <<= 2; addr &= svga->decode_mask; + if (svga->translate_address) { - latch_addr = svga->translate_address(latch_addr, p); - addr = svga->translate_address(addr, p); + latch_addr = svga->translate_address(latch_addr, priv); + addr = svga->translate_address(addr, priv); } /* standard VGA latched access */ @@ -1401,27 +1779,27 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) } void -svga_write(uint32_t addr, uint8_t val, void *p) +svga_write(uint32_t addr, uint8_t val, void *priv) { - svga_write_common(addr, val, 0, p); + svga_write_common(addr, val, 0, priv); } void -svga_write_linear(uint32_t addr, uint8_t val, void *p) +svga_write_linear(uint32_t addr, uint8_t val, void *priv) { - svga_write_common(addr, val, 1, p); + svga_write_common(addr, val, 1, priv); } uint8_t -svga_read(uint32_t addr, void *p) +svga_read(uint32_t addr, void *priv) { - return svga_read_common(addr, 0, p); + return svga_read_common(addr, 0, priv); } uint8_t -svga_read_linear(uint32_t addr, void *p) +svga_read_linear(uint32_t addr, void *priv) { - return svga_read_common(addr, 1, p); + return svga_read_common(addr, 1, priv); } void @@ -1442,7 +1820,7 @@ svga_doblit(int wx, int wy, svga_t *svga) x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); - bottom = (svga->monitor->mon_overscan_y >> 1) + (svga->crtc[8] & 0x1f); + bottom = (svga->monitor->mon_overscan_y >> 1); if (svga->vertical_linedbl) { y_add <<= 1; @@ -1494,14 +1872,14 @@ svga_doblit(int wx, int wy, svga_t *svga) p = &svga->monitor->target_buffer->line[i & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } for (i = 0; i < bottom; i++) { p = &svga->monitor->target_buffer->line[(svga->monitor->mon_ysize + svga->y_add + i) & 0x7ff][0]; for (j = 0; j < (svga->monitor->mon_xsize + x_add); j++) - p[j] = svga->overscan_color; + p[j] = svga->dpms ? 0 : svga->overscan_color; } } @@ -1512,12 +1890,12 @@ svga_doblit(int wx, int wy, svga_t *svga) } void -svga_writeb_linear(uint32_t addr, uint8_t val, void *p) +svga_writeb_linear(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; if (!svga->fast) { - svga_write_linear(addr, val, p); + svga_write_linear(addr, val, priv); return; } @@ -1525,18 +1903,18 @@ svga_writeb_linear(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - *(uint8_t *) &svga->vram[addr] = val; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->vram[addr] = val; } void -svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) +svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; if (!svga->fast) { - svga_write_common(addr, val, linear, p); - svga_write_common(addr + 1, val >> 8, linear, p); + svga_write_common(addr, val, linear, priv); + svga_write_common(addr + 1, val >> 8, linear, priv); return; } @@ -1551,12 +1929,12 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) addr &= svga->decode_mask; if (svga->translate_address) { - uint32_t addr2 = svga->translate_address(addr, p); + uint32_t addr2 = svga->translate_address(addr, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = val & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; } - addr2 = svga->translate_address(addr + 1, p); + addr2 = svga->translate_address(addr + 1, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; @@ -1572,27 +1950,27 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) } void -svga_writew(uint32_t addr, uint16_t val, void *p) +svga_writew(uint32_t addr, uint16_t val, void *priv) { - svga_writew_common(addr, val, 0, p); + svga_writew_common(addr, val, 0, priv); } void -svga_writew_linear(uint32_t addr, uint16_t val, void *p) +svga_writew_linear(uint32_t addr, uint16_t val, void *priv) { - svga_writew_common(addr, val, 1, p); + svga_writew_common(addr, val, 1, priv); } void -svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) +svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; if (!svga->fast) { - svga_write_common(addr, val, linear, p); - svga_write_common(addr + 1, val >> 8, linear, p); - svga_write_common(addr + 2, val >> 16, linear, p); - svga_write_common(addr + 3, val >> 24, linear, p); + svga_write_common(addr, val, linear, priv); + svga_write_common(addr + 1, val >> 8, linear, priv); + svga_write_common(addr + 2, val >> 16, linear, priv); + svga_write_common(addr + 3, val >> 24, linear, priv); return; } @@ -1607,22 +1985,22 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) addr &= svga->decode_mask; if (svga->translate_address) { - uint32_t addr2 = svga->translate_address(addr, p); + uint32_t addr2 = svga->translate_address(addr, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = val & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; } - addr2 = svga->translate_address(addr + 1, p); + addr2 = svga->translate_address(addr + 1, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; } - addr2 = svga->translate_address(addr + 2, p); + addr2 = svga->translate_address(addr + 2, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = (val >> 16) & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; } - addr2 = svga->translate_address(addr + 3, p); + addr2 = svga->translate_address(addr + 3, priv); if (addr2 < svga->vram_max) { svga->vram[addr2 & svga->vram_mask] = (val >> 24) & 0xff; svga->changedvram[addr2 >> 12] = svga->monitor->mon_changeframecount; @@ -1638,39 +2016,39 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) } void -svga_writel(uint32_t addr, uint32_t val, void *p) +svga_writel(uint32_t addr, uint32_t val, void *priv) { - svga_writel_common(addr, val, 0, p); + svga_writel_common(addr, val, 0, priv); } void -svga_writel_linear(uint32_t addr, uint32_t val, void *p) +svga_writel_linear(uint32_t addr, uint32_t val, void *priv) { - svga_writel_common(addr, val, 1, p); + svga_writel_common(addr, val, 1, priv); } uint8_t -svga_readb_linear(uint32_t addr, void *p) +svga_readb_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + const svga_t *svga = (svga_t *) priv; if (!svga->fast) - return svga_read_linear(addr, p); + return svga_read_linear(addr, priv); addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; - return *(uint8_t *) &svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } uint16_t -svga_readw_common(uint32_t addr, uint8_t linear, void *p) +svga_readw_common(uint32_t addr, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; if (!svga->fast) - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8); + return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8); cycles -= svga->monitor->mon_video_timing_read_w; @@ -1683,12 +2061,12 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *p) addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff; - uint8_t val2 = 0xff; - uint32_t addr2 = svga->translate_address(addr, p); + uint8_t val1 = 0xff; + uint8_t val2 = 0xff; + uint32_t addr2 = svga->translate_address(addr, priv); if (addr2 < svga->vram_max) val1 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr + 1, p); + addr2 = svga->translate_address(addr + 1, priv); if (addr2 < svga->vram_max) val2 = svga->vram[addr2 & svga->vram_mask]; return (val2 << 8) | val1; @@ -1700,25 +2078,24 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *p) } uint16_t -svga_readw(uint32_t addr, void *p) +svga_readw(uint32_t addr, void *priv) { - return svga_readw_common(addr, 0, p); + return svga_readw_common(addr, 0, priv); } uint16_t -svga_readw_linear(uint32_t addr, void *p) +svga_readw_linear(uint32_t addr, void *priv) { - return svga_readw_common(addr, 1, p); + return svga_readw_common(addr, 1, priv); } uint32_t -svga_readl_common(uint32_t addr, uint8_t linear, void *p) +svga_readl_common(uint32_t addr, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - if (!svga->fast) { - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8) | (svga_read_common(addr + 2, linear, p) << 16) | (svga_read_common(addr + 3, linear, p) << 24); - } + if (!svga->fast) + return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8) | (svga_read_common(addr + 2, linear, priv) << 16) | (svga_read_common(addr + 3, linear, priv) << 24); cycles -= svga->monitor->mon_video_timing_read_l; @@ -1731,20 +2108,20 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *p) addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff; - uint8_t val2 = 0xff; - uint8_t val3 = 0xff; - uint8_t val4 = 0xff; - uint32_t addr2 = svga->translate_address(addr, p); + uint8_t val1 = 0xff; + uint8_t val2 = 0xff; + uint8_t val3 = 0xff; + uint8_t val4 = 0xff; + uint32_t addr2 = svga->translate_address(addr, priv); if (addr2 < svga->vram_max) val1 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr + 1, p); + addr2 = svga->translate_address(addr + 1, priv); if (addr2 < svga->vram_max) val2 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr + 2, p); + addr2 = svga->translate_address(addr + 2, priv); if (addr2 < svga->vram_max) val3 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr + 3, p); + addr2 = svga->translate_address(addr + 3, priv); if (addr2 < svga->vram_max) val4 = svga->vram[addr2 & svga->vram_mask]; return (val4 << 24) | (val3 << 16) | (val2 << 8) | val1; @@ -1756,13 +2133,13 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *p) } uint32_t -svga_readl(uint32_t addr, void *p) +svga_readl(uint32_t addr, void *priv) { - return svga_readl_common(addr, 0, p); + return svga_readl_common(addr, 0, priv); } uint32_t -svga_readl_linear(uint32_t addr, void *p) +svga_readl_linear(uint32_t addr, void *priv) { - return svga_readl_common(addr, 1, p); + return svga_readl_common(addr, 1, priv); } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index af4cb83da9..9b395ea6cb 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -16,6 +16,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -29,6 +30,20 @@ #include <86box/vid_svga_render.h> #include <86box/vid_svga_render_remap.h> +uint32_t +svga_lookup_lut_ram(svga_t* svga, uint32_t val) +{ + if (!svga->lut_map) + return val; + + uint8_t r = getcolr(svga->pallook[getcolr(val)]); + uint8_t g = getcolg(svga->pallook[getcolg(val)]); + uint8_t b = getcolb(svga->pallook[getcolb(val)]); + return makecol32(r, g, b) | (val & 0xFF000000); +} + +#define lookup_lut(val) svga_lookup_lut_ram(svga, val) + void svga_render_null(svga_t *svga) { @@ -65,11 +80,25 @@ svga_render_blank(svga_t *svga) case 9: char_width = 16; break; + + default: + break; } +#if 0 + pclog("svga->displine = %i, svga->y_add = %i, svga->x_add = %i\n", svga->displine, svga->y_add, svga->x_add); +#endif uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; +#if 0 + pclog("svga->hdisp = %i, svga->scrollcache = %i, char_width = %i, sizeof(uint32_t) = %i\n", svga->hdisp, svga->scrollcache, char_width, sizeof(uint32_t)); +#endif uint32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); - memset(line_ptr, 0, line_width); + +#if 0 + pclog("line_width = %i\n", line_width); +#endif + if ((svga->hdisp + svga->scrollcache) > 0) + memset(line_ptr, 0, line_width); } void @@ -78,7 +107,7 @@ svga_render_overscan_left(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->scrblank || (svga->hdisp == 0)) + if (svga->scrblank || (svga->hdisp <= 0)) return; uint32_t *line_ptr = svga->monitor->target_buffer->line[svga->displine + svga->y_add]; @@ -94,7 +123,7 @@ svga_render_overscan_right(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->scrblank || (svga->hdisp == 0)) + if (svga->scrblank || (svga->hdisp <= 0)) return; uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; @@ -389,202 +418,6 @@ svga_render_text_80_ksc5601(svga_t *svga) } } -void -svga_render_2bpp_lowres(svga_t *svga) -{ - int changed_offset; - int x; - uint8_t dat[2]; - uint32_t addr; - uint32_t *p; - uint32_t changed_addr; - - if ((svga->displine + svga->y_add) < 0) - return; - - if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - addr &= ~7; - - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } - - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 16; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); - - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - - svga->ma &= svga->vram_mask; - - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - - p += 16; - } - } - } -} - -void -svga_render_2bpp_highres(svga_t *svga) -{ - int changed_offset; - int x; - uint8_t dat[2]; - uint32_t addr; - uint32_t *p; - uint32_t changed_addr; - - if ((svga->displine + svga->y_add) < 0) - return; - - if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - addr &= ~7; - - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } - - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 8; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - - svga->ma &= svga->vram_mask; - - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - - p += 8; - } - } - } -} - void svga_render_2bpp_headland_highres(svga_t *svga) { @@ -640,197 +473,286 @@ svga_render_2bpp_headland_highres(svga_t *svga) } } -void -svga_render_4bpp_lowres(svga_t *svga) +static void +svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) { int x; - int oddeven; uint32_t addr; uint32_t *p; - uint8_t edat[4]; - uint8_t dat; - uint32_t changed_addr; + uint32_t changed_offset; + + const bool blinked = !!(svga->blink & 0x10); + const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0); + + /* + The following is likely how it works on an IBM VGA - that is, it works with its BIOS. + But on some cards, certain modes are broken. + - S3 Trio: mode 13h (320x200x8), incbypow2 given as 2 treated as 0 + - ET4000/W32i: mode 2Eh (640x480x8), incevery given as 2 treated as 1 + */ + const bool forcepacked = combine8bits && (svga->force_old_addr || svga->packed_chain4); + + /* + SVGA cards with a high-resolution 8bpp mode may actually bypass the VGA shifter logic. + - HT-216 (+ other Video7 chipsets?) has 0x3C4.0xC8 bit 4 which, when set to 1, loads + bytes directly, bypassing the shifters. + */ + const bool highres8bpp = combine8bits && highres; + + const bool dwordload = ((svga->seqregs[0x01] & 0x10) != 0); + const bool wordload = ((svga->seqregs[0x01] & 0x04) != 0) && !dwordload; + const bool wordincr = ((svga->crtc[0x17] & 0x08) != 0); + const bool dwordincr = ((svga->crtc[0x14] & 0x20) != 0) && !wordincr; + const bool dwordshift = ((svga->crtc[0x14] & 0x40) != 0); + const bool wordshift = ((svga->crtc[0x17] & 0x40) == 0) && !dwordshift; + const uint32_t incbypow2 = forcepacked ? 0 : (dwordshift ? 2 : wordshift ? 1 : 0); + const uint32_t incevery = forcepacked ? 1 : (dwordincr ? 4 : wordincr ? 2 : 1); + const uint32_t loadevery = forcepacked ? 1 : (dwordload ? 4 : wordload ? 2 : 1); + + const bool shift4bit = ((svga->gdcreg[0x05] & 0x40) == 0x40) || highres8bpp; + const bool shift2bit = (((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit); + + const int dwshift = highres ? 0 : 1; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth * ((combine8bits && !svga->packed_4bpp) ? 4 : 8); + const uint32_t planemask = 0x11111111 * (uint32_t) (svga->plane_mask); + const uint32_t blinkmask = (attrblink ? 0x88888888 : 0x0); + const uint32_t blinkval = (attrblink && blinked ? 0x88888888 : 0x0); + + /* + This is actually a 8x 3-bit lookup table, + preshifted by 2 bits to allow shifting by multiples of 4 bits. + + Anyway, when we perform a planar-to-chunky conversion, + we keep the pixel values in a scrambled order. + This lookup table unscrambles them. + + WARNING: Octal values are used here! + */ + const uint32_t shift_values = (shift4bit + ? ((067452301) << 2) + : shift2bit + ? ((026370415) << 2) + : ((002461357) << 2)); if ((svga->displine + svga->y_add) < 0) return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; - oddeven = 0; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; + if (svga->force_old_addr) + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + else + changed_offset = svga->remap_func(svga, svga->ma) >> 12; - if (svga->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; + if (!(svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)) + return; + p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - addr &= ~7; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; + uint32_t incr_counter = 0; + uint32_t load_counter = 0; + uint32_t edat = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { + if (load_counter == 0) { + /* Find our address */ + if (svga->force_old_addr) { + addr = ((svga->ma & ~0x3) << incbypow2); + + if (incbypow2 == 2) { + if (svga->ma & (4 << 15)) + addr |= 0x8; + if (svga->ma & (4 << 14)) + addr |= 0x4; + } else if (incbypow2 == 1) { + if ((svga->crtc[0x17] & 0x20)) { + if (svga->ma & (4 << 15)) + addr |= 0x4; + } else { + if (svga->ma & (4 << 13)) + addr |= 0x4; + } + } else { + /* Nothing */ } if (!(svga->crtc[0x17] & 0x01)) addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); if (!(svga->crtc[0x17] & 0x02)) addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + } else if (svga->remap_required) + addr = svga->remap_func(svga, svga->ma); + else + addr = svga->ma; + + addr &= svga->vram_display_mask; - if (svga->seqregs[1] & 4) { - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; + /* Load VRAM */ + edat = *(uint32_t *) &svga->vram[addr]; + + /* + EGA and VGA actually use 4bpp planar as its native format. + But 4bpp chunky is generally easier to deal with on a modern CPU. + shift4bit is the native format for this renderer (4bpp chunky). + */ + if (svga->ati_4color || !shift4bit) { + if (shift2bit && !svga->ati_4color) { + /* Group 2x 2bpp values into 4bpp values */ + edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC); } else { - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); - svga->ma += 4; + /* Group 4x 1bpp values into 4bpp values */ + edat = (edat & 0xAA55AA55) | ((edat << 7) & 0x55005500) | ((edat >> 7) & 0x00AA00AA); + edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC); } - svga->ma &= svga->vram_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - - p += 16; } + } else { + /* + According to the 82C451 VGA clone chipset datasheet, all 4 planes chain in a ring. + So, rotate them all around. + Planar version: edat = (edat >> 8) | (edat << 24); + Here's the chunky version... + */ + edat = ((edat >> 1) & 0x77777777) | ((edat << 3) & 0x88888888); } - } else { - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + load_counter += 1; + if (load_counter >= loadevery) + load_counter = 0; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + incr_counter += 1; + if (incr_counter >= incevery) { + incr_counter = 0; + svga->ma += 4; + /* DISCREPANCY TODO FIXME 2/4bpp used vram_mask, 8bpp used vram_display_mask --GM */ + svga->ma &= svga->vram_display_mask; + } - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; + uint32_t current_shift = shift_values; + uint32_t out_edat = edat; + /* + Apply blink + FIXME: Confirm blink behaviour on real hardware + + The VGA 4bpp graphics blink logic was a pain to work out. + + If plane 3 is enabled in the attribute controller, then: + - if bit 3 is 0, then we force the output of it to be 1. + - if bit 3 is 1, then the output blinks. + This can be tested with Lotus 1-2-3 release 2.3 with the WYSIWYG addon. + + If plane 3 is disabled in the attribute controller, then the output blinks. + This can be tested with QBASIC SCREEN 10 - anything using color #2 should + blink and nothing else. + + If you can simplify the following and have it still work, give yourself a medal. + */ + out_edat = ((out_edat & planemask & ~blinkmask) | ((out_edat | ~planemask) & blinkmask & blinkval)) ^ blinkmask; + + for (int i = 0; i < (8 + (svga->ati_4color ? 8 : 0)); i += (svga->ati_4color ? 4 : 2)) { + /* + c0 denotes the first 4bpp pixel shifted, while c1 denotes the second. + For 8bpp modes, the first 4bpp pixel is the upper 4 bits. + */ + uint32_t c0 = (out_edat >> (current_shift & 0x1C)) & 0xF; + current_shift >>= 3; + uint32_t c1 = (out_edat >> (current_shift & 0x1C)) & 0xF; + current_shift >>= 3; + + if (svga->ati_4color) { + uint32_t q[4]; + q[0] = svga->pallook[svga->egapal[(c0 & 0x0c) >> 2]]; + q[1] = svga->pallook[svga->egapal[c0 & 0x03]]; + q[2] = svga->pallook[svga->egapal[(c1 & 0x0c) >> 2]]; + q[3] = svga->pallook[svga->egapal[c1 & 0x03]]; + + const int outoffs = i << dwshift; + for (int ch = 0; ch < 4; ch++) { + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + (dotwidth * ch)] = q[ch]; + } + } else if (combine8bits) { + if (svga->packed_4bpp) { + uint32_t p0 = svga->map8[c0]; + uint32_t p1 = svga->map8[c1]; + const int outoffs = i << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + dotwidth] = p1; } else { - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); - svga->ma += 4; + uint32_t ccombined = (c0 << 4) | c1; + uint32_t p0 = svga->map8[ccombined]; + const int outoffs = (i >> 1) << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; } - svga->ma &= svga->vram_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - - p += 16; + } else { + uint32_t p0 = svga->pallook[svga->egapal[c0]]; + uint32_t p1 = svga->pallook[svga->egapal[c1]]; + const int outoffs = i << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + dotwidth] = p1; } } + + if (svga->ati_4color) + p += (charwidth << 1); + // p += charwidth; + else + p += charwidth; } } +/* + Remap these to the paletted renderer + (*, highres, combine8bits) + */ +void svga_render_2bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, false); } +void svga_render_2bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, false); } +void svga_render_4bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, false); } +void svga_render_4bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, false); } +void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, true); } +void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); } + void -svga_render_4bpp_highres(svga_t *svga) +svga_render_8bpp_clone_highres(svga_t *svga) { - int changed_offset; int x; - int oddeven; - uint32_t addr; uint32_t *p; - uint8_t edat[4]; - uint8_t dat; + uint32_t dat; uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) return; if (svga->force_old_addr) { - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; - oddeven = 0; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - - if (svga->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; - - addr &= ~7; - - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } - - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - if (svga->seqregs[1] & 4) { - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); - svga->ma += 4; - } - svga->ma &= svga->vram_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + svga->ma += 8; p += 8; } + svga->ma &= svga->vram_display_mask; } } else { changed_addr = svga->remap_func(svga, svga->ma); @@ -842,41 +764,43 @@ svga_render_4bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; - - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); - svga->ma += 4; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; } - svga->ma &= svga->vram_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - p += 8; + svga->ma += 4; + p += 4; + } } + svga->ma &= svga->vram_display_mask; } } } +// TODO: Integrate more of this into the generic paletted renderer --GM +#if 0 void svga_render_8bpp_lowres(svga_t *svga) { @@ -1031,6 +955,7 @@ svga_render_8bpp_highres(svga_t *svga) } } } +#endif void svga_render_8bpp_tseng_lowres(svga_t *svga) @@ -1154,13 +1079,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1179,13 +1104,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1193,8 +1118,8 @@ svga_render_15bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1225,20 +1150,20 @@ svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1256,20 +1181,20 @@ svga_render_15bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1277,8 +1202,8 @@ svga_render_15bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1305,17 +1230,17 @@ svga_render_15bpp_mix_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1341,24 +1266,24 @@ svga_render_15bpp_mix_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1386,13 +1311,13 @@ svga_render_16bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1411,13 +1336,13 @@ svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1425,8 +1350,8 @@ svga_render_16bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += 4; } @@ -1457,20 +1382,20 @@ svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { uint32_t dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1488,20 +1413,20 @@ svga_render_16bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1509,8 +1434,8 @@ svga_render_16bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); svga->ma += 4; } @@ -1548,7 +1473,7 @@ svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(fg); } } } else { @@ -1567,10 +1492,10 @@ svga_render_24bpp_lowres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1583,10 +1508,10 @@ svga_render_24bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1621,16 +1546,16 @@ svga_render_24bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + p[x + 1] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + p[x + 2] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; + p[x + 3] = lookup_lut(dat & 0xffffff); svga->ma += 12; } @@ -1652,10 +1577,10 @@ svga_render_24bpp_highres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1668,10 +1593,10 @@ svga_render_24bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1703,7 +1628,7 @@ svga_render_32bpp_lowres(svga_t *svga) dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(dat); } } } else { @@ -1719,16 +1644,16 @@ svga_render_32bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } svga->ma &= svga->vram_display_mask; @@ -1759,7 +1684,7 @@ svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); } svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -1777,14 +1702,14 @@ svga_render_32bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } @@ -1818,14 +1743,14 @@ svga_render_ABGR8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); } svga->ma += x * 4; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); svga->ma += 4; } @@ -1858,14 +1783,14 @@ svga_render_RGBA8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); svga->ma += 4; } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 6d708d53bd..9e46662b68 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -36,8 +36,9 @@ #include <86box/vid_ega.h> #include <86box/vid_colorplus.h> #include <86box/vid_mda.h> +#include <86box/vid_xga_device.h> -typedef struct { +typedef struct video_card_t { const device_t *device; int flags; } VIDEO_CARD; @@ -76,192 +77,203 @@ static const device_t vid_internal_device = { static const VIDEO_CARD video_cards[] = { // clang-format off - { &vid_none_device }, - { &vid_internal_device }, - { &atiega_device }, - { &mach64gx_isa_device }, - { &ati28800k_device }, - { &ati18800_vga88_device }, - { &ati28800_device }, - { &compaq_ati28800_device }, + { &vid_none_device }, + { &vid_internal_device }, + { &atiega800p_device }, + { &mach8_vga_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_isa_device }, + { &ati28800k_device }, + { &ati18800_vga88_device }, + { &ati28800_device }, + { &compaq_ati28800_device }, #if defined(DEV_BRANCH) && defined(USE_XL24) - { &ati28800_wonderxl24_device }, + { &ati28800_wonderxl24_device }, #endif - { &ati18800_device }, + { &ati18800_device }, #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - { &ati18800_wonder_device }, + { &ati18800_wonder_device }, #endif - { &cga_device }, - { &sega_device }, - { &gd5401_isa_device }, - { &gd5402_isa_device }, - { &gd5420_isa_device }, - { &gd5422_isa_device }, - { &gd5426_isa_device }, - { &gd5426_diamond_speedstar_pro_a1_isa_device }, - { &gd5428_boca_isa_device }, - { &gd5428_isa_device }, - { &gd5429_isa_device }, - { &gd5434_isa_device }, - { &gd5434_diamond_speedstar_64_a3_isa_device }, - { &compaq_cga_device }, - { &compaq_cga_2_device }, - { &cpqega_device }, - { &ega_device }, - { &g2_gc205_device }, - { &hercules_device, VIDEO_FLAG_TYPE_MDA }, - { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, - { &incolor_device }, - { &im1024_device }, - { &iskra_ega_device }, - { &et4000_kasan_isa_device }, - { &mda_device, VIDEO_FLAG_TYPE_MDA }, - { &genius_device }, - { &nga_device }, - { &ogc_device }, - { &oti037c_device }, - { &oti067_device }, - { &oti077_device }, - { ¶dise_pvga1a_device }, - { ¶dise_wd90c11_device }, - { ¶dise_wd90c30_device }, - { &colorplus_device }, - { &pgc_device }, - { &cga_pravetz_device }, - { &radius_svga_multiview_isa_device }, - { &realtek_rtg3106_device }, - { &s3_diamond_stealth_vram_isa_device }, - { &s3_orchid_86c911_isa_device }, - { &s3_ami_86c924_isa_device }, - { &s3_metheus_86c928_isa_device }, - { &s3_phoenix_86c801_isa_device }, - { &s3_spea_mirage_86c801_isa_device }, - { &sigma_device }, - { &tvga8900b_device }, - { &tvga8900d_device }, - { &tvga9000b_device }, - { &nec_sv9000_device }, - { &et4000k_isa_device }, - { &et2000_device }, - { &et3000_isa_device }, - { &et4000_isa_device }, - { &et4000w32_device }, - { &et4000w32i_isa_device }, - { &vga_device }, - { &v7_vga_1024i_device }, - { &wy700_device }, - { &gd5426_mca_device }, - { &gd5428_mca_device }, - { &et4000_mca_device }, - { &radius_svga_multiview_mca_device }, - { &mach64gx_pci_device }, - { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, - { &gd5430_pci_device, }, - { &gd5434_pci_device }, - { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5440_pci_device }, - { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5446_stb_pci_device,VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5480_pci_device }, - { &s3_spea_mercury_lite_86c928_pci_device }, - { &s3_diamond_stealth64_964_pci_device }, - { &s3_elsa_winner2000_pro_x_964_pci_device }, - { &s3_mirocrystal_20sv_964_pci_device }, - { &s3_bahamas64_pci_device }, - { &s3_phoenix_vision864_pci_device }, - { &s3_diamond_stealth_se_pci_device }, - { &s3_phoenix_trio32_pci_device }, - { &s3_diamond_stealth64_pci_device }, - { &s3_9fx_pci_device }, - { &s3_phoenix_trio64_pci_device }, - { &s3_elsa_winner2000_pro_x_pci_device }, - { &s3_mirovideo_40sv_ergo_968_pci_device }, - { &s3_9fx_771_pci_device }, - { &s3_phoenix_vision968_pci_device }, - { &s3_spea_mercury_p64v_pci_device }, - { &s3_9fx_531_pci_device }, - { &s3_phoenix_vision868_pci_device }, - { &s3_phoenix_trio64vplus_pci_device }, - { &s3_trio64v2_dx_pci_device }, - { &s3_virge_325_pci_device }, - { &s3_diamond_stealth_2000_pci_device }, - { &s3_diamond_stealth_3000_pci_device }, - { &s3_stb_velocity_3d_pci_device }, - { &s3_virge_375_pci_device }, - { &s3_diamond_stealth_2000pro_pci_device }, - { &s3_virge_385_pci_device }, - { &s3_virge_357_pci_device }, - { &s3_diamond_stealth_4000_pci_device }, - { &s3_trio3d2x_pci_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA) - { &millennium_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &mystique_device }, - { &mystique_220_device }, -#endif - { &tgui9440_pci_device }, - { &tgui9660_pci_device }, - { &tgui9680_pci_device }, - { &voodoo_banshee_device }, - { &creative_voodoo_banshee_device }, - { &voodoo_3_1000_device }, - { &voodoo_3_2000_device }, - { &voodoo_3_3000_device }, - { &mach64gx_vlb_device }, - { &et4000w32i_vlb_device }, - { &et4000w32p_videomagic_revb_vlb_device }, - { &et4000w32p_revc_vlb_device }, - { &et4000w32p_cardex_vlb_device }, - { &et4000w32p_vlb_device }, - { &et4000w32p_noncardex_vlb_device }, - { &gd5424_vlb_device }, - { &gd5426_vlb_device }, - { &gd5428_vlb_device }, - { &gd5428_diamond_speedstar_pro_b1_vlb_device }, - { &gd5429_vlb_device }, - { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, - { &gd5430_vlb_device }, - { &gd5434_vlb_device }, - { &sis_6202_device }, - { &s3_metheus_86c928_vlb_device }, - { &s3_mirocrystal_8s_805_vlb_device }, - { &s3_mirocrystal_10sd_805_vlb_device }, - { &s3_phoenix_86c805_vlb_device }, - { &s3_spea_mirage_86c805_vlb_device }, - { &s3_diamond_stealth64_964_vlb_device }, - { &s3_mirocrystal_20sv_964_vlb_device }, - { &s3_mirocrystal_20sd_864_vlb_device }, - { &s3_bahamas64_vlb_device }, - { &s3_phoenix_vision864_vlb_device }, - { &s3_diamond_stealth_se_vlb_device }, - { &s3_phoenix_trio32_vlb_device }, - { &s3_diamond_stealth64_vlb_device }, - { &s3_9fx_vlb_device }, - { &s3_phoenix_trio64_vlb_device }, - { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, - { &ht216_32_standalone_device }, - { &tgui9400cxi_device }, - { &tgui9440_vlb_device }, - { &s3_virge_357_agp_device }, - { &s3_diamond_stealth_4000_agp_device }, - { &s3_trio3d2x_agp_device }, - { &velocity_100_agp_device }, - { &velocity_200_agp_device }, - { &voodoo_3_1000_agp_device }, - { &voodoo_3_2000_agp_device }, - { &voodoo_3_3000_agp_device }, - { &voodoo_3_3500_agp_ntsc_device }, - { &voodoo_3_3500_agp_pal_device }, - { &compaq_voodoo_3_3500_agp_device }, - { &voodoo_3_3500_se_agp_device }, - { &voodoo_3_3500_si_agp_device }, - { NULL } + { &cga_device }, + { &sega_device }, + { &gd5401_isa_device }, + { &gd5402_isa_device }, + { &gd5420_isa_device }, + { &gd5422_isa_device }, + { &gd5426_isa_device }, + { &gd5426_diamond_speedstar_pro_a1_isa_device }, + { &gd5428_boca_isa_device }, + { &gd5428_isa_device }, + { &gd5429_isa_device }, + { &gd5434_isa_device }, + { &gd5434_diamond_speedstar_64_a3_isa_device }, + { &compaq_cga_device }, + { &compaq_cga_2_device }, + { &cpqega_device }, + { &ega_device }, + { &g2_gc205_device }, + { &hercules_device, VIDEO_FLAG_TYPE_MDA }, + { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, + { &incolor_device }, + { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, + { &im1024_device }, + { &iskra_ega_device }, + { &et4000_kasan_isa_device }, + { &mda_device, VIDEO_FLAG_TYPE_MDA }, + { &genius_device }, + { &nga_device }, + { &ogc_device }, + { &oti037c_device }, + { &oti067_device }, + { &oti077_device }, + { ¶dise_pvga1a_device }, + { ¶dise_wd90c11_device }, + { ¶dise_wd90c30_device }, + { &colorplus_device }, + { &pgc_device }, + { &cga_pravetz_device }, + { &radius_svga_multiview_isa_device }, + { &realtek_rtg3105_device }, + { &realtek_rtg3106_device }, + { &s3_diamond_stealth_vram_isa_device }, + { &s3_orchid_86c911_isa_device }, + { &s3_ami_86c924_isa_device }, + { &s3_metheus_86c928_isa_device }, + { &s3_phoenix_86c801_isa_device }, + { &s3_spea_mirage_86c801_isa_device }, + { &sigma_device }, + { &tvga8900b_device }, + { &tvga8900d_device }, + { &tvga9000b_device }, + { &nec_sv9000_device }, + { &et4000k_isa_device }, + { &et2000_device }, + { &et3000_isa_device }, + { &et4000_tc6058af_isa_device }, + { &et4000_isa_device }, + { &et4000w32_device }, + { &et4000w32i_isa_device }, + { &vga_device }, + { &v7_vga_1024i_device }, + { &wy700_device }, + { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, + { &gd5426_mca_device }, + { &gd5428_mca_device }, + { &et4000_mca_device }, + { &radius_svga_multiview_mca_device }, + { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_pci_device }, + { &mach64vt2_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, + { &gd5430_pci_device, }, + { &gd5434_pci_device }, + { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5440_pci_device }, + { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5480_pci_device }, + { &s3_spea_mercury_lite_86c928_pci_device }, + { &s3_diamond_stealth64_964_pci_device }, + { &s3_elsa_winner2000_pro_x_964_pci_device }, + { &s3_mirocrystal_20sv_964_pci_device }, + { &s3_bahamas64_pci_device }, + { &s3_phoenix_vision864_pci_device }, + { &s3_diamond_stealth_se_pci_device }, + { &s3_phoenix_trio32_pci_device }, + { &s3_diamond_stealth64_pci_device }, + { &s3_9fx_pci_device }, + { &s3_phoenix_trio64_pci_device }, + { &s3_elsa_winner2000_pro_x_pci_device }, + { &s3_mirovideo_40sv_ergo_968_pci_device }, + { &s3_9fx_771_pci_device }, + { &s3_phoenix_vision968_pci_device }, + { &s3_spea_mercury_p64v_pci_device }, + { &s3_9fx_531_pci_device }, + { &s3_phoenix_vision868_pci_device }, + { &s3_cardex_trio64vplus_pci_device }, + { &s3_phoenix_trio64vplus_pci_device }, + { &s3_trio64v2_dx_pci_device }, + { &s3_virge_325_pci_device }, + { &s3_diamond_stealth_2000_pci_device }, + { &s3_diamond_stealth_3000_pci_device }, + { &s3_stb_velocity_3d_pci_device }, + { &s3_virge_375_pci_device }, + { &s3_diamond_stealth_2000pro_pci_device }, + { &s3_virge_385_pci_device }, + { &s3_virge_357_pci_device }, + { &s3_diamond_stealth_4000_pci_device }, + { &s3_trio3d2x_pci_device }, + { &chips_69000_device }, + { &millennium_device }, + { &millennium_ii_device }, + { &mystique_device }, + { &mystique_220_device }, + { &tgui9440_pci_device }, + { &tgui9660_pci_device }, + { &tgui9680_pci_device }, + { &voodoo_banshee_device }, + { &creative_voodoo_banshee_device }, + { &voodoo_3_1000_device }, + { &voodoo_3_2000_device }, + { &voodoo_3_3000_device }, + { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_vlb_device }, + { &et4000w32i_vlb_device }, + { &et4000w32p_videomagic_revb_vlb_device }, + { &et4000w32p_revc_vlb_device }, + { &et4000w32p_cardex_vlb_device }, + { &et4000w32p_vlb_device }, + { &et4000w32p_noncardex_vlb_device }, + { &gd5424_vlb_device }, + { &gd5426_vlb_device }, + { &gd5428_vlb_device }, + { &gd5428_diamond_speedstar_pro_b1_vlb_device }, + { &gd5429_vlb_device }, + { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, + { &gd5430_vlb_device }, + { &gd5434_vlb_device }, + { &sis_6202_device }, + { &s3_metheus_86c928_vlb_device }, + { &s3_mirocrystal_8s_805_vlb_device }, + { &s3_mirocrystal_10sd_805_vlb_device }, + { &s3_phoenix_86c805_vlb_device }, + { &s3_spea_mirage_86c805_vlb_device }, + { &s3_diamond_stealth64_964_vlb_device }, + { &s3_mirocrystal_20sv_964_vlb_device }, + { &s3_mirocrystal_20sd_864_vlb_device }, + { &s3_bahamas64_vlb_device }, + { &s3_phoenix_vision864_vlb_device }, + { &s3_diamond_stealth_se_vlb_device }, + { &s3_phoenix_trio32_vlb_device }, + { &s3_diamond_stealth64_vlb_device }, + { &s3_9fx_vlb_device }, + { &s3_phoenix_trio64_vlb_device }, + { &s3_spea_mirage_p64_vlb_device }, + { &s3_phoenix_vision968_vlb_device }, + { &s3_phoenix_vision868_vlb_device }, + { &s3_stb_powergraph_64_video_vlb_device }, + { &ht216_32_standalone_device }, + { &tgui9400cxi_device }, + { &tgui9440_vlb_device }, + { &s3_virge_357_agp_device }, + { &s3_diamond_stealth_4000_agp_device }, + { &s3_trio3d2x_agp_device }, + { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &velocity_100_agp_device }, + { &velocity_200_agp_device }, + { &voodoo_3_1000_agp_device }, + { &voodoo_3_2000_agp_device }, + { &voodoo_3_3000_agp_device }, + { &voodoo_3_3500_agp_ntsc_device }, + { &voodoo_3_3500_agp_pal_device }, + { &compaq_voodoo_3_3500_agp_device }, + { &voodoo_3_3500_se_agp_device }, + { &voodoo_3_3500_si_agp_device }, + { NULL } // clang-format on }; @@ -338,8 +350,16 @@ video_reset(int card) monitor_index_global = 0; loadfont("roms/video/mda/mda.rom", 0); + if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) && + (gfxcard[1] > VID_INTERNAL) && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { + video_monitor_init(1); + monitor_index_global = 1; + device_add(video_cards[gfxcard[1]].device); + monitor_index_global = 0; + } + /* Do not initialize internal cards here. */ - if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { + if ((card > VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name); video_prepare(); @@ -348,21 +368,40 @@ video_reset(int card) device_add(video_cards[card].device); } - if (!(card == VID_NONE) - && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) - && gfxcard[1] != 0 - && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { - video_monitor_init(1); - monitor_index_global = 1; - device_add(video_cards[gfxcard[1]].device); - monitor_index_global = 0; - } + was_reset = 1; +} + +void +video_post_reset(void) +{ + int ibm8514_has_vga = 0; + if (gfxcard[0] == VID_INTERNAL) + ibm8514_has_vga = (video_get_type_monitor(0) == VIDEO_FLAG_TYPE_8514); + else if (gfxcard[0] != VID_NONE) + ibm8514_has_vga = (video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514); + else + ibm8514_has_vga = 0; + + if (ibm8514_has_vga) + ibm8514_active = 1; + + if (ibm8514_standalone_enabled) + ibm8514_device_add(); + + if (xga_standalone_enabled) + xga_device_add(); + + /* Reset the graphics card (or do nothing if it was already done + by the machine's init function). */ + video_reset(gfxcard[0]); +} +void +video_voodoo_init(void) +{ /* Enable the Voodoo if configured. */ if (voodoo_enabled) device_add(&voodoo_device); - - was_reset = 1; } int @@ -395,7 +434,7 @@ video_card_has_config(int card) return (device_has_config(video_cards[card].device) ? 1 : 0); } -char * +const char * video_get_internal_name(int card) { return device_get_internal_name(video_cards[card].device); @@ -407,7 +446,7 @@ video_get_video_from_internal_name(char *s) int c = 0; while (video_cards[c].device != NULL) { - if (!strcmp((char *) video_cards[c].device->internal_name, s)) + if (!strcmp(video_cards[c].device->internal_name, s)) return c; c++; } @@ -432,3 +471,15 @@ video_is_ega_vga(void) { return (video_get_type() == VIDEO_FLAG_TYPE_SPECIAL); } + +int +video_is_8514(void) +{ + return (video_get_type() == VIDEO_FLAG_TYPE_8514); +} + +int +video_is_xga(void) +{ + return (video_get_type() == VIDEO_FLAG_TYPE_XGA); +} diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index fc191b2497..490c724cea 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Trident TGUI9400CXi and TGUI9440 emulation. + * Trident TGUI9400CXi and TGUI9440/96x0 emulation. * * TGUI9400CXi has extended write modes, controlled by extended * GDC registers : @@ -76,7 +76,8 @@ #include <86box/vid_svga_render.h> #define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.VBI" -#define ROM_TGUI_9440 "roms/video/tgui9440/BIOS.BIN" +#define ROM_TGUI_9440_VLB "roms/video/tgui9440/trident_9440_vlb.bin" +#define ROM_TGUI_9440_PCI "roms/video/tgui9440/BIOS.BIN" #define ROM_TGUI_96xx "roms/video/tgui9660/Union.VBI" #define EXT_CTRL_16BIT 0x01 @@ -103,7 +104,10 @@ typedef struct tgui_t { svga_t svga; int pci; - int type, card; + uint8_t pci_slot; + uint8_t irq_state; + + int type; uint8_t int_line; uint8_t pci_regs[256]; @@ -126,8 +130,9 @@ typedef struct tgui_t { int offset; uint16_t ger22; - int16_t err, top, left, bottom, right; - int x, y, dx, dy; + int16_t err; + int16_t top, left, bottom, right; + int16_t x, y, cx, cy, dx, dy; uint32_t src, dst, src_old, dst_old; int pat_x, pat_y; int use_src; @@ -169,17 +174,17 @@ typedef struct tgui_t { video_timings_t timing_tgui_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 8, .write_l = 16, .read_b = 4, .read_w = 8, .read_l = 16 }; video_timings_t timing_tgui_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 8, .write_l = 16, .read_b = 4, .read_w = 8, .read_l = 16 }; -static void tgui_out(uint16_t addr, uint8_t val, void *p); -static uint8_t tgui_in(uint16_t addr, void *p); +static void tgui_out(uint16_t addr, uint8_t val, void *priv); +static uint8_t tgui_in(uint16_t addr, void *priv); static void tgui_recalcmapping(tgui_t *tgui); -static void tgui_accel_out(uint16_t addr, uint8_t val, void *p); -static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p); -static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p); -static uint8_t tgui_accel_in(uint16_t addr, void *p); -static uint16_t tgui_accel_in_w(uint16_t addr, void *p); -static uint32_t tgui_accel_in_l(uint16_t addr, void *p); +static void tgui_accel_out(uint16_t addr, uint8_t val, void *priv); +static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *priv); +static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *priv); +static uint8_t tgui_accel_in(uint16_t addr, void *priv); +static uint16_t tgui_accel_in_w(uint16_t addr, void *priv); +static uint32_t tgui_accel_in_l(uint16_t addr, void *priv); static uint8_t tgui_accel_read(uint32_t addr, void *priv); static uint16_t tgui_accel_read_w(uint32_t addr, void *priv); @@ -193,15 +198,15 @@ static void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); static void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); static void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); -static uint8_t tgui_ext_linear_read(uint32_t addr, void *p); -static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p); +static uint8_t tgui_ext_linear_read(uint32_t addr, void *priv); +static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv); +static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv); +static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv); -static uint8_t tgui_ext_read(uint32_t addr, void *p); -static void tgui_ext_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); +static uint8_t tgui_ext_read(uint32_t addr, void *priv); +static void tgui_ext_write(uint32_t addr, uint8_t val, void *priv); +static void tgui_ext_writew(uint32_t addr, uint16_t val, void *priv); +static void tgui_ext_writel(uint32_t addr, uint32_t val, void *priv); /*Remap address for chain-4/doubleword style layout*/ static __inline uint32_t @@ -219,11 +224,10 @@ tgui_update_irqs(tgui_t *tgui) if (!tgui->pci) return; - if (!(tgui->oldctrl1 & 0x40)) { - pci_set_irq(tgui->card, PCI_INTA); - } else { - pci_clear_irq(tgui->card, PCI_INTA); - } + if (!(tgui->oldctrl1 & 0x40)) + pci_set_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state); + else + pci_clear_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state); } static void @@ -289,9 +293,9 @@ tgui_set_io(tgui_t *tgui) } static void -tgui_out(uint16_t addr, uint8_t val, void *p) +tgui_out(uint16_t addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; uint8_t old; @@ -326,6 +330,9 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (!(svga->gdcreg[0xf] & 1)) svga->read_bank = svga->write_bank; return; + + default: + break; } break; @@ -415,6 +422,9 @@ tgui_out(uint16_t addr, uint8_t val, void *p) case 0x5f: svga->gdcreg[svga->gdcaddr] = val; break; + + default: + break; } break; case 0x3D4: @@ -488,6 +498,9 @@ tgui_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & 1) ? 64 : 32); } break; + + default: + break; } if (old != val) { @@ -496,7 +509,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) svga->fullchange = 3; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } } @@ -526,14 +539,17 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); tgui->clock_k = (val & 0x10) >> 4; break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -tgui_in(uint16_t addr, void *p) +tgui_in(uint16_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; uint8_t temp; @@ -556,6 +572,9 @@ tgui_in(uint16_t addr, void *p) case TGUI_9660: case TGUI_9680: return 0xd3; /*TGUI9660XGi*/ + + default: + break; } } if (svga->seqaddr == 0x0d) { @@ -617,6 +636,9 @@ tgui_in(uint16_t addr, void *p) return tgui->tgui_3d8; case 0x3d9: return tgui->tgui_3d9; + + default: + break; } return svga_in(addr, svga); } @@ -624,9 +646,9 @@ tgui_in(uint16_t addr, void *p) void tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *) svga->p; - uint8_t ger22lower = tgui->accel.ger22 & 0xff; - uint8_t ger22upper = (tgui->accel.ger22 >> 8); + const tgui_t *tgui = (tgui_t *) svga->priv; + uint8_t ger22lower = (tgui->accel.ger22 & 0xff); + uint8_t ger22upper = (tgui->accel.ger22 >> 8); if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -634,13 +656,8 @@ tgui_recalctimings(svga_t *svga) if (svga->crtc[0x29] & 0x10) svga->rowoffset |= 0x100; - if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) { - if ((tgui->accel.bpp == 0) && (ger22lower != 14) && (svga->bpp == 24)) - svga->hdisp = (svga->crtc[1] + 1) * 8; - if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440)) - svga->rowoffset <<= 1; - // pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); - } + if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) + svga->hdisp = (svga->crtc[1] + 1) * 8; if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; @@ -728,6 +745,9 @@ tgui_recalctimings(svga_t *svga) case 0x0f: svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; break; + + default: + break; } if (svga->gdcreg[0xf] & 0x08) { svga->htotal <<= 1; @@ -741,19 +761,31 @@ tgui_recalctimings(svga_t *svga) case 8: svga->render = svga_render_8bpp_highres; if (tgui->type >= TGUI_9660) { - if ((svga->dispend == 510) || (svga->dispend == 512)) - svga->hdisp = 1280; - else if ((svga->dispend == 600) && (svga->hdisp == 800) && svga->interlace) - svga->hdisp = 1600; + if (svga->dispend == ((1024 >> 1) - 2)) + svga->dispend += 2; + if (svga->dispend == (1024 >> 1)) + svga->hdisp <<= 1; + else if ((svga->hdisp == (1600 >> 1)) && (svga->dispend == (1200 >> 1)) && svga->interlace) + svga->hdisp <<= 1; + else if (svga->hdisp == (1024 >> 1)) { + if (svga->interlace && (svga->dispend == (768 >> 1))) + svga->hdisp <<= 1; + else if (!svga->interlace && (svga->dispend == 768)) + svga->hdisp <<= 1; + } + if (ger22upper & 0x80) { + svga->htotal <<= 1; + svga->hdisp <<= 1; + svga->hdisp_time <<= 1; + } switch (svga->hdisp) { case 640: - if (ger22upper & 0x01) - svga->rowoffset = 0x50; + if (!ger22lower) + svga->rowoffset = 80; break; - case 1600: - if (svga->rowoffset != 0x100) - svga->rowoffset = 0x100; + + default: break; } } @@ -776,11 +808,13 @@ tgui_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1024) { + if (!ger22upper) svga->rowoffset <<= 1; - } } break; + + default: + break; } } } @@ -851,11 +885,13 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } } else { mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); switch (svga->gdcreg[6] & 0xC) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -863,12 +899,6 @@ tgui_recalcmapping(tgui_t *tgui) break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if ((svga->crtc[0x36] & 0x03) == 0x01) - mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x02) - mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x03) - mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ @@ -879,7 +909,22 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } + + if (tgui->pci && tgui->linear_base) /*Assume that, with PCI, linear addressing is always enabled.*/ + mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); + + if ((svga->crtc[0x36] & 0x03) == 0x01) + mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x02) + mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x03) + mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); + else + mem_mapping_disable(&tgui->accel_mapping); } if (tgui->type >= TGUI_9440) { @@ -906,14 +951,14 @@ tgui_hwcursor_draw(svga_t *svga, int displine) if (svga->crtc[0x50] & 0x40) { if (offset >= svga->hwcursor_latch.x) { if (dat[0] & 0x80000000) - ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; + (buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; } } else { if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x80000000)) - ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; + (buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; else if (dat[1] & 0x80000000) - ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] ^= 0xffffff; + (buffer32->line[displine])[svga->x_add + offset] ^= 0xffffff; } } offset++; @@ -927,9 +972,9 @@ tgui_hwcursor_draw(svga_t *svga, int displine) } uint8_t -tgui_pci_read(int func, int addr, void *p) +tgui_pci_read(UNUSED(int func), int addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + const tgui_t *tgui = (tgui_t *) priv; switch (addr) { case 0x00: @@ -943,7 +988,7 @@ tgui_pci_read(int func, int addr, void *p) return (tgui->type == TGUI_9440) ? 0x94 : 0x96; case PCI_REG_COMMAND: - return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + return tgui->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ @@ -989,23 +1034,27 @@ tgui_pci_read(int func, int addr, void *p) return tgui->int_line; case 0x3d: return PCI_INTA; + + default: + break; } return 0; } void -tgui_pci_write(int func, int addr, uint8_t val, void *p) +tgui_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; switch (addr) { case PCI_REG_COMMAND: - tgui->pci_regs[PCI_REG_COMMAND] = (val & 0x23); - if (val & PCI_COMMAND_IO) { + tgui->pci_regs[PCI_REG_COMMAND] = val & 0x23; + if (val & PCI_COMMAND_IO) tgui_set_io(tgui); - } else + else tgui_remove_io(tgui); + tgui_recalcmapping(tgui); break; @@ -1060,14 +1109,17 @@ tgui_pci_write(int func, int addr, uint8_t val, void *p) case 0x3c: tgui->int_line = val; return; + + default: + break; } } static uint8_t -tgui_ext_linear_read(uint32_t addr, void *p) +tgui_ext_linear_read(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; + svga_t *svga = (svga_t *) priv; + tgui_t *tgui = (tgui_t *) svga->priv; cycles -= video_timing_read_b; @@ -1075,21 +1127,26 @@ tgui_ext_linear_read(uint32_t addr, void *p) if (addr >= svga->vram_max) return 0xff; - addr &= ~0xf; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - for (uint8_t c = 0; c < 16; c++) { - tgui->copy_latch[c] = svga->vram[addr + c]; - addr += ((c & 3) == 3) ? 13 : 1; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (int c = 0; c < 16; c++) { + tgui->copy_latch[c] = svga->vram[addr]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + return svga->vram[addr]; } - return svga->vram[addr & svga->vram_mask]; + return svga_read_linear(addr, svga); } static uint8_t -tgui_ext_read(uint32_t addr, void *p) +tgui_ext_read(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; addr = (addr & svga->banked_mask) + svga->read_bank; @@ -1097,14 +1154,15 @@ tgui_ext_read(uint32_t addr, void *p) } static void -tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) +tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; - int c; - uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; - uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; - uint8_t mask = tgui->ext_gdc_regs[7]; + svga_t *svga = (svga_t *) priv; + const tgui_t *tgui = (tgui_t *) svga->priv; + int c; + int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); + uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; + uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; + uint8_t mask = tgui->ext_gdc_regs[7]; cycles -= video_timing_write_b; @@ -1112,73 +1170,65 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; - - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c == 4) ? 13 : 1; - } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[0]; - addr += (c == 4) ? 13 : 1; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (c = 0; c < 16; c++) { + svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + addr &= svga->vram_mask; + } + } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + if (bpp) { + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = tgui->ext_gdc_regs[4]; + addr += (c == 4) ? 13 : 1; + addr &= svga->vram_mask; + } } - break; - - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *) &svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; + } else { + if (bpp) { + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; + addr += (c == 4) ? 13 : 1; + addr &= svga->vram_mask; + } } - break; - } + } + } else + svga_write_linear(addr, val, svga); } static void -tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) +tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; - int c; - uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; - uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; - uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + svga_t *svga = (svga_t *) priv; + const tgui_t *tgui = (tgui_t *) svga->priv; + int c; + int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); + uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; + uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; + uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; cycles -= video_timing_write_w; @@ -1186,96 +1236,108 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= ~0xf; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; val = (val >> 8) | (val << 8); - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c & 3) ? 1 : 13; - } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[0]; - addr += (c & 3) ? 1 : 13; - } - break; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (c = 0; c < 16; c++) { + svga->vram[addr] = tgui->copy_latch[c]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + if (bpp) { + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = tgui->ext_gdc_regs[4]; - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } } - break; + } else { + if (bpp) { + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *) &svga->vram[addr + c] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } } - break; - } + } + } else + svga_writew_linear(addr, val, svga); } static void -tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) +tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv) { - tgui_ext_linear_writew(addr, val, p); + svga_t *svga = (svga_t *) priv; + const tgui_t *tgui = (tgui_t *) svga->priv; + + cycles -= video_timing_write_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; + + addr = dword_remap(svga, addr); + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + + if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT | EXT_CTRL_LATCH_COPY)) { + tgui_ext_linear_writew(addr, val & 0xffff, priv); + tgui_ext_linear_writew(addr + 2, val >> 16, priv); + } else { + svga_writel_linear(addr, val, svga); + } } static void -tgui_ext_write(uint32_t addr, uint8_t val, void *p) +tgui_ext_write(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_write(addr, val, svga); } static void -tgui_ext_writew(uint32_t addr, uint16_t val, void *p) +tgui_ext_writew(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_writew(addr, val, svga); } static void -tgui_ext_writel(uint32_t addr, uint32_t val, void *p) +tgui_ext_writel(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_writel(addr, val, svga); } @@ -1325,35 +1387,33 @@ enum { #define WRITE(addr, dat) \ if (tgui->accel.bpp == 0) { \ svga->vram[(addr) &tgui->vram_mask] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; \ } else if (tgui->accel.bpp == 1) { \ vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else { \ vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ } static void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { - svga_t *svga = &tgui->svga; - uint32_t *pattern_data; - int x; - int y; - int c; - int d; - uint32_t out; - uint32_t src_dat = 0; - uint32_t dst_dat; - uint32_t pat_dat; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint32_t *vram_l = (uint32_t *) svga->vram; - uint8_t ger22lower = tgui->accel.ger22 & 0xff; - uint8_t ger22upper = (tgui->accel.ger22 >> 8) & 0xff; + svga_t *svga = &tgui->svga; + const uint32_t *pattern_data; + int x; + int y; + int c; + int d; + uint32_t out; + uint32_t src_dat = 0; + uint32_t dst_dat; + uint32_t pat_dat; + int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; + int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; + uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; if (tgui->accel.bpp == 0) { trans_col &= 0xff; @@ -1361,7 +1421,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) trans_col &= 0xffff; } - if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { + if ((count != -1) && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { count -= (tgui->accel.flags >> 24) & 7; cpu_dat <<= (tgui->accel.flags >> 24) & 7; } @@ -1409,39 +1469,25 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - switch (svga->hdisp) { - case 640: - case 1024: - case 1280: - tgui->accel.pitch = svga->hdisp; - break; - case 800: /*Disassembly of the TGUI9440/96x0 drivers shows that 800x600 is treated as 832 in the acceleration pitch (0x340 as horizontal display)*/ - tgui->accel.pitch = svga->hdisp + 32; - break; - case 1600: - tgui->accel.pitch = 2048; - break; - } + /* See Linux kernel drivers/video/tridentfb.c for the pitch */ + tgui->accel.pitch = svga->rowoffset; - switch (ger22lower) { - case 4: /*8-bit mode for modes up to 1024x768.*/ - case 9: /*15-bit and 16-bit modes.*/ - if (!(ger22upper & 0x01)) { - if (ger22upper == 0x00) - tgui->accel.pitch = 1024; - } + switch (svga->bpp) { + case 8: + case 24: + tgui->accel.pitch <<= 3; break; - case 8: /*8-bit mode for modes greater than 1024x768 and 24-bit mode for 640x480 (latter is TGUI9440AGi only).*/ - if (!(ger22upper & 0x01)) { - if (ger22upper == 0x00) { - if (svga->bpp == 24) - tgui->accel.pitch = 2048; - } - } + case 15: + case 16: + tgui->accel.pitch <<= 2; + break; + case 32: + tgui->accel.pitch <<= 1; break; } - - // pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); +#if 0 + pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); +#endif switch (tgui->accel.command) { case TGUI_BITBLT: @@ -1660,49 +1706,47 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) break; case TGUI_SCANLINE: - { - if (count == -1) { - tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); - tgui->accel.src = tgui->accel.src_old; + if (count == -1) { + tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); + tgui->accel.src = tgui->accel.src_old; - tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old; + tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old; - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y = tgui->accel.dst_y; - } + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y = tgui->accel.dst_y; + } - while (count--) { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); + while (count--) { + READ(tgui->accel.src, src_dat); + READ(tgui->accel.dst, dst_dat); - pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { - MIX(); + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); - WRITE(tgui->accel.dst, out); - } + WRITE(tgui->accel.dst, out); + } - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - tgui->accel.pat_y += ydir; - return; - } + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + tgui->accel.pat_y += ydir; + return; } } break; @@ -1711,11 +1755,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (count == -1) { tgui->accel.dx = tgui->accel.dst_x & 0xfff; tgui->accel.dy = tgui->accel.dst_y & 0xfff; - - if (tgui->accel.dst_x & 0x1000) - tgui->accel.dx |= ~0xfff; - if (tgui->accel.dst_y & 0x1000) - tgui->accel.dy |= ~0xfff; + tgui->accel.y = tgui->accel.size_y; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1731,99 +1771,74 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - // pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y); - while (count-- && (tgui->accel.y <= (tgui->accel.size_y))) { - // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - + while (count--) { /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) { READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - MIX(); WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } - if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) { + if (!tgui->accel.y) break; - } - if (tgui->accel.err >= (tgui->accel.size_y & 0xfff)) { - // pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y); - if ((tgui->accel.src_x >= 2048) && (tgui->accel.src_x < 4096)) - tgui->accel.err -= (4096 - tgui->accel.src_x); - else if ((tgui->accel.src_x >= 4096) && (tgui->accel.src_x < 32768)) - tgui->accel.err -= (32768 - tgui->accel.src_x); - else - tgui->accel.err += tgui->accel.src_x; + if (tgui->accel.size_x >= 0) { + tgui->accel.size_x += tgui->accel.src_x; /*Step minor axis*/ - switch (tgui->accel.flags & 0x700) { - case 0x300: - tgui->accel.dy--; + switch ((tgui->accel.flags >> 8) & 7) { + case 0: + case 2: + tgui->accel.dy++; break; - case 0x100: + case 1: + case 3: tgui->accel.dy--; break; - case 0x700: - tgui->accel.dx--; - break; - case 0x500: + case 4: + case 5: tgui->accel.dx++; break; - case 0x200: - tgui->accel.dy++; - break; - case 0x000: - tgui->accel.dy++; - break; - case 0x600: + case 6: + case 7: tgui->accel.dx--; break; - case 0x400: - tgui->accel.dx++; + + default: break; - } - } else { - // pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y); - tgui->accel.err += tgui->accel.src_y; - } + } + } else + tgui->accel.size_x += tgui->accel.src_y; /*Step major axis*/ - switch (tgui->accel.flags & 0x700) { - case 0x300: - tgui->accel.dx--; - break; - case 0x100: + switch ((tgui->accel.flags >> 8) & 7) { + case 0: + case 1: tgui->accel.dx++; break; - case 0x700: - tgui->accel.dy--; - break; - case 0x500: - tgui->accel.dy--; - break; - case 0x200: + case 2: + case 3: tgui->accel.dx--; break; - case 0x000: - tgui->accel.dx++; - break; - case 0x600: + case 4: + case 6: tgui->accel.dy++; break; - case 0x400: - tgui->accel.dy++; + case 5: + case 7: + tgui->accel.dy--; + break; + + default: break; } - tgui->accel.y++; + tgui->accel.y--; + tgui->accel.dx &= 0xfff; + tgui->accel.dy &= 0xfff; } break; @@ -1831,11 +1846,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (count == -1) { tgui->accel.dx = tgui->accel.dst_x & 0xfff; tgui->accel.dy = tgui->accel.dst_y & 0xfff; - - if (tgui->accel.dst_x & 0x1000) - tgui->accel.dx |= ~0xfff; - if (tgui->accel.dst_y & 0x1000) - tgui->accel.dy |= ~0xfff; + tgui->accel.y = tgui->accel.sv_size_y & 0xfff; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1851,26 +1862,19 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - while (count-- && (tgui->accel.y <= (tgui->accel.sv_size_y & 0xfff))) { - // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - + while (count--) { /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) { READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - MIX(); WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } - if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) + if (!tgui->accel.y) break; switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { @@ -1902,9 +1906,14 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.dx++; tgui->accel.dy++; break; + + default: + break; } - tgui->accel.y++; + tgui->accel.y--; + tgui->accel.dx &= 0xfff; + tgui->accel.dy &= 0xfff; } break; @@ -1915,11 +1924,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (count == -1) { tgui->accel.dx = tgui->accel.dst_x & 0xfff; tgui->accel.dy = tgui->accel.dst_y & 0xfff; - - if (tgui->accel.dst_x & 0x1000) - tgui->accel.dx |= ~0xfff; - if (tgui->accel.dst_y & 0x1000) - tgui->accel.dy |= ~0xfff; + tgui->accel.y = tgui->accel.size_y; tgui->accel.left = tgui->accel.src_x_clip & 0xfff; tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; @@ -1935,26 +1940,19 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - while (count-- && (tgui->accel.y <= (tgui->accel.size_y & 0xfff))) { - // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - + while (count--) { /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if (tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && ((tgui->accel.dx & 0xfff) >= tgui->accel.left) && ((tgui->accel.dx & 0xfff) <= tgui->accel.right) && ((tgui->accel.dy & 0xfff) >= tgui->accel.top) && ((tgui->accel.dy & 0xfff) <= tgui->accel.bottom))) { READ(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), dst_dat); pat_dat = tgui->accel.fg_col; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - MIX(); WRITE(tgui->accel.dx + (tgui->accel.dy * tgui->accel.pitch), out); } - if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) + if (!tgui->accel.y) break; switch ((tgui->accel.size_y >> 8) & 0xe0) { @@ -1986,61 +1984,65 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.dx++; tgui->accel.dy++; break; + + default: + break; } - tgui->accel.y++; + tgui->accel.y--; + tgui->accel.dx &= 0xfff; + tgui->accel.dy &= 0xfff; } break; + + default: + break; } } static void -tgui_accel_out(uint16_t addr, uint8_t val, void *p) +tgui_accel_out(uint16_t addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; + svga_t *svga = &tgui->svga; switch (addr) { case 0x2122: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: + switch (svga->bpp) { case 8: + case 24: tgui->accel.bpp = 0; break; - - case 9: - switch (tgui->svga.bpp) { - case 32: - tgui->accel.bpp = 3; - break; - default: - tgui->accel.bpp = 1; - break; - } + case 15: + case 16: + tgui->accel.bpp = 1; + break; + case 32: + tgui->accel.bpp = 3; break; - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; - - case 24: - tgui->accel.bpp = 0; - break; - - case 32: - tgui->accel.bpp = 3; - break; - } + default: break; } break; case 0x2123: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); + //pclog("Pitch IO23: val = %02x, rowoffset = %x.\n", tgui->accel.ger22, svga->crtc[0x13]); + switch (svga->bpp) { + case 8: + case 24: + tgui->accel.bpp = 0; + break; + case 15: + case 16: + tgui->accel.bpp = 1; + break; + case 32: + tgui->accel.bpp = 3; + break; + } break; case 0x2124: /*Command*/ @@ -2120,36 +2122,37 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); break; - case 0x213c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; + case 0x213c: /*Src X, Diagonal Step Constant*/ + tgui->accel.src_x = (tgui->accel.src_x & 0x3f00) | val; break; - case 0x213d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); + case 0x213d: /*Src X, Diagonal Step Constant*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + tgui->accel.src_x |= ~0x3fff; break; - case 0x213e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; + case 0x213e: /*Src Y, Axial Step Constant*/ + tgui->accel.src_y = (tgui->accel.src_y & 0x3f00) | val; break; - case 0x213f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); + case 0x213f: /*Src Y, Axial Step Constant*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + tgui->accel.src_y |= ~0x3fff; break; - case 0x2140: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; + case 0x2140: /*Size X, Line Error Term*/ + tgui->accel.size_x = (tgui->accel.size_x & 0x3f00) | val; break; - case 0x2141: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - tgui->accel.err = tgui->accel.size_x; - if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) - tgui->accel.err -= 4096; - else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) - tgui->accel.err -= 32768; + case 0x2141: /*Size X, Line Error Term*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + tgui->accel.size_x |= ~0x1fff; break; - case 0x2142: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + case 0x2142: /*Size Y, Major Axis Pixel Count*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xf00) | val; tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; break; - case 0x2143: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + case 0x2143: /*Size Y, Major Axis Pixel Count*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff) | ((val & 0x0f) << 8); tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); break; @@ -2335,21 +2338,24 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) case 0x21ff: tgui->accel.pattern[addr & 0x7f] = val; break; + + default: + break; } } static void -tgui_accel_out_w(uint16_t addr, uint16_t val, void *p) +tgui_accel_out_w(uint16_t addr, uint16_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; tgui_accel_out(addr, val, tgui); tgui_accel_out(addr + 1, val >> 8, tgui); } static void -tgui_accel_out_l(uint16_t addr, uint32_t val, void *p) +tgui_accel_out_l(uint16_t addr, uint32_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; switch (addr) { case 0x2124: /*Long version of Command and ROP together*/ @@ -2369,9 +2375,9 @@ tgui_accel_out_l(uint16_t addr, uint32_t val, void *p) } static uint8_t -tgui_accel_in(uint16_t addr, void *p) +tgui_accel_in(uint16_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + const tgui_t *tgui = (tgui_t *) priv; switch (addr) { case 0x2120: /*Status*/ @@ -2617,28 +2623,31 @@ tgui_accel_in(uint16_t addr, void *p) case 0x21fe: case 0x21ff: return tgui->accel.pattern[addr & 0x7f]; + + default: + break; } return 0; } static uint16_t -tgui_accel_in_w(uint16_t addr, void *p) +tgui_accel_in_w(uint16_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; return tgui_accel_in(addr, tgui) | (tgui_accel_in(addr + 1, tgui) << 8); } static uint32_t -tgui_accel_in_l(uint16_t addr, void *p) +tgui_accel_in_l(uint16_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; return tgui_accel_in_w(addr, tgui) | (tgui_accel_in_w(addr + 2, tgui) << 16); } static void -tgui_accel_write(uint32_t addr, uint8_t val, void *p) +tgui_accel_write(uint32_t addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; if ((svga->crtc[0x36] & 0x03) == 0x02) { @@ -2649,373 +2658,37 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) return; } - switch (addr & 0xff) { - case 0x22: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: - case 8: - tgui->accel.bpp = 0; - break; + tgui_accel_out((addr & 0xff) + 0x2100, val, tgui); +} - case 9: - switch (tgui->svga.bpp) { - case 32: - tgui->accel.bpp = 3; - break; - default: - tgui->accel.bpp = 1; - break; - } - break; +static void +tgui_accel_write_w(uint32_t addr, uint16_t val, void *priv) +{ + tgui_t *tgui = (tgui_t *) priv; - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; + tgui_accel_write(addr, val, tgui); + tgui_accel_write(addr + 1, val >> 8, tgui); +} - case 24: - tgui->accel.bpp = 0; - break; +static void +tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv) +{ + tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; - case 32: - tgui->accel.bpp = 3; - break; - } - break; + switch (addr & 0xff) { + case 0x24: /*Long version of Command and ROP together*/ + if ((svga->crtc[0x36] & 0x03) == 0x02) { + if ((addr & ~0xff) != 0xbff00) + return; + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + if ((addr & ~0xff) != 0xb7f00) + return; } - break; - - case 0x23: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); - break; - - case 0x24: /*Command*/ - tgui->accel.command = val; - tgui_accel_command(-1, 0, tgui); - break; - - case 0x27: /*ROP*/ - tgui->accel.rop = val; - tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); - break; - - case 0x28: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val; - break; - case 0x29: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8); - break; - case 0x2a: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16); - break; - case 0x2b: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24); - break; - - case 0x2c: /*Foreground colour*/ - case 0x78: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val; - break; - case 0x2d: /*Foreground colour*/ - case 0x79: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8); - break; - case 0x2e: /*Foreground colour*/ - case 0x7a: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x2f: /*Foreground colour*/ - case 0x7b: - tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24); - break; - - case 0x30: /*Background colour*/ - case 0x7c: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val; - break; - case 0x31: /*Background colour*/ - case 0x7d: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8); - break; - case 0x32: /*Background colour*/ - case 0x7e: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x33: /*Background colour*/ - case 0x7f: - tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24); - break; - - case 0x34: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val; - break; - case 0x35: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8); - break; - - case 0x38: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; - break; - case 0x39: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); - break; - case 0x3a: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; - break; - case 0x3b: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); - break; - - case 0x3c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; - break; - case 0x3d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); - break; - case 0x3e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; - break; - case 0x3f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); - break; - - case 0x40: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; - break; - case 0x41: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - tgui->accel.err = tgui->accel.size_x; - if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) - tgui->accel.err -= 4096; - else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) - tgui->accel.err -= 32768; - break; - case 0x42: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; - break; - case 0x43: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); - break; - - case 0x44: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffffff00) | val; - break; - case 0x45: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8); - break; - case 0x46: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16); - break; - case 0x47: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24); - break; - - case 0x48: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val; - break; - case 0x49: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8); - break; - case 0x4a: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val; - break; - case 0x4b: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8); - break; - - case 0x4c: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val; - break; - case 0x4d: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8); - break; - case 0x4e: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val; - break; - case 0x4f: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8); - break; - - case 0x68: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val; - break; - case 0x69: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8); - break; - case 0x6a: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16); - break; - case 0x6b: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24); - break; - - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - case 0xa0: - case 0xa1: - case 0xa2: - case 0xa3: - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7: - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3: - case 0xd4: - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - case 0xe0: - case 0xe1: - case 0xe2: - case 0xe3: - case 0xe4: - case 0xe5: - case 0xe6: - case 0xe7: - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: - case 0xec: - case 0xed: - case 0xee: - case 0xef: - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: - tgui->accel.pattern[addr & 0x7f] = val; - break; - } -} - -static void -tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) -{ - tgui_t *tgui = (tgui_t *) p; - - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); -} - -static void -tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) -{ - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; - - switch (addr & 0xff) { - case 0x24: /*Long version of Command and ROP together*/ - if ((svga->crtc[0x36] & 0x03) == 0x02) { - if ((addr & ~0xff) != 0xbff00) - return; - } else if ((svga->crtc[0x36] & 0x03) == 0x01) { - if ((addr & ~0xff) != 0xb7f00) - return; - } - tgui->accel.command = val & 0xff; - tgui->accel.rop = val >> 24; - tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33); - tgui_accel_command(-1, 0, tgui); + tgui->accel.command = val & 0xff; + tgui->accel.rop = val >> 24; + tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33); + tgui_accel_command(-1, 0, tgui); break; default: @@ -3026,10 +2699,10 @@ tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) } static uint8_t -tgui_accel_read(uint32_t addr, void *p) +tgui_accel_read(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; if ((svga->crtc[0x36] & 0x03) == 0x02) { if ((addr & ~0xff) != 0xbff00) @@ -3283,29 +2956,34 @@ tgui_accel_read(uint32_t addr, void *p) case 0xfe: case 0xff: return tgui->accel.pattern[addr & 0x7f]; + + default: + break; } return 0xff; } static uint16_t -tgui_accel_read_w(uint32_t addr, void *p) +tgui_accel_read_w(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; + return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); } static uint32_t -tgui_accel_read_l(uint32_t addr, void *p) +tgui_accel_read_l(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; + return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); } static void -tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) +tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; + svga_t *svga = (svga_t *) priv; + tgui_t *tgui = (tgui_t *) svga->priv; if (tgui->write_blitter) { tgui_accel_command(8, val << 24, tgui); @@ -3314,10 +2992,10 @@ tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) } static void -tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) +tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; + svga_t *svga = (svga_t *) priv; + tgui_t *tgui = (tgui_t *) svga->priv; if (tgui->write_blitter) tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); @@ -3326,10 +3004,10 @@ tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) } static void -tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) +tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) p; - tgui_t *tgui = (tgui_t *) svga->p; + svga_t *svga = (svga_t *) priv; + tgui_t *tgui = (tgui_t *) svga->priv; if (tgui->write_blitter) tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); @@ -3338,113 +3016,113 @@ tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) } static void -tgui_mmio_write(uint32_t addr, uint8_t val, void *p) +tgui_mmio_write(uint32_t addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out(addr, val, p); + tgui_accel_out(addr, val, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write(addr, val, p); + tgui_accel_write(addr, val, priv); else - tgui_out(addr, val, p); + tgui_out(addr, val, priv); } static void -tgui_mmio_write_w(uint32_t addr, uint16_t val, void *p) +tgui_mmio_write_w(uint32_t addr, uint16_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out_w(addr, val, p); + tgui_accel_out_w(addr, val, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write_w(addr, val, p); + tgui_accel_write_w(addr, val, priv); else { - tgui_out(addr, val & 0xff, p); - tgui_out(addr + 1, val >> 8, p); + tgui_out(addr, val & 0xff, priv); + tgui_out(addr + 1, val >> 8, priv); } } static void -tgui_mmio_write_l(uint32_t addr, uint32_t val, void *p) +tgui_mmio_write_l(uint32_t addr, uint32_t val, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out_l(addr, val, p); + tgui_accel_out_l(addr, val, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write_l(addr, val, p); + tgui_accel_write_l(addr, val, priv); else { - tgui_out(addr, val & 0xff, p); - tgui_out(addr + 1, val >> 8, p); - tgui_out(addr + 2, val >> 16, p); - tgui_out(addr + 3, val >> 24, p); + tgui_out(addr, val & 0xff, priv); + tgui_out(addr + 1, val >> 8, priv); + tgui_out(addr + 2, val >> 16, priv); + tgui_out(addr + 3, val >> 24, priv); } } static uint8_t -tgui_mmio_read(uint32_t addr, void *p) +tgui_mmio_read(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; uint8_t ret = 0xff; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in(addr, p); + ret = tgui_accel_in(addr, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read(addr, p); + ret = tgui_accel_read(addr, priv); else - ret = tgui_in(addr, p); + ret = tgui_in(addr, priv); return ret; } static uint16_t -tgui_mmio_read_w(uint32_t addr, void *p) +tgui_mmio_read_w(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; - uint16_t ret = 0xffff; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; + uint16_t ret = 0xffff; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in_w(addr, p); + ret = tgui_accel_in_w(addr, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read_w(addr, p); + ret = tgui_accel_read_w(addr, priv); else - ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8); + ret = tgui_in(addr, priv) | (tgui_in(addr + 1, priv) << 8); return ret; } static uint32_t -tgui_mmio_read_l(uint32_t addr, void *p) +tgui_mmio_read_l(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) p; - svga_t *svga = &tgui->svga; - uint32_t ret = 0xffffffff; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; + uint32_t ret = 0xffffffff; addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in_l(addr, p); + ret = tgui_accel_in_l(addr, priv); else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read_l(addr, p); + ret = tgui_accel_read_l(addr, priv); else - ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8) | (tgui_in(addr + 2, p) << 16) | (tgui_in(addr + 3, p) << 24); + ret = tgui_in(addr, priv) | (tgui_in(addr + 1, priv) << 8) | (tgui_in(addr + 2, priv) << 16) | (tgui_in(addr + 3, priv) << 24); return ret; } @@ -3470,11 +3148,14 @@ tgui_init(const device_t *info) bios_fn = ROM_TGUI_9400CXI; break; case TGUI_9440: - bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440; + if (tgui->pci) + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440_PCI; + else + bios_fn = ROM_TGUI_9440_VLB; break; case TGUI_9660: case TGUI_9680: - bios_fn = ROM_TGUI_96xx; + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_96xx; break; default: free(tgui); @@ -3484,7 +3165,7 @@ tgui_init(const device_t *info) tgui->has_bios = (bios_fn != NULL); if (tgui->has_bios) { - rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (tgui->pci) mem_mapping_disable(&tgui->bios_rom.mapping); } @@ -3510,16 +3191,19 @@ tgui_init(const device_t *info) mem_mapping_disable(&tgui->accel_mapping); mem_mapping_disable(&tgui->mmio_mapping); + if (tgui->vram_size == (2 << 20)) + svga->crtc[0x21] |= 0x10; + tgui_set_io(tgui); if (tgui->pci && (tgui->type >= TGUI_9440)) { if (tgui->has_bios) - tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + pci_add_card(PCI_ADD_NORMAL, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot); else - tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui); + pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot); } - tgui->pci_regs[PCI_REG_COMMAND] = 7; + tgui->pci_regs[PCI_REG_COMMAND] = 0x83; if (tgui->has_bios) { tgui->pci_regs[0x30] = 0x00; @@ -3544,9 +3228,15 @@ tgui9400cxi_available(void) } static int -tgui9440_available(void) +tgui9440_vlb_available(void) +{ + return rom_present(ROM_TGUI_9440_VLB); +} + +static int +tgui9440_pci_available(void) { - return rom_present(ROM_TGUI_9440); + return rom_present(ROM_TGUI_9440_PCI); } static int @@ -3556,9 +3246,9 @@ tgui96xx_available(void) } void -tgui_close(void *p) +tgui_close(void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_close(&tgui->svga); @@ -3571,19 +3261,19 @@ tgui_close(void *p) } void -tgui_speed_changed(void *p) +tgui_speed_changed(void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; svga_recalctimings(&tgui->svga); } void -tgui_force_redraw(void *p) +tgui_force_redraw(void *priv) { - tgui_t *tgui = (tgui_t *) p; + tgui_t *tgui = (tgui_t *) priv; - tgui->svga.fullchange = changeframecount; + tgui->svga.fullchange = tgui->svga.monitor->mon_changeframecount; } // clang-format off @@ -3664,7 +3354,7 @@ const device_t tgui9440_vlb_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_available }, + { .available = tgui9440_vlb_available }, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3678,7 +3368,7 @@ const device_t tgui9440_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_available }, + { .available = tgui9440_pci_available }, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3712,6 +3402,20 @@ const device_t tgui9660_pci_device = { .config = tgui96xx_config }; +const device_t tgui9660_onboard_pci_device = { + .name = "Trident TGUI 9660XGi On-Board PCI", + .internal_name = "tgui9660_onboard_pci", + .flags = DEVICE_PCI, + .local = TGUI_9660 | ONBOARD, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = tgui_speed_changed, + .force_redraw = tgui_force_redraw, + .config = tgui96xx_config +}; + const device_t tgui9680_pci_device = { .name = "Trident TGUI 9680XGi PCI", .internal_name = "tgui9680_pci", diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 32c37ca8bc..f23cb73967 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -91,7 +91,7 @@ vid_out(uint16_t addr, uint8_t val, void *priv) #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; + !(svga->miscout & 1)) addr ^= 0x60; #endif switch (addr) { @@ -137,6 +137,9 @@ vid_out(uint16_t addr, uint8_t val, void *priv) case 0x210a: ti->reg_210a = val; break; + + default: + break; } svga_out(addr, val, svga); @@ -151,7 +154,7 @@ vid_in(uint16_t addr, void *priv) #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; + !(svga->miscout & 1)) addr ^= 0x60; #endif switch (addr) { diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index 66c2ca9220..4108b9a4ed 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -27,6 +27,7 @@ #include <86box/mem.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> typedef struct tkd8001_ramdac_t { int state; @@ -34,9 +35,9 @@ typedef struct tkd8001_ramdac_t { } tkd8001_ramdac_t; void -tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv; switch (addr) { case 0x3C6: @@ -59,6 +60,9 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 7: svga->bpp = 16; break; + + default: + break; } return; } @@ -68,15 +72,18 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) +tkd8001_ramdac_in(uint16_t addr, void *priv, svga_t *svga) { - tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv; switch (addr) { case 0x3C6: @@ -89,12 +96,15 @@ tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } return svga_in(addr, svga); } static void * -tkd8001_ramdac_init(const device_t *info) +tkd8001_ramdac_init(UNUSED(const device_t *info)) { tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) malloc(sizeof(tkd8001_ramdac_t)); memset(ramdac, 0, sizeof(tkd8001_ramdac_t)); diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 5cac5fb063..591851016f 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -74,9 +74,9 @@ static uint8_t crtc_mask[0x40] = { static void tvga_recalcbanking(tvga_t *tvga); void -tvga_out(uint16_t addr, uint8_t val, void *p) +tvga_out(uint16_t addr, uint8_t val, void *priv) { - tvga_t *tvga = (tvga_t *) p; + tvga_t *tvga = (tvga_t *) priv; svga_t *svga = &tvga->svga; uint8_t old; @@ -111,6 +111,9 @@ tvga_out(uint16_t addr, uint8_t val, void *p) tvga_recalcbanking(tvga); } return; + + default: + break; } break; @@ -143,6 +146,9 @@ tvga_out(uint16_t addr, uint8_t val, void *p) svga->gdcreg[0xf] = val; tvga_recalcbanking(tvga); break; + + default: + break; } break; case 0x3D4: @@ -171,6 +177,9 @@ tvga_out(uint16_t addr, uint8_t val, void *p) case 0x1e: svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; break; + + default: + break; } return; case 0x3D8: @@ -194,14 +203,17 @@ tvga_out(uint16_t addr, uint8_t val, void *p) svga_recalctimings(svga); } break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -tvga_in(uint16_t addr, void *p) +tvga_in(uint16_t addr, void *priv) { - tvga_t *tvga = (tvga_t *) p; + tvga_t *tvga = (tvga_t *) priv; svga_t *svga = &tvga->svga; if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) @@ -241,6 +253,9 @@ tvga_in(uint16_t addr, void *p) return tvga->tvga_3d8; case 0x3d9: return tvga->tvga_3d9; + + default: + break; } return svga_in(addr, svga); } @@ -261,9 +276,9 @@ tvga_recalcbanking(tvga_t *tvga) void tvga_recalctimings(svga_t *svga) { - tvga_t *tvga = (tvga_t *) svga->p; - int clksel; - int high_res_256 = 0; + const tvga_t *tvga = (tvga_t *) svga->priv; + int clksel; + int high_res_256 = 0; if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, @@ -346,6 +361,9 @@ tvga_recalctimings(svga_t *svga) case 0xf: svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; break; + + default: + break; } if (tvga->card_id != TVGA8900CLD_ID) { @@ -378,6 +396,9 @@ tvga_recalctimings(svga_t *svga) svga->render = svga_render_24bpp_highres; svga->hdisp /= 3; break; + + default: + break; } svga->lowres = 0; } @@ -417,7 +438,7 @@ tvga_init(const device_t *info) return NULL; } - rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tvga->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(info, &tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, @@ -458,9 +479,9 @@ tvga9000b_nec_sv9000_available(void) } void -tvga_close(void *p) +tvga_close(void *priv) { - tvga_t *tvga = (tvga_t *) p; + tvga_t *tvga = (tvga_t *) priv; svga_close(&tvga->svga); @@ -468,17 +489,17 @@ tvga_close(void *p) } void -tvga_speed_changed(void *p) +tvga_speed_changed(void *priv) { - tvga_t *tvga = (tvga_t *) p; + tvga_t *tvga = (tvga_t *) priv; svga_recalctimings(&tvga->svga); } void -tvga_force_redraw(void *p) +tvga_force_redraw(void *priv) { - tvga_t *tvga = (tvga_t *) p; + tvga_t *tvga = (tvga_t *) priv; tvga->svga.fullchange = changeframecount; } diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 8a59f6e01d..b50d0406b2 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -27,15 +27,17 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_fallthrough.h> -typedef struct -{ +typedef struct tvp3026_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; + int hwc_y; + int hwc_x; uint8_t ind_idx; - uint8_t dcc, dc_init; + uint8_t dcc; + uint8_t dc_init; uint8_t ccr; uint8_t true_color; uint8_t latch_cntl; @@ -48,16 +50,22 @@ typedef struct uint8_t mode; uint8_t pll_addr; uint8_t clock_sel; - struct - { - uint8_t m, n, p; + struct { + uint8_t m; + uint8_t n; + uint8_t p; } pix, mem, loop; + uint8_t gpio_cntl; + uint8_t gpio_data; + uint8_t (*gpio_read)(uint8_t cntl, void *priv); + void (*gpio_write)(uint8_t cntl, uint8_t val, void *priv); + void *gpio_priv; } tvp3026_ramdac_t; static void tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) { - if ((ramdac->true_color & 0x80) == 0x80) { + if (ramdac->true_color & 0x80) { if (ramdac->mcr & 0x08) svga->bpp = 8; else @@ -83,15 +91,18 @@ tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) case 0x0f: svga->bpp = 24; break; + + default: + break; } } svga_recalctimings(svga); } void -tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; uint32_t o32; uint8_t *cd; uint16_t index; @@ -103,6 +114,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ ramdac->ind_idx = val; + fallthrough; case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ case 0x03: case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ @@ -147,6 +159,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t svga->dac_addr = (svga->dac_addr + 1) & 0xff; svga->dac_pos = 0; break; + + default: + break; } break; case 0x09: /* Direct Cursor Control (RS value = 1001) */ @@ -201,6 +216,16 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t ramdac->misc = val; svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; break; + case 0x2a: /* General-Purpose I/O Control */ + ramdac->gpio_cntl = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; + case 0x2b: /* General-Purpose I/O Data */ + ramdac->gpio_data = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; case 0x2c: /* PLL Address */ ramdac->pll_addr = val; break; @@ -215,6 +240,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->pix.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc); break; @@ -229,6 +257,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->mem.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3); break; @@ -243,12 +274,18 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->loop.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); break; case 0x39: /* MCLK/Loop Clock Control */ ramdac->mclk = val; break; + + default: + break; } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -273,17 +310,20 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; + + default: + break; } return; } uint8_t -tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; uint8_t temp = 0xff; - uint8_t *cd; + const uint8_t *cd; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -327,6 +367,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) else temp = ramdac->extpal[index].b & 0x3f; break; + + default: + break; } break; case 0x09: /* Direct Cursor Control (RS value = 1001) */ @@ -361,6 +404,16 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x1e: /* Miscellaneous Control */ temp = ramdac->misc; break; + case 0x2a: /* General-Purpose I/O Control */ + temp = ramdac->gpio_cntl; + break; + case 0x2b: /* General-Purpose I/O Data */ + if (ramdac->gpio_read) { + temp = 0xe0 | (ramdac->gpio_cntl & 0x1f); /* keep upper bits untouched */ + ramdac->gpio_data = (ramdac->gpio_data & temp) | (ramdac->gpio_read(ramdac->gpio_cntl, ramdac->gpio_priv) & ~temp); + } + temp = ramdac->gpio_data; + break; case 0x2c: /* PLL Address */ temp = ramdac->pll_addr; break; @@ -378,6 +431,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 3: temp = 0x40; /*PLL locked to frequency*/ break; + + default: + break; } break; case 0x2e: /* Memory Clock PLL Data */ @@ -394,6 +450,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 3: temp = 0x40; /*PLL locked to frequency*/ break; + + default: + break; } break; case 0x2f: /* Loop Clock PLL Data */ @@ -407,6 +466,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 2: temp = ramdac->loop.p; break; + + default: + break; } break; case 0x39: /* MCLK/Loop Clock Control */ @@ -415,6 +477,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x3f: /* ID */ temp = 0x26; break; + + default: + break; } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -436,17 +501,52 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x0f: /* Cursor Y High Register (RS value = 1111) */ temp = (ramdac->hwc_y >> 8) & 0xff; break; + + default: + break; } return temp; } void -tvp3026_recalctimings(void *p, svga_t *svga) +tvp3026_recalctimings(void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; - svga->interlace = (ramdac->ccr & 0x40); + svga->interlace = !!(ramdac->ccr & 0x40); + /* TODO: Figure out gamma correction for 15/16 bpp color. */ + svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); + + if (!(ramdac->clock_sel & 0x70)) { + if (ramdac->mcr != 0x98) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } +} + +uint32_t +tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; } void @@ -466,7 +566,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) uint32_t clr2; uint32_t clr3; uint32_t *p; - uint8_t *cd; + const uint8_t *cd; tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; @@ -497,7 +597,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) comb = (b0 | (b1 << 1)); y_pos = displine; - x_pos = offset + svga->x_add; + x_pos = (offset + svga->x_add) & 2047; p = svga->monitor->target_buffer->line[y_pos]; if (offset >= svga->dac_hwcursor_latch.x) { @@ -513,6 +613,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr3; break; + + default: + break; } break; case 2: /* XGA */ @@ -526,6 +629,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 3: /* X-Windows */ @@ -536,8 +642,14 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr2; break; + + default: + break; } break; + + default: + break; } } offset++; @@ -550,14 +662,14 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) } float -tvp3026_getclock(int clock, void *p) +tvp3026_getclock(int clock, void *priv) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; - int n; - int m; - int pl; - float f_vco; - float f_pll; + const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + int n; + int m; + int pl; + float f_vco; + float f_pll; if (clock == 0) return 25175000.0; @@ -569,12 +681,24 @@ tvp3026_getclock(int clock, void *p) n = ramdac->pix.n & 0x3f; m = ramdac->pix.m & 0x3f; pl = ramdac->pix.p & 0x03; - f_vco = 8.0 * 14318184 * (float) (65 - m) / (float) (65 - n); + f_vco = 8.0f * 14318184 * (float) (65 - m) / (float) (65 - n); f_pll = f_vco / (float) (1 << pl); return f_pll; } +void +tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), + void (*write)(uint8_t cntl, uint8_t val, void *priv), + void *cb_priv, void *priv) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + + ramdac->gpio_read = read; + ramdac->gpio_write = write; + ramdac->gpio_priv = cb_priv; +} + void * tvp3026_ramdac_init(const device_t *info) { diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index ac26c2b5d8..8b2e761a3a 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -35,9 +35,9 @@ static video_timings_t timing_ps1_svga_isa = { .type = VIDEO_ISA, .write_b = 6, static video_timings_t timing_ps1_svga_mca = { .type = VIDEO_MCA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; void -vga_out(uint16_t addr, uint8_t val, void *p) +vga_out(uint16_t addr, uint8_t val, void *priv) { - vga_t *vga = (vga_t *) p; + vga_t *vga = (vga_t *) priv; svga_t *svga = &vga->svga; uint8_t old; @@ -69,14 +69,17 @@ vga_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } uint8_t -vga_in(uint16_t addr, void *p) +vga_in(uint16_t addr, void *priv) { - vga_t *vga = (vga_t *) p; + vga_t *vga = (vga_t *) priv; svga_t *svga = &vga->svga; uint8_t temp; @@ -157,9 +160,9 @@ vga_available(void) } void -vga_close(void *p) +vga_close(void *priv) { - vga_t *vga = (vga_t *) p; + vga_t *vga = (vga_t *) priv; svga_close(&vga->svga); @@ -167,23 +170,23 @@ vga_close(void *p) } void -vga_speed_changed(void *p) +vga_speed_changed(void *priv) { - vga_t *vga = (vga_t *) p; + vga_t *vga = (vga_t *) priv; svga_recalctimings(&vga->svga); } void -vga_force_redraw(void *p) +vga_force_redraw(void *priv) { - vga_t *vga = (vga_t *) p; + vga_t *vga = (vga_t *) priv; vga->svga.fullchange = changeframecount; } const device_t vga_device = { - .name = "VGA", + .name = "IBM VGA", .internal_name = "vga", .flags = DEVICE_ISA, .local = 0, @@ -197,7 +200,7 @@ const device_t vga_device = { }; const device_t ps1vga_device = { - .name = "PS/1 VGA", + .name = "IBM PS/1 VGA", .internal_name = "ps1vga", .flags = DEVICE_ISA, .local = 0, @@ -211,7 +214,7 @@ const device_t ps1vga_device = { }; const device_t ps1vga_mca_device = { - .name = "PS/1 VGA", + .name = "IBM PS/1 VGA", .internal_name = "ps1vga_mca", .flags = DEVICE_MCA, .local = 0, diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 6544246be5..734179fa9b 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -149,9 +149,9 @@ voodoo_recalc(voodoo_t *voodoo) } static uint16_t -voodoo_readw(uint32_t addr, void *p) +voodoo_readw(uint32_t addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; addr &= 0xffffff; @@ -160,8 +160,8 @@ voodoo_readw(uint32_t addr, void *p) if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ { if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + const voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; if (y & 1) voodoo = set->voodoos[1]; @@ -184,9 +184,9 @@ voodoo_readw(uint32_t addr, void *p) } static uint32_t -voodoo_readl(uint32_t addr, void *p) +voodoo_readl(uint32_t addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; uint32_t temp = 0xffffffff; int fifo_size; voodoo->rd_count++; @@ -194,13 +194,12 @@ voodoo_readl(uint32_t addr, void *p) cycles -= voodoo->read_time; - if (addr & 0x800000) /*Texture*/ - { + if (addr & 0x800000) { /*Texture*/ } else if (addr & 0x400000) /*Framebuffer*/ { if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + const voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; if (y & 1) voodoo = set->voodoos[1]; @@ -394,9 +393,9 @@ voodoo_readl(uint32_t addr, void *p) } static void -voodoo_writew(uint32_t addr, uint16_t val, void *p) +voodoo_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; voodoo->wr_count++; addr &= 0xffffff; @@ -407,9 +406,9 @@ voodoo_writew(uint32_t addr, uint16_t val, void *p) } static void -voodoo_writel(uint32_t addr, uint32_t val, void *p) +voodoo_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; voodoo->wr_count++; @@ -429,7 +428,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) { voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { - // voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); +#if 0 + voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); +#endif *(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) @@ -492,7 +493,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->initEnable & 0x01) { voodoo->fbiInit4 = val; voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); - // voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); +#if 0 + voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); +#endif } break; case SST_backPorch: @@ -538,7 +541,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); - // voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); +#if 0 + voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); +#endif } break; case SST_fbiInit2: @@ -590,6 +595,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) case 0x0b: voodoo->dac_readdata = 0x79; break; + + default: + break; } } else voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; @@ -599,7 +607,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; else voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); - // voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); +#if 0 + voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); +#endif voodoo->dac_reg_ff = !voodoo->dac_reg_ff; if (!voodoo->dac_reg_ff) voodoo->dac_data[4]++; @@ -642,7 +652,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_cmdFifoBaseAddr: voodoo->cmdfifo_base = (val & 0x3ff) << 12; voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; - // voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +#if 0 + voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +#endif break; case SST_cmdFifoRdPtr: @@ -670,32 +682,32 @@ voodoo_writel(uint32_t addr, uint32_t val, void *p) } static uint16_t -voodoo_snoop_readw(uint32_t addr, void *p) +voodoo_snoop_readw(uint32_t addr, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) p; + const voodoo_set_t *set = (voodoo_set_t *) priv; return voodoo_readw(addr, set->voodoos[0]); } static uint32_t -voodoo_snoop_readl(uint32_t addr, void *p) +voodoo_snoop_readl(uint32_t addr, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) p; + const voodoo_set_t *set = (voodoo_set_t *) priv; return voodoo_readl(addr, set->voodoos[0]); } static void -voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) +voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) p; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writew(addr, val, set->voodoos[0]); voodoo_writew(addr, val, set->voodoos[1]); } static void -voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) +voodoo_snoop_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) p; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writel(addr, val, set->voodoos[0]); voodoo_writel(addr, val, set->voodoos[1]); @@ -747,18 +759,20 @@ voodoo_recalcmapping(voodoo_set_t *set) } uint8_t -voodoo_pci_read(int func, int addr, void *p) +voodoo_pci_read(int func, int addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + const voodoo_t *voodoo = (voodoo_t *) priv; if (func) return 0; - // voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); +#if 0 + voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); +#endif switch (addr) { case 0x00: - return 0x1a; /*3dfx*/ + return 0x1a; /*3Dfx*/ case 0x01: return 0x12; @@ -801,19 +815,24 @@ voodoo_pci_read(int func, int addr, void *p) return (voodoo->initEnable >> 16) & 0xff; case 0x43: return (voodoo->initEnable >> 24) & 0xff; + + default: + break; } return 0; } void -voodoo_pci_write(int func, int addr, uint8_t val, void *p) +voodoo_pci_write(int func, int addr, uint8_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; if (func) return; - // voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); +#if 0 + voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); +#endif switch (addr) { case 0x04: @@ -840,13 +859,16 @@ voodoo_pci_write(int func, int addr, uint8_t val, void *p) voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); voodoo_recalcmapping(voodoo->set); break; + + default: + break; } } static void -voodoo_speed_changed(void *p) +voodoo_speed_changed(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) p; + const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; voodoo_pixelclock_update(voodoo_set->voodoos[0]); voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); @@ -858,13 +880,15 @@ voodoo_speed_changed(void *p) voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); } - // voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); +#if 0 + voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); +#endif } static void -voodoo_force_blit(void *p) +voodoo_force_blit(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) p; + const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex); if (voodoo_set->voodoos[0]->can_blit) { @@ -910,6 +934,9 @@ voodoo_card_init(void) case VOODOO_2: voodoo->dual_tmus = 1; break; + + default: + break; } if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ @@ -917,7 +944,7 @@ voodoo_card_init(void) else voodoo_generate_filter_v1(voodoo); - pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); + pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo, &voodoo->pci_slot); mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); @@ -1157,7 +1184,7 @@ voodoo_2d3d_card_init(int type) } void * -voodoo_init(const device_t *info) +voodoo_init(UNUSED(const device_t *info)) { voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); uint32_t tmuConfig = 1; @@ -1199,6 +1226,9 @@ voodoo_init(const device_t *info) case VOODOO_2: tmuConfig = 1 | (3 << 6); break; + + default: + break; } voodoo_set->voodoos[0]->tmuConfig = tmuConfig; @@ -1261,9 +1291,9 @@ voodoo_card_close(voodoo_t *voodoo) } void -voodoo_close(void *p) +voodoo_close(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) p; + voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; if (voodoo_set->nr_cards == 2) voodoo_card_close(voodoo_set->voodoos[1]); @@ -1280,7 +1310,7 @@ static const device_config_t voodoo_config[] = { .type = CONFIG_SELECTION, .selection = { { - .description = "Voodoo Graphics", + .description = "3Dfx Voodoo Graphics", .value = VOODOO_1 }, { @@ -1288,7 +1318,7 @@ static const device_config_t voodoo_config[] = { .value = VOODOO_SB50 }, { - .description = "Voodoo 2", + .description = "3Dfx Voodoo 2", .value = VOODOO_2 }, { @@ -1397,7 +1427,7 @@ static const device_config_t voodoo_config[] = { }; const device_t voodoo_device = { - .name = "3DFX Voodoo Graphics", + .name = "3Dfx Voodoo Graphics", .internal_name = "voodoo", .flags = DEVICE_PCI, .local = 0, diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d2e57de814..098e919d48 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -142,8 +142,11 @@ typedef struct banshee_t { int desktop_y; uint32_t desktop_stride_tiled; - int type, card, agp, has_bios; - int vblank_irq; + int type, agp; + int has_bios, vblank_irq; + + uint8_t pci_slot; + uint8_t irq_state; void *i2c, *i2c_ddc, *ddc; } banshee_t; @@ -208,6 +211,7 @@ enum { Agp_agpGraphicsStride = 0x10, }; +#define VGAINIT0_RAMDAC_8BIT (1 << 2) #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) #define VIDPROCCFG_VIDPROC_ENABLE (1 << 0) @@ -215,7 +219,9 @@ enum { #define VIDPROCCFG_INTERLACE (1 << 3) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_DESKTOP_CLUT_BYPASS (1 << 10) #define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) +#define VIDPROCCFG_DESKTOP_CLUT_SEL (1 << 12) #define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) @@ -306,16 +312,16 @@ static void banshee_update_irqs(banshee_t *banshee) { if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) { - pci_set_irq(banshee->card, PCI_INTA); + pci_set_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state); } else { - pci_clear_irq(banshee->card, PCI_INTA); + pci_clear_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state); } } static void banshee_vblank_start(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->p; + banshee_t *banshee = (banshee_t *) svga->priv; if (banshee->vblank_irq >= 0) { banshee->vblank_irq = 1; banshee_update_irqs(banshee); @@ -323,9 +329,9 @@ banshee_vblank_start(svga_t *svga) } static void -banshee_out(uint16_t addr, uint8_t val, void *p) +banshee_out(uint16_t addr, uint8_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; svga_t *svga = &banshee->svga; uint8_t old; @@ -370,18 +376,24 @@ banshee_out(uint16_t addr, uint8_t val, void *p) } } break; + + default: + break; } svga_out(addr, val, svga); } static uint8_t -banshee_in(uint16_t addr, void *p) +banshee_in(uint16_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; svga_t *svga = &banshee->svga; uint8_t temp; - // if (addr != 0x3da) banshee_log("banshee_in : %04X ", addr); +#if 0 + if (addr != 0x3da) + banshee_log("banshee_in : %04X ", addr); +#endif if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -405,7 +417,10 @@ banshee_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } - // if (addr != 0x3da) banshee_log("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); +#if 0 + if (addr != 0x3da) + banshee_log("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); +#endif return temp; } @@ -424,8 +439,7 @@ banshee_updatemapping(banshee_t *banshee) } banshee_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { + switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/ case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -442,6 +456,9 @@ banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } banshee_log("Linear framebuffer %08X ", banshee->memBaseAddr1); @@ -451,11 +468,37 @@ banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } +uint32_t +banshee_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + banshee_t *banshee = (banshee_t *) svga->priv; + uint32_t ret = 0x00000000; + uint16_t src_b = (color & 0x1f) << 3; + uint16_t src_g = (color & 0x7e0) >> 3; + uint16_t src_r = (color & 0xf800) >> 8; + + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_CLUT_SEL) { + src_b += 256; + src_g += 256; + src_r += 256; + } + + if (svga->lut_map) { + uint8_t b = getcolr(svga->pallook[src_b]); + uint8_t g = getcolg(svga->pallook[src_g]); + uint8_t r = getcolb(svga->pallook[src_r]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } else + ret = video_16to32[color]; + + return ret; +} + static void banshee_render_16bpp_tiled(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->p; - uint32_t *p = &((uint32_t *) svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; + banshee_t *banshee = (banshee_t *) svga->priv; + uint32_t *p = &(svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; uint32_t addr; int drawn = 0; @@ -471,10 +514,10 @@ banshee_render_16bpp_tiled(svga_t *svga) if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; if (svga->changedvram[addr >> 12] || svga->fullchange) { - uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; + const uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; for (uint8_t xx = 0; xx < 64; xx++) - *p++ = video_16to32[*vram_p++]; + *p++ = banshee_conv_16to32(svga, *vram_p++, 16); drawn = 1; } else @@ -494,13 +537,13 @@ banshee_render_16bpp_tiled(svga_t *svga) static void banshee_recalctimings(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *) svga->priv; + const voodoo_t *voodoo = banshee->voodoo; /*7 R/W Horizontal Retrace End bit 5. - 6 R/W Horizontal Retrace Start bit 8 0x4 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 + 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! 3 R/W Reserved. - 2 R/W Horizontal Display Enable End bit 8. 0x1 1 R/W Reserved. - @@ -509,6 +552,44 @@ banshee_recalctimings(svga_t *svga) svga->htotal += 0x100; if (svga->crtc[0x1a] & 0x04) svga->hdisp += 0x100; + + if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE) { + /* Video processing mode - assume timings akin to Cirrus' special blanking mode, + that is, no overscan and relying on display end to blank. */ + if (banshee->vgaInit0 & 0x40) { + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + + (((svga->crtc[0x1a] & 0x04) >> 2) << 8); + svga->hblank_end_mask = 0x0000007f; + } else { + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/; + svga->hblank_end_mask = 0x0000003f; + } + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; + + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + + svga->linedbl = 0; + } else { + if (banshee->vgaInit0 & 0x40) { + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2]; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((svga->crtc[0x1a] & 0x20) >> 5) << 6); + svga->hblank_end_mask = 0x0000007f; + } else { + svga->hblankstart = svga->crtc[2]; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5); + svga->hblank_end_mask = 0x0000003f; + } + } + /*6 R/W Vertical Retrace Start bit 10 0x10 5 R/W Reserved. - 4 R/W Vertical Blank Start bit 10. 0x15 @@ -524,7 +605,10 @@ banshee_recalctimings(svga_t *svga) svga->vblankstart += 0x400; if (svga->crtc[0x1b] & 0x40) svga->vsyncstart += 0x400; - // banshee_log("svga->hdisp=%i\n", svga->hdisp); + +#if 0 + banshee_log("svga->hdisp=%i\n", svga->hdisp); +#endif svga->interlace = 0; @@ -559,14 +643,16 @@ banshee_recalctimings(svga_t *svga) svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; svga->ma_latch = banshee->vidDesktopStartAddr >> 2; banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; - // banshee_log("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); +#if 0 + banshee_log("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); +#endif svga->char_width = 8; svga->split = 99999; if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { svga->hdisp *= 2; - svga->htotal *= 2; + svga->dots_per_clock *= 2; } svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE); @@ -583,11 +669,13 @@ banshee_recalctimings(svga_t *svga) if (svga->overlay.cur_xsize <= 0 || svga->overlay.cur_ysize <= 0) svga->overlay.ena = 0; if (svga->overlay.ena) { - /* banshee_log("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", - voodoo->overlay.start_x, voodoo->overlay.start_y, - voodoo->overlay.end_x, voodoo->overlay.end_y, - voodoo->overlay.size_x, voodoo->overlay.size_y, - svga->overlay.pitch);*/ +#if 0 + banshee_log("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", + voodoo->overlay.start_x, voodoo->overlay.start_y, + voodoo->overlay.end_x, voodoo->overlay.end_y, + voodoo->overlay.size_x, voodoo->overlay.size_y, + svga->overlay.pitch); +#endif if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) { /*Overlay is full screen, so don't bother rendering the desktop behind it*/ @@ -596,7 +684,9 @@ banshee_recalctimings(svga_t *svga) } } } else { - // banshee_log("Normal shift out\n"); +#if 0 + banshee_log("Normal shift out\n"); +#endif svga->bpp = 8; } @@ -609,19 +699,27 @@ banshee_recalctimings(svga_t *svga) double freq = (((double) n + 2) / (((double) m + 2) * (double) (1 << k))) * 14318184.0; svga->clock = (cpuclock * (float) (1ULL << 32)) / freq; - // svga->clock = cpuclock / freq; +#if 0 + svga->clock = cpuclock / freq; +#endif - // banshee_log("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); +#if 0 + banshee_log("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); +#endif } } static void -banshee_ext_out(uint16_t addr, uint8_t val, void *p) +banshee_ext_out(uint16_t addr, uint8_t val, void *priv) { - // banshee_t *banshee = (banshee_t *)p; - // svga_t *svga = &banshee->svga; +#if 0 + banshee_t *banshee = (banshee_t *)priv; + svga_t *svga = &banshee->svga; +#endif - // banshee_log("banshee_ext_out: addr=%04x val=%02x\n", addr, val); +#if 0 + banshee_log("banshee_ext_out: addr=%04x val=%02x\n", addr, val); +#endif switch (addr & 0xff) { case 0xb0: @@ -672,7 +770,7 @@ banshee_ext_out(uint16_t addr, uint8_t val, void *p) case 0xdd: case 0xde: case 0xdf: - banshee_out((addr & 0xff) + 0x300, val, p); + banshee_out((addr & 0xff) + 0x300, val, priv); break; default: @@ -680,13 +778,15 @@ banshee_ext_out(uint16_t addr, uint8_t val, void *p) } } static void -banshee_ext_outl(uint16_t addr, uint32_t val, void *p) +banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; - // banshee_log("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); +#if 0 + banshee_log("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); +#endif switch (addr & 0xff) { case Init_pciInit0: @@ -698,7 +798,9 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Init_lfbMemoryConfig: banshee->lfbMemoryConfig = val; - // banshee_log("lfbMemoryConfig=%08x\n", val); +#if 0 + banshee_log("lfbMemoryConfig=%08x\n", val); +#endif voodoo->tile_base = (val & 0x1fff) << 12; voodoo->tile_stride = 1024 << ((val >> 13) & 7); voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); @@ -731,6 +833,8 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) break; case Init_vgaInit0: banshee->vgaInit0 = val; + svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT)); + svga_recalctimings(svga); break; case Init_vgaInit1: banshee->vgaInit1 = val; @@ -764,10 +868,13 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_vidProcCfg: banshee->vidProcCfg = val; - // banshee_log("vidProcCfg=%08x\n", val); +#if 0 + banshee_log("vidProcCfg=%08x\n", val); +#endif banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; svga->fullchange = changeframecount; + svga->lut_map = !(val & VIDPROCCFG_DESKTOP_CLUT_BYPASS) && (svga->bpp < 24); svga_recalctimings(svga); break; @@ -797,7 +904,9 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); svga->hwcursor.cur_xsize = 64; svga->hwcursor.cur_ysize = 64; - // banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); +#if 0 + banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); +#endif break; case Video_hwCurC0: banshee->hwCurC0 = val; @@ -808,7 +917,9 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_vidSerialParallelPort: banshee->vidSerialParallelPort = val; - // banshee_log("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); +#if 0 + banshee_log("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); +#endif i2c_gpio_set(banshee->i2c_ddc, !!(val & VIDSERIAL_DDC_DCK_W), !!(val & VIDSERIAL_DDC_DDA_W)); i2c_gpio_set(banshee->i2c, !!(val & VIDSERIAL_I2C_SCK_W), !!(val & VIDSERIAL_I2C_SDA_W)); break; @@ -836,16 +947,22 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) break; case Video_vidOverlayDudx: voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; - // banshee_log("vidOverlayDudx=%08x\n", val); +#if 0 + banshee_log("vidOverlayDudx=%08x\n", val); +#endif break; case Video_vidOverlayDudxOffsetSrcWidth: voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; - // banshee_log("vidOverlayDudxOffsetSrcWidth=%08x\n", val); +#if 0 + banshee_log("vidOverlayDudxOffsetSrcWidth=%08x\n", val); +#endif break; case Video_vidOverlayDvdy: voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; - // banshee_log("vidOverlayDvdy=%08x\n", val); +#if 0 + banshee_log("vidOverlayDvdy=%08x\n", val); +#endif break; case Video_vidOverlayDvdyOffset: voodoo->overlay.vidOverlayDvdyOffset = val; @@ -853,26 +970,35 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_vidDesktopStartAddr: banshee->vidDesktopStartAddr = val & 0xffffff; - // banshee_log("vidDesktopStartAddr=%08x\n", val); +#if 0 + banshee_log("vidDesktopStartAddr=%08x\n", val); +#endif svga->fullchange = changeframecount; svga_recalctimings(svga); break; case Video_vidDesktopOverlayStride: banshee->vidDesktopOverlayStride = val; - // banshee_log("vidDesktopOverlayStride=%08x\n", val); +#if 0 + banshee_log("vidDesktopOverlayStride=%08x\n", val); +#endif svga->fullchange = changeframecount; svga_recalctimings(svga); break; - // default: - // fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); + default: +#if 0 + fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); +#endif + break; } } static uint8_t -banshee_ext_in(uint16_t addr, void *p) +banshee_ext_in(uint16_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - // svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; +#if 0 + svga_t *svga = &banshee->svga; +#endif uint8_t ret = 0xff; switch (addr & 0xff) { @@ -881,7 +1007,9 @@ banshee_ext_in(uint16_t addr, void *p) case Init_status + 2: case Init_status + 3: ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; - // banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); +#if 0 + banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); +#endif break; case 0xb0: @@ -932,7 +1060,7 @@ banshee_ext_in(uint16_t addr, void *p) case 0xdd: case 0xde: case 0xdf: - ret = banshee_in((addr & 0xff) + 0x300, p); + ret = banshee_in((addr & 0xff) + 0x300, priv); break; default: @@ -948,15 +1076,14 @@ banshee_ext_in(uint16_t addr, void *p) static uint32_t banshee_status(banshee_t *banshee) { - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; - uint32_t ret; + voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + uint32_t ret = 0; - ret = 0; if (fifo_entries < 0x20) ret |= 0x1f - fifo_entries; else @@ -979,25 +1106,29 @@ banshee_status(banshee_t *banshee) if (!voodoo->voodoo_busy) voodoo_wake_fifo_thread(voodoo); - // banshee_log("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); +#if 0 + banshee_log("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); +#endif return ret; } static uint32_t -banshee_ext_inl(uint16_t addr, void *p) +banshee_ext_inl(uint16_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - uint32_t ret = 0xffffffff; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; + uint32_t ret = 0xffffffff; cycles -= voodoo->read_time; switch (addr & 0xff) { case Init_status: ret = banshee_status(banshee); - // banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); +#if 0 + banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); +#endif break; case Init_pciInit0: ret = banshee->pciInit0; @@ -1090,7 +1221,9 @@ banshee_ext_inl(uint16_t addr, void *p) if (i2c_gpio_get_sda(banshee->i2c)) ret |= VIDSERIAL_I2C_SDA_R; } - // banshee_log("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); +#if 0 + banshee_log("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); +#endif break; case Video_vidScreenSize: @@ -1135,27 +1268,31 @@ banshee_ext_inl(uint16_t addr, void *p) return ret; } -static uint32_t banshee_reg_readl(uint32_t addr, void *p); +static uint32_t banshee_reg_readl(uint32_t addr, void *priv); static uint8_t -banshee_reg_read(uint32_t addr, void *p) +banshee_reg_read(uint32_t addr, void *priv) { - // banshee_log("banshee_reg_read: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 3)); +#if 0 + banshee_log("banshee_reg_read: addr=%08x\n", addr); +#endif + return banshee_reg_readl(addr & ~3, priv) >> (8 * (addr & 3)); } static uint16_t -banshee_reg_readw(uint32_t addr, void *p) +banshee_reg_readw(uint32_t addr, void *priv) { - // banshee_log("banshee_reg_readw: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 2)); +#if 0 + banshee_log("banshee_reg_readw: addr=%08x\n", addr); +#endif + return banshee_reg_readl(addr & ~3, priv) >> (8 * (addr & 2)); } static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) { - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; + const voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; switch (addr & 0x1fc) { case Agp_agpHostAddressLow: @@ -1212,9 +1349,9 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) } static uint32_t -banshee_reg_readl(uint32_t addr, void *p) +banshee_reg_readl(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; uint32_t ret = 0xffffffff; @@ -1361,6 +1498,9 @@ banshee_reg_readl(uint32_t addr, void *p) break; } break; + + default: + break; } #if 0 @@ -1372,7 +1512,7 @@ banshee_reg_readl(uint32_t addr, void *p) } static void -banshee_reg_write(uint32_t addr, uint8_t val, void *p) +banshee_reg_write(UNUSED(uint32_t addr), UNUSED(uint8_t val), UNUSED(void *priv)) { #if 0 banshee_log("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); @@ -1380,9 +1520,9 @@ banshee_reg_write(uint32_t addr, uint8_t val, void *p) } static void -banshee_reg_writew(uint32_t addr, uint16_t val, void *p) +banshee_reg_writew(uint32_t addr, uint16_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; cycles -= voodoo->write_time; @@ -1409,6 +1549,9 @@ banshee_reg_writew(uint32_t addr, uint16_t val, void *p) case 0x1f00000: voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); break; + + default: + break; } } @@ -1498,9 +1641,9 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) } static void -banshee_reg_writel(uint32_t addr, uint32_t val, void *p) +banshee_reg_writel(uint32_t addr, uint32_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; if (addr == voodoo->last_write_addr + 4) @@ -1621,15 +1764,18 @@ banshee_reg_writel(uint32_t addr, uint32_t val, void *p) case 0x1f00000: voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); break; + + default: + break; } } static uint8_t -banshee_read_linear(uint32_t addr, void *p) +banshee_read_linear(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; cycles -= voodoo->read_time; @@ -1663,14 +1809,14 @@ banshee_read_linear(uint32_t addr, void *p) } static uint16_t -banshee_read_linear_w(uint32_t addr, void *p) +banshee_read_linear_w(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 1) - return banshee_read_linear(addr, p) | (banshee_read_linear(addr + 1, p) << 8); + return banshee_read_linear(addr, priv) | (banshee_read_linear(addr + 1, priv) << 8); cycles -= voodoo->read_time; if ((banshee->pci_regs[0x30] & 0x01) && addr >= banshee->bios_rom.mapping.base && addr < (banshee->bios_rom.mapping.base + banshee->bios_rom.sz)) { @@ -1703,14 +1849,14 @@ banshee_read_linear_w(uint32_t addr, void *p) } static uint32_t -banshee_read_linear_l(uint32_t addr, void *p) +banshee_read_linear_l(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 3) - return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr + 2, p) << 16); + return banshee_read_linear_w(addr, priv) | (banshee_read_linear_w(addr + 2, priv) << 16); cycles -= voodoo->read_time; @@ -1744,11 +1890,11 @@ banshee_read_linear_l(uint32_t addr, void *p) } static void -banshee_write_linear(uint32_t addr, uint8_t val, void *p) +banshee_write_linear(uint32_t addr, uint8_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; cycles -= voodoo->write_time; @@ -1779,15 +1925,15 @@ banshee_write_linear(uint32_t addr, uint8_t val, void *p) } static void -banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) +banshee_write_linear_w(uint32_t addr, uint16_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 1) { - banshee_write_linear(addr, val, p); - banshee_write_linear(addr + 1, val >> 8, p); + banshee_write_linear(addr, val, priv); + banshee_write_linear(addr + 1, val >> 8, priv); return; } @@ -1819,16 +1965,16 @@ banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) } static void -banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) +banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; int timing; if (addr & 3) { - banshee_write_linear_w(addr, val, p); - banshee_write_linear_w(addr + 2, val >> 16, p); + banshee_write_linear_w(addr, val, priv); + banshee_write_linear_w(addr + 2, val >> 16, priv); return; } @@ -1923,14 +2069,14 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) void banshee_hwcursor_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *) svga->p; - int x; - int x_off; - int xx; - uint32_t col0 = banshee->hwCurC0; - uint32_t col1 = banshee->hwCurC1; - uint8_t plane0[8]; - uint8_t plane1[8]; + const banshee_t *banshee = (banshee_t *) svga->priv; + int x; + int x_off; + int xx; + uint32_t col0 = banshee->hwCurC0; + uint32_t col1 = banshee->hwCurC1; + uint8_t plane0[8]; + uint8_t plane1[8]; for (uint8_t c = 0; c < 8; c++) plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; @@ -1946,7 +2092,7 @@ banshee_hwcursor_draw(svga_t *svga, int displine) if (x_off > -8) { for (xx = 0; xx < 8; xx++) { if (plane0[x >> 3] & (1 << 7)) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; @@ -1961,9 +2107,9 @@ banshee_hwcursor_draw(svga_t *svga, int displine) if (x_off > -8) { for (xx = 0; xx < 8; xx++) { if (!(plane0[x >> 3] & (1 << 7))) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; else if (plane1[x >> 3] & (1 << 7)) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; @@ -2128,8 +2274,6 @@ banshee_hwcursor_draw(svga_t *svga, int displine) void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) { - int g; - int h; float difference; float diffg; float thiscol; @@ -2143,10 +2287,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) fcg *= hack; /* box prefilter */ - for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into - { - for (h = 0; h < 256; h++) // pixel 2 - our main pixel - { + for (uint16_t g = 0; g < 256; g++) { // pixel 1 - our target pixel we want to bleed into + for (uint16_t h = 0; h < 256; h++) { // pixel 2 - our main pixel float avg; float avgdiff; @@ -2228,10 +2370,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) fcg *= 6; #endif - for (g = 0; g < 256; g++) // pixel 1 - { - for (h = 0; h < 256; h++) // pixel 2 - { + for (uint16_t g = 0; g < 256; g++) { // pixel 1 + for (uint16_t h = 0; h < 256; h++) { // pixel 2 difference = (float) (h - g); diffg = difference; @@ -2271,18 +2411,18 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) static void banshee_overlay_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *) svga->p; - voodoo_t *voodoo = banshee->voodoo; - uint32_t *p; - int x; - int y = voodoo->overlay.src_y >> 20; - uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); - uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch); - uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; - uint32_t src_x = 0; - unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; - int skip_filtering; - uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; + banshee_t *banshee = (banshee_t *) svga->priv; + voodoo_t *voodoo = banshee->voodoo; + uint32_t *p; + int x; + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); + uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch); + uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; + uint32_t src_x = 0; + unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; + int skip_filtering; + const uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && !svga->fullchange && ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { voodoo->overlay.src_y += (1 << 20); @@ -2296,7 +2436,7 @@ banshee_overlay_draw(svga_t *svga, int displine) if (src_addr >= 0x800000) fatal("overlay out of range!\n"); #endif - p = &((uint32_t *) svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add]; + p = &(svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add]; if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); @@ -2510,9 +2650,9 @@ banshee_overlay_draw(svga_t *svga, int displine) } void -banshee_set_overlay_addr(void *p, uint32_t addr) +banshee_set_overlay_addr(void *priv, UNUSED(uint32_t addr)) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_t *voodoo = banshee->voodoo; banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; @@ -2523,7 +2663,7 @@ banshee_set_overlay_addr(void *p, uint32_t addr) static void banshee_vsync_callback(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->p; + banshee_t *banshee = (banshee_t *) svga->priv; voodoo_t *voodoo = banshee->voodoo; voodoo->retrace_count++; @@ -2548,10 +2688,12 @@ banshee_vsync_callback(svga_t *svga) } static uint8_t -banshee_pci_read(int func, int addr, void *p) +banshee_pci_read(int func, int addr, void *priv) { - banshee_t *banshee = (banshee_t *) p; - // svga_t *svga = &banshee->svga; + const banshee_t *banshee = (banshee_t *) priv; +#if 0 + svga_t *svga = &banshee->svga; +#endif uint8_t ret = 0; if (func) @@ -2743,6 +2885,9 @@ banshee_pci_read(int func, int addr, void *p) case 0x67: ret = banshee->pci_regs[0x67]; break; + + default: + break; } #if 0 banshee_log("%02X\n", ret); @@ -2751,9 +2896,9 @@ banshee_pci_read(int func, int addr, void *p) } static void -banshee_pci_write(int func, int addr, uint8_t val, void *p) +banshee_pci_write(int func, int addr, uint8_t val, void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; #if 0 svga_t *svga = &banshee->svga; #endif @@ -2872,6 +3017,9 @@ banshee_pci_write(int func, int addr, uint8_t val, void *p) case 0x66: banshee->pci_regs[0x66] = val & 0xc0; return; + + default: + break; } } @@ -3086,10 +3234,13 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->dramInit1 = 1 << 30; /*SDRAM*/ banshee->svga.decode_mask = 0x1ffffff; - banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); + if (banshee->has_bios) + pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot); + else + pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot); banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); - banshee->voodoo->p = banshee; + banshee->voodoo->priv = banshee; banshee->voodoo->vram = banshee->svga.vram; banshee->voodoo->changedvram = banshee->svga.changedvram; banshee->voodoo->fb_mem = banshee->svga.vram; @@ -3108,6 +3259,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee"); banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc)); + banshee->svga.conv_16to32 = banshee_conv_16to32; + switch (type) { case TYPE_BANSHEE: if (has_sgram) { @@ -3178,6 +3331,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->pci_regs[0x2e] = 0x54; banshee->pci_regs[0x2f] = 0x00; break; + + default: + break; } video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); @@ -3357,9 +3513,9 @@ velocity_200_available(void) } static void -banshee_close(void *p) +banshee_close(void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; voodoo_card_close(banshee->voodoo); svga_close(&banshee->svga); @@ -3371,23 +3527,23 @@ banshee_close(void *p) } static void -banshee_speed_changed(void *p) +banshee_speed_changed(void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; svga_recalctimings(&banshee->svga); } static void -banshee_force_redraw(void *p) +banshee_force_redraw(void *priv) { - banshee_t *banshee = (banshee_t *) p; + banshee_t *banshee = (banshee_t *) priv; banshee->svga.fullchange = changeframecount; } const device_t voodoo_banshee_device = { - .name = "3dfx Voodoo Banshee", + .name = "3Dfx Voodoo Banshee", .internal_name = "voodoo_banshee_pci", .flags = DEVICE_PCI, .local = 0, diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 1752888561..33ee602b54 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -207,7 +207,7 @@ get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) } static void -PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) +PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, UNUSED(uint8_t rop), uint32_t src, int src_colorkey) { switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { case DST_FORMAT_COL_8_BPP: @@ -250,11 +250,14 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, voodoo->changedvram[addr >> 12] = changeframecount; break; } + + default: + break; } } static void -PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey) +PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, int src_colorkey) { switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { case DST_FORMAT_COL_8_BPP: @@ -293,6 +296,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src voodoo->changedvram[addr >> 12] = changeframecount; break; } + + default: + break; } } @@ -364,6 +370,9 @@ update_src_stride(voodoo_t *voodoo) bansheeblt_log("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); #endif break; + + default: + break; } } @@ -385,12 +394,12 @@ end_command(voodoo_t *voodoo) static void banshee_do_rectfill(voodoo_t *voodoo) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; #if 0 bansheeblt_log("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); @@ -519,13 +528,13 @@ DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src) static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int src_colorkey; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int src_colorkey; switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { case SRC_FORMAT_COL_8_BPP: @@ -601,6 +610,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } + + default: + break; } } if (use_x_dir) { @@ -619,7 +631,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr } else { /*Conversion required*/ if (dst_y >= clip->y_min && dst_y < clip->y_max) { - // int src_x = voodoo->banshee_blt.srcX; +#if 0 + int src_x = voodoo->banshee_blt.srcX; +#endif int dst_x = voodoo->banshee_blt.dstX; int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; uint8_t pattern_mask = pattern_mono[pat_y & 7]; @@ -777,7 +791,7 @@ banshee_do_screen_to_screen_blt(voodoo_t *voodoo) } static void -banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) +banshee_do_host_to_screen_blt(voodoo_t *voodoo, UNUSED(int count), uint32_t data) { #if 0 if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) @@ -849,15 +863,15 @@ banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) static void do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, int *src_y) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; #if 0 int src_y = voodoo->banshee_blt.srcY; #endif - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + const uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; #if 0 int error_y = voodoo->banshee_blt.dstSizeY / 2; @@ -891,7 +905,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); - // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); +#if 0 + bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); +#endif voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } @@ -937,6 +953,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } + + default: + break; } } @@ -984,7 +1003,7 @@ banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) } static void -banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) +banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, UNUSED(int count), uint32_t data) { #if 0 if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) @@ -1063,16 +1082,16 @@ step_line(voodoo_t *voodoo) static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t rop = voodoo->banshee_blt.command >> 24; - int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); - int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); - int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; - int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; - int x = voodoo->banshee_blt.srcX; - int y = voodoo->banshee_blt.srcY; - int error; - uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t rop = voodoo->banshee_blt.command >> 24; + int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); + int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); + int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; + int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; + int x = voodoo->banshee_blt.srcX; + int y = voodoo->banshee_blt.srcY; + int error; + uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; if (dx > dy) /*X major*/ { @@ -1143,12 +1162,12 @@ banshee_polyfill_start(voodoo_t *voodoo) static void banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); - int y_end; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); + int y_end; #if 0 bansheeblt_log("Polyfill : data %08x\n", data); diff --git a/src/video/vid_voodoo_blitter.c b/src/video/vid_voodoo_blitter.c index a1105795c5..6ea2edcc34 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -163,23 +163,23 @@ voodoo_v2_blit_start(voodoo_t *voodoo) int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x; - int y; - /* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", - voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ +#if 0 + voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", + voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg); +#endif voodoo_wait_for_render_thread_idle(voodoo); switch (voodoo->bltCommand & BLIT_COMMAND_MASK) { case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) { - uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride]; - uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - int src_x = voodoo->bltSrcX; - int dst_x = voodoo->bltDstX; + for (int y = 0; y <= size_y; y++) { + const uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride]; + uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; + int src_x = voodoo->bltSrcX; + int dst_x = voodoo->bltDstX; - for (x = 0; x <= size_x; x++) { + for (int x = 0; x <= size_x; x++) { uint16_t src_dat = src[src_x]; uint16_t dst_dat = dst[dst_x]; int rop = 0; @@ -231,7 +231,7 @@ voodoo_v2_blit_start(voodoo_t *voodoo) break; case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) { + for (int y = 0; y <= size_y; y++) { uint16_t *dst; int dst_x = voodoo->bltDstX; @@ -242,7 +242,7 @@ voodoo_v2_blit_start(voodoo_t *voodoo) } else dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - for (x = 0; x <= size_x; x++) { + for (int x = 0; x <= size_x; x++) { if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) goto skip_pixel_fill; @@ -265,7 +265,7 @@ voodoo_v2_blit_start(voodoo_t *voodoo) dat64 = voodoo->bltColorFg | ((uint64_t) voodoo->bltColorFg << 16) | ((uint64_t) voodoo->bltColorFg << 32) | ((uint64_t) voodoo->bltColorFg << 48); - for (y = 0; y <= size_y; y++) { + for (int y = 0; y <= size_y; y++) { uint64_t *dst; /*This may be wrong*/ @@ -282,7 +282,7 @@ voodoo_v2_blit_start(voodoo_t *voodoo) dst = (uint64_t *) &voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask]; - for (x = 0; x <= size_x; x++) + for (int x = 0; x <= size_x; x++) dst[x] = dat64; dst_y++; @@ -345,6 +345,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) case BLIT_SRC_RGB_BGRA: src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); break; + + default: + break; } data >>= 16; src_bits -= 16; @@ -373,6 +376,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) g = (data >> 16) & 0xff; b = (data >> 24) & 0xff; break; + + default: + break; } switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { case BLIT_SRC_24BPP: @@ -390,9 +396,15 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); break; + + default: + break; } src_bits = 0; break; + + default: + break; } if (SLI_ENABLED) { diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index 77d54398fa..e6cf136746 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -141,10 +141,11 @@ voodoo_calc_clutData(voodoo_t *voodoo) int r = (c >> 8) & 0xf8; int g = (c >> 3) & 0xfc; int b = (c << 3) & 0xf8; - // r |= (r >> 5); - // g |= (g >> 6); - // b |= (b >> 5); - +#if 0 + r |= (r >> 5); + g |= (g >> 6); + b |= (b >> 5); +#endif voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; } } @@ -442,7 +443,7 @@ voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, } static void -voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, UNUSED(int line)) { int x; @@ -506,10 +507,10 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, } void -voodoo_callback(void *p) +voodoo_callback(void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; - monitor_t *monitor = &monitors[voodoo->monitor_index]; + voodoo_t *voodoo = (voodoo_t *) priv; + const monitor_t *monitor = &monitors[voodoo->monitor_index]; if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { if (voodoo->line < voodoo->v_disp) { @@ -576,7 +577,9 @@ voodoo_callback(void *p) } skip_draw: if (voodoo->line == voodoo->v_disp) { - // voodoodisp_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); +#if 0 + voodoodisp_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); +#endif voodoo->retrace_count++; if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) { if (voodoo == voodoo->set->voodoos[0]) { diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 06941eb051..94394e1157 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -59,9 +59,9 @@ voodoo_fb_log(const char *fmt, ...) #endif uint16_t -voodoo_fb_readw(uint32_t addr, void *p) +voodoo_fb_readw(uint32_t addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; int x; int y; uint32_t read_addr; @@ -76,7 +76,7 @@ voodoo_fb_readw(uint32_t addr, void *p) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -100,9 +100,9 @@ voodoo_fb_readw(uint32_t addr, void *p) return temp; } uint32_t -voodoo_fb_readl(uint32_t addr, void *p) +voodoo_fb_readl(uint32_t addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; int x; int y; uint32_t read_addr; @@ -117,7 +117,7 @@ voodoo_fb_readl(uint32_t addr, void *p) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -168,28 +168,32 @@ do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) } void -voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) +voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; - voodoo_params_t *params = &voodoo->params; - int x; - int y; - uint32_t write_addr; - uint32_t write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; + voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_params_t *params = &voodoo->params; + int x; + int y; + uint32_t write_addr; + uint32_t write_addr_aux; + rgba8_t colour_data; + uint16_t depth_data; + uint8_t alpha_data; + int write_mask = 0; colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; depth_data = voodoo->params.zaColor & 0xffff; alpha_data = voodoo->params.zaColor >> 24; - // while (!RB_EMPTY) - // thread_reset_event(voodoo->not_full_event); +#if 0 + while (!RB_EMPTY) + thread_reset_event(voodoo->not_full_event); +#endif - // voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val); +#if 0 + voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val); +#endif switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -304,26 +308,30 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) } void -voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) +voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; - voodoo_params_t *params = &voodoo->params; - int x; - int y; - uint32_t write_addr; - uint32_t write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0; - int count = 1; + voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_params_t *params = &voodoo->params; + int x; + int y; + uint32_t write_addr; + uint32_t write_addr_aux; + rgba8_t colour_data[2]; + uint16_t depth_data[2]; + uint8_t alpha_data[2]; + int write_mask = 0; + int count = 1; depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; - // while (!RB_EMPTY) - // thread_reset_event(voodoo->not_full_event); +#if 0 + while (!RB_EMPTY) + thread_reset_event(voodoo->not_full_event); +#endif - // voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val); +#if 0 + voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val); +#endif switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -393,12 +401,12 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) else write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - // voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); +#if 0 + voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); +#endif if (voodoo->lfbMode & 0x100) { - int c; - - for (c = 0; c < count; c++) { + for (int c = 0; c < count; c++) { rgba8_t write_data = colour_data[c]; uint16_t new_depth = depth_data[c]; diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index ab82d104ef..f8495edec9 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -81,9 +81,9 @@ voodoo_wake_fifo_thread_now(voodoo_t *voodoo) } void -voodoo_wake_timer(void *p) +voodoo_wake_timer(void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -160,7 +160,7 @@ cmdfifo_get(voodoo_t *voodoo) uint32_t val; if (!voodoo->cmdfifo_in_sub) { - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) { + while (voodoo->fifo_thread_run && (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)) { thread_wait_event(voodoo->wake_fifo_thread, -1); thread_reset_event(voodoo->wake_fifo_thread); } @@ -295,21 +295,27 @@ voodoo_fifo_thread(void *param) int num_verticies; int v_num; - // voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); +#if 0 + voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); +#endif voodoo->cmd_status &= ~7; voodoo->cmd_status |= (header & 7); voodoo->cmd_status |= (1 << 11); switch (header & 7) { case 0: - // voodoo_fifo_log("CMDFIFO0\n"); +#if 0 + voodoo_fifo_log("CMDFIFO0\n"); +#endif voodoo->cmd_status = (voodoo->cmd_status & 0xffff8fff) | (((header >> 3) & 7) << 12); switch ((header >> 3) & 7) { case 0: /*NOP*/ break; case 1: /*JSR*/ - // voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc); +#if 0 + voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc); +#endif voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; voodoo->cmdfifo_in_sub = 1; @@ -322,7 +328,9 @@ voodoo_fifo_thread(void *param) case 3: /*JMP local frame buffer*/ voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; - // voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); +#if 0 + voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); +#endif break; default: @@ -334,13 +342,20 @@ voodoo_fifo_thread(void *param) case 1: num = header >> 16; addr = (header & 0x7ff8) >> 1; - // voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr); +#if 0 + voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr); +#endif while (num--) { uint32_t val = cmdfifo_get(voodoo); if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { - // if (voodoo->type != VOODOO_BANSHEE) - // fatal("CMDFIFO1: Not Banshee\n"); - // voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#if 0 + if (voodoo->type != VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); +#endif + +#if 0 + voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#endif voodoo_2d_reg_writel(voodoo, addr, val); } else { if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) @@ -382,8 +397,10 @@ voodoo_fifo_thread(void *param) v_num = 0; if (((header >> 3) & 7) == 2) v_num = 1; - // voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); - // voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); +#if 0 + voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); + voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); +#endif while (num_verticies--) { voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); @@ -435,7 +452,9 @@ voodoo_fifo_thread(void *param) num = (header >> 29) & 7; mask = (header >> 15) & 0x3fff; addr = (header & 0x7ff8) >> 1; - // voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr); +#if 0 + voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr); +#endif while (mask) { if (mask & 1) { uint32_t val = cmdfifo_get(voodoo); @@ -443,7 +462,10 @@ voodoo_fifo_thread(void *param) if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { if (voodoo->type < VOODOO_BANSHEE) fatal("CMDFIFO1: Not Banshee\n"); - // voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#if 0 + voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#endif + voodoo_2d_reg_writel(voodoo, addr, val); } else { if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) @@ -463,22 +485,30 @@ voodoo_fifo_thread(void *param) break; case 5: - // if (header & 0x3fc00000) - // fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); +#if 0 + if (header & 0x3fc00000) + fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); +#endif num = (header >> 3) & 0x7ffff; addr = cmdfifo_get(voodoo) & 0xffffff; if (!num) num = 1; - // voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); +#if 0 + voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); +#endif switch (header >> 30) { case 0: /*Linear framebuffer (Banshee)*/ case 1: /*Planar YUV*/ if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { - // voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#if 0 + voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); } if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { - // voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#if 0 + voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); } while (num--) { diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 51b9568b8f..ce3ee60641 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -70,9 +70,9 @@ voodoo_reg_log(const char *fmt, ...) #endif void -voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) +voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; void (*voodoo_recalc_tex)(voodoo_t * voodoo, int tmu) = NULL; union { uint32_t i; @@ -89,7 +89,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo_recalc_tex = voodoo_recalc_tex12; tempif.i = val; - // voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); +#if 0 + voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); +#endif addr &= 0x3fc; if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) @@ -97,11 +99,13 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) switch (addr) { case SST_swapbufferCMD: if (voodoo->type >= VOODOO_BANSHEE) { - // voodoo_reg_log("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); +#if 0 + voodoo_reg_log("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); +#endif voodoo_wait_for_render_thread_idle(voodoo); if (!(val & 1)) { - banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); + banshee_set_overlay_addr(voodoo->priv, voodoo->leftOverlayBuf); thread_wait_mutex(voodoo->swap_mutex); if (voodoo->swap_count > 0) voodoo->swap_count--; @@ -136,8 +140,10 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.swapbufferCMD = val; - // voodoo_reg_log("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); - // voodoo->front_offset = params->front_offset; +#if 0 + voodoo_reg_log("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); + voodoo->front_offset = params->front_offset; +#endif voodoo_wait_for_render_thread_idle(voodoo); if (!(val & 1)) { memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); @@ -670,7 +676,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.draw_offset = val & 0xfffff0; voodoo->fb_write_offset = voodoo->params.draw_offset; - // voodoo_reg_log("colorBufferAddr=%06x\n", voodoo->params.draw_offset); +#if 0 + voodoo_reg_log("colorBufferAddr=%06x\n", voodoo->params.draw_offset); +#endif } break; case SST_colBufferStride: @@ -679,10 +687,14 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.col_tiled = voodoo->col_tiled; if (voodoo->col_tiled) { voodoo->row_width = (val & 0x7f) * 128 * 32; - // voodoo_reg_log("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); +#if 0 + voodoo_reg_log("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); +#endif } else { voodoo->row_width = val & 0x3fff; - // voodoo_reg_log("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); +#if 0 + voodoo_reg_log("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); +#endif } voodoo->params.row_width = voodoo->row_width; } @@ -690,7 +702,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_auxBufferAddr: if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.aux_offset = val & 0xfffff0; - // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); +#if 0 + pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); +#endif } break; case SST_auxBufferStride: @@ -699,10 +713,14 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.aux_tiled = voodoo->aux_tiled; if (voodoo->aux_tiled) { voodoo->aux_row_width = (val & 0x7f) * 128 * 32; - // voodoo_reg_log("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); +#if 0 + voodoo_reg_log("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); +#endif } else { voodoo->aux_row_width = val & 0x3fff; - // voodoo_reg_log("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); +#if 0 + voodoo_reg_log("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); +#endif } voodoo->params.aux_row_width = voodoo->aux_row_width; } @@ -726,12 +744,16 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_sVx: tempif.i = val; voodoo->verts[3].sVx = tempif.f; - // voodoo_reg_log("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); +#if 0 + voodoo_reg_log("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); +#endif break; case SST_sVy: tempif.i = val; voodoo->verts[3].sVy = tempif.f; - // voodoo_reg_log("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); +#if 0 + voodoo_reg_log("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); +#endif break; case SST_sARGB: voodoo->verts[3].sBlue = (float) (val & 0xff); @@ -789,7 +811,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_sBeginTriCMD: - // voodoo_reg_log("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); +#if 0 + voodoo_reg_log("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); +#endif voodoo->verts[0] = voodoo->verts[3]; voodoo->verts[1] = voodoo->verts[3]; voodoo->verts[2] = voodoo->verts[3]; @@ -800,7 +824,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->cull_pingpong = 0; break; case SST_sDrawTriCMD: - // voodoo_reg_log("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); +#if 0 + voodoo_reg_log("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); +#endif /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx chips, but this works with a number of games that switch between strip and fan mode in the middle of a run (eg Black & White, Viper Racing)*/ @@ -840,7 +866,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->num_verticies++; if (voodoo->num_verticies == 3) { - // voodoo_reg_log("triangle_setup\n"); +#if 0 + voodoo_reg_log("triangle_setup\n"); +#endif voodoo_triangle_setup(voodoo); voodoo->cull_pingpong = !voodoo->cull_pingpong; @@ -852,7 +880,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltSrcBaseAddr = val & 0x3fffff; break; case SST_bltDstBaseAddr: - // voodoo_reg_log("Write bltDstBaseAddr %08x\n", val); +#if 0 + voodoo_reg_log("Write bltDstBaseAddr %08x\n", val); +#endif voodoo->bltDstBaseAddr = val & 0x3fffff; break; case SST_bltXYStrides: @@ -969,7 +999,9 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.texBaseAddr[0] = val & 0xfffff0; else voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; - // voodoo_reg_log("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); +#if 0 + voodoo_reg_log("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); +#endif voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { @@ -1089,6 +1121,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } break; } + fallthrough; case SST_nccTable0_I2: if (!(val & (1 << 31))) { if (chip & CHIP_TREX0) { @@ -1327,5 +1360,8 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_leftOverlayBuf: voodoo->leftOverlayBuf = val; break; + + default: + break; } } diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index c0e6e01966..42426744a5 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -178,7 +178,9 @@ voodoo_fls(uint16_t val) { int num = 0; - // voodoo_render_log("fls(%04x) = ", val); +#if 0 + voodoo_render_log("fls(%04x) = ", val); +#endif if (!(val & 0xff00)) { num += 8; val <<= 8; @@ -195,7 +197,9 @@ voodoo_fls(uint16_t val) num += 1; val <<= 1; } - // voodoo_render_log("%i %04x\n", num, val); +#if 0 + voodoo_render_log("%i %04x\n", num, val); +#endif return num; } @@ -241,7 +245,7 @@ tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) #define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) static inline void -tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) +tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, UNUSED(int x)) { rgba_u dat[4]; @@ -320,36 +324,44 @@ voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *st s >>= 4; t >>= 4; - // if (x == 80) - // if (voodoo_output) - // voodoo_render_log("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); +#if 0 + if (x == 80) + if (voodoo_output) + voodoo_render_log("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); +#endif d[0] = (16 - _ds) * (16 - dt); d[1] = _ds * (16 - dt); d[2] = (16 - _ds) * dt; d[3] = _ds * dt; - // texture_state.s = s; - // texture_state.t = t; +#if 0 + texture_state.s = s; + texture_state.t = t; +#endif tex_read_4(state, &texture_state, s, t, d, tmu, x); - /* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; - state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; - state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; - state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ - /* state->tex_r = tex_samples[0].r; - state->tex_g = tex_samples[0].g; - state->tex_b = tex_samples[0].b; - state->tex_a = tex_samples[0].a;*/ +#if 0 + state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; + state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; + state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; + state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ +#endif +#if 0 + state->tex_r = tex_samples[0].r; + state->tex_g = tex_samples[0].g; + state->tex_b = tex_samples[0].b; + state->tex_a = tex_samples[0].a; +#endif } else { - // rgba_t tex_samples; - // voodoo_texture_state_t texture_state; - // int s = state->tex_s >> (18+state->lod); - // int t = state->tex_t >> (18+state->lod); - // int s, t; - - // state->tex_s -= 1 << (17+state->lod); - // state->tex_t -= 1 << (17+state->lod); +#if 0 + rgba_t tex_samples; + voodoo_texture_state_t texture_state; + int s = state->tex_s >> (18+state->lod); + int t = state->tex_t >> (18+state->lod); + state->tex_s -= 1 << (17+state->lod); + state->tex_t -= 1 << (17+state->lod); +#endif s = state->tex_s >> (4 + tex_lod); t = state->tex_t >> (4 + tex_lod); @@ -357,10 +369,12 @@ voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *st texture_state.t = t; tex_read(state, &texture_state, tmu); - /* state->tex_r = tex_samples[0].rgba.r; - state->tex_g = tex_samples[0].rgba.g; - state->tex_b = tex_samples[0].rgba.b; - state->tex_a = tex_samples[0].rgba.a;*/ +#if 0 + state->tex_r = tex_samples[0].rgba.r; + state->tex_g = tex_samples[0].rgba.g; + state->tex_b = tex_samples[0].rgba.b; + state->tex_a = tex_samples[0].rgba.a; +#endif } } @@ -432,8 +446,10 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta c_reverse = !tc_reverse_blend; a_reverse = !tca_reverse_blend; } - /* c_reverse1 = c_reverse; - a_reverse1 = a_reverse;*/ +#if 0 + c_reverse1 = c_reverse; + a_reverse1 = a_reverse; +#endif if (tc_sub_clocal_1) { switch (tc_mselect_1) { case TC_MSELECT_ZERO: @@ -459,6 +475,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TC_MSELECT_LOD_FRAC: factor_r = factor_g = factor_b = state->lod_frac[1]; break; + + default: + break; } if (!c_reverse) { r = (-state->tex_r[1] * (factor_r + 1)) >> 8; @@ -504,6 +523,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TCA_MSELECT_LOD_FRAC: factor_a = state->lod_frac[1]; break; + + default: + break; } if (!a_reverse) a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; @@ -559,6 +581,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TC_MSELECT_LOD_FRAC: factor_r = factor_g = factor_b = state->lod_frac[0]; break; + + default: + break; } if (!c_reverse) { r = (r * (factor_r + 1)) >> 8; @@ -606,6 +631,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TCA_MSELECT_LOD_FRAC: factor_a = state->lod_frac[0]; break; + + default: + break; } if (a_reverse) a = (a * ((factor_a ^ 0xff) + 1)) >> 8; @@ -639,30 +667,32 @@ int voodoo_recomp = 0; static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) { - /* int rgb_sel = params->fbzColorPath & 3; - int a_sel = (params->fbzColorPath >> 2) & 3; - int cc_localselect = params->fbzColorPath & (1 << 4); - int cca_localselect = (params->fbzColorPath >> 5) & 3; - int cc_localselect_override = params->fbzColorPath & (1 << 7); - int cc_zero_other = params->fbzColorPath & (1 << 8); - int cc_sub_clocal = params->fbzColorPath & (1 << 9); - int cc_mselect = (params->fbzColorPath >> 10) & 7; - int cc_reverse_blend = params->fbzColorPath & (1 << 13); - int cc_add = (params->fbzColorPath >> 14) & 3; - int cc_add_alocal = params->fbzColorPath & (1 << 15); - int cc_invert_output = params->fbzColorPath & (1 << 16); - int cca_zero_other = params->fbzColorPath & (1 << 17); - int cca_sub_clocal = params->fbzColorPath & (1 << 18); - int cca_mselect = (params->fbzColorPath >> 19) & 7; - int cca_reverse_blend = params->fbzColorPath & (1 << 22); - int cca_add = (params->fbzColorPath >> 23) & 3; - int cca_invert_output = params->fbzColorPath & (1 << 25); - int src_afunc = (params->alphaMode >> 8) & 0xf; - int dest_afunc = (params->alphaMode >> 12) & 0xf; - int alpha_func = (params->alphaMode >> 1) & 7; - int a_ref = params->alphaMode >> 24; - int depth_op = (params->fbzMode >> 5) & 7; - int dither = params->fbzMode & FBZ_DITHER;*/ +#if 0 + int rgb_sel = params->fbzColorPath & 3; + int a_sel = (params->fbzColorPath >> 2) & 3; + int cc_localselect = params->fbzColorPath & (1 << 4); + int cca_localselect = (params->fbzColorPath >> 5) & 3; + int cc_localselect_override = params->fbzColorPath & (1 << 7); + int cc_zero_other = params->fbzColorPath & (1 << 8); + int cc_sub_clocal = params->fbzColorPath & (1 << 9); + int cc_mselect = (params->fbzColorPath >> 10) & 7; + int cc_reverse_blend = params->fbzColorPath & (1 << 13); + int cc_add = (params->fbzColorPath >> 14) & 3; + int cc_add_alocal = params->fbzColorPath & (1 << 15); + int cc_invert_output = params->fbzColorPath & (1 << 16); + int cca_zero_other = params->fbzColorPath & (1 << 17); + int cca_sub_clocal = params->fbzColorPath & (1 << 18); + int cca_mselect = (params->fbzColorPath >> 19) & 7; + int cca_reverse_blend = params->fbzColorPath & (1 << 22); + int cca_add = (params->fbzColorPath >> 23) & 3; + int cca_invert_output = params->fbzColorPath & (1 << 25); + int src_afunc = (params->alphaMode >> 8) & 0xf; + int dest_afunc = (params->alphaMode >> 12) & 0xf; + int alpha_func = (params->alphaMode >> 1) & 7; + int a_ref = params->alphaMode >> 24; + int depth_op = (params->fbzMode >> 5) & 7; + int dither = params->fbzMode & FBZ_DITHER;*/ +#endif int texels; #ifndef NO_CODEGEN uint8_t (*voodoo_draw)(voodoo_state_t * state, voodoo_params_t * params, int x, int real_y); @@ -723,7 +753,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * yend = params->clipHighY; state->y = ystart; - // yend--; +#if 0 + yend--; +#endif if (SLI_ENABLED) { int test_y; @@ -760,7 +792,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * #endif voodoo_render_log("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); - // voodoo_render_log("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); +#if 0 + voodoo_render_log("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); +#endif for (; state->y < yend; state->y += y_diff) { int x; @@ -916,7 +950,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * voodoo->fbiPixelsIn++; voodoo_render_log(" X=%03i T=%08x\n", x, state->tmu0_t); - // if (voodoo->fbzMode & FBZ_RGB_WMASK) +#if 0 + if (voodoo->fbzMode & FBZ_RGB_WMASK) +#endif { int update = 1; uint8_t cother_r = 0; @@ -956,7 +992,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * w_depth = 0xffff; } - // w_depth = CLAMP16(w_depth); +#if 0 + w_depth = CLAMP16(w_depth); +#endif if (params->fbzMode & FBZ_W_BUFFER) new_depth = w_depth; @@ -1047,6 +1085,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * cother_g = src_g; cother_b = src_b; break; + + default: + break; } switch (cca_localselect) { @@ -1434,15 +1475,15 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) vertexCy_adjusted = (state.vertexCy + 7) >> 4; if (state.vertexBy - state.vertexAy) - state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexBy - state.vertexAy); + state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexBy - state.vertexAy); else state.dxAB = 0; if (state.vertexCy - state.vertexAy) - state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexCy - state.vertexAy); + state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexCy - state.vertexAy); else state.dxAC = 0; if (state.vertexCy - state.vertexBy) - state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (int) (state.vertexCy - state.vertexBy); + state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (state.vertexCy - state.vertexBy); else state.dxBC = 0; diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 1e94134600..3939db3cdf 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -192,7 +192,9 @@ voodoo_recalc_tex3(voodoo_t *voodoo, int tmu) if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) tex_lod++; /*Skip LOD 0*/ - // voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); +#if 0 + voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); +#endif for (lod = 0; lod <= LOD_MAX + 1; lod++) { if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { switch (tex_lod) { @@ -302,18 +304,22 @@ voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) lod_min = (params->tLOD[tmu] >> 2) & 15; lod_max = (params->tLOD[tmu] >> 8) & 15; - // voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); +#if 0 + voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); +#endif lod_min = MIN(lod_min, 8); lod_max = MIN(lod_max, 8); for (int lod = lod_min; lod <= lod_max; lod++) { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x; - int y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; - - // voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); + uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; + uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; + int x; + int y; + int shift = 8 - params->tex_lod[tmu][lod]; + const rgba_u *pal; + +#if 0 + voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); +#endif switch (params->tformat[tmu]) { case TEX_RGB332: @@ -550,7 +556,9 @@ flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) int wait_for_idle = 0; memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); - // voodoo_texture_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); +#if 0 + voodoo_texture_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); +#endif for (uint8_t c = 0; c < TEX_CACHE_MAX; c++) { if (voodoo->texture_cache[tmu][c].base != -1) { for (uint8_t d = 0; d < 4; d++) { @@ -564,7 +572,9 @@ flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) if (addr_end_masked < addr_start_masked) addr_end_masked = voodoo->texture_mask + 1; if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { - // voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); +#if 0 + voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); +#endif if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) wait_for_idle = 1; @@ -583,12 +593,12 @@ flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) } void -voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) +voodoo_tex_writel(uint32_t addr, uint32_t val, void *priv) { int lod; int s; int t; - voodoo_t *voodoo = (voodoo_t *) p; + voodoo_t *voodoo = (voodoo_t *) priv; int tmu; if (addr & 0x400000) @@ -618,8 +628,10 @@ voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (lod > LOD_MAX) return; - // if (addr >= 0x200000) - // return; +#if 0 + if (addr >= 0x200000) + return; +#endif if (voodoo->params.tformat[tmu] & 8) addr = voodoo->params.tex_base[tmu][lod] + s * 2 + (t << voodoo->params.tex_shift[tmu][lod]) * 2; @@ -629,11 +641,15 @@ voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { - // voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#if 0 + voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); } if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu ^ 1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { - // voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#if 0 + voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu ^ 1); } *(uint32_t *) (&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index c81a41de8b..600fa21a81 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -28,6 +28,7 @@ #include <86box/mem.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/plat_unused.h> #define WY700_XSIZE 1280 #define WY700_YSIZE 800 @@ -216,16 +217,16 @@ static int cgacols[256][2][2]; static int mdacols[256][2][2]; void wy700_recalctimings(wy700_t *wy700); -void wy700_write(uint32_t addr, uint8_t val, void *p); -uint8_t wy700_read(uint32_t addr, void *p); +void wy700_write(uint32_t addr, uint8_t val, void *priv); +uint8_t wy700_read(uint32_t addr, void *priv); void wy700_checkchanges(wy700_t *wy700); static video_timings_t timing_wy700 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void -wy700_out(uint16_t addr, uint8_t val, void *p) +wy700_out(uint16_t addr, uint8_t val, void *priv) { - wy700_t *wy700 = (wy700_t *) p; + wy700_t *wy700 = (wy700_t *) priv; switch (addr) { /* These three registers are only mapped in the 3Dx range, * not the 3Bx range. */ @@ -283,13 +284,17 @@ wy700_out(uint16_t addr, uint8_t val, void *p) case 0x3D9: wy700->cga_colour = val; return; + + default: + break; } } uint8_t -wy700_in(uint16_t addr, void *p) +wy700_in(uint16_t addr, void *priv) { - wy700_t *wy700 = (wy700_t *) p; + const wy700_t *wy700 = (wy700_t *) priv; + switch (addr) { case 0x3b0: case 0x3b2: @@ -318,6 +323,9 @@ wy700_in(uint16_t addr, void *p) return wy700->mda_stat; case 0x3da: return wy700->cga_stat; + + default: + break; } return 0xff; } @@ -378,6 +386,9 @@ wy700_checkchanges(wy700_t *wy700) case 7: /* Enable display */ wy700->enabled = 1; break; + + default: + break; } /* A control write with the top bit set selects graphics mode */ if (wy700->wy700_control & 0x80) { @@ -456,9 +467,9 @@ wy700_checkchanges(wy700_t *wy700) } void -wy700_write(uint32_t addr, uint8_t val, void *p) +wy700_write(uint32_t addr, uint8_t val, void *priv) { - wy700_t *wy700 = (wy700_t *) p; + wy700_t *wy700 = (wy700_t *) priv; if (wy700->wy700_mode & 0x80) /* High-res mode. */ { @@ -475,11 +486,11 @@ wy700_write(uint32_t addr, uint8_t val, void *p) } uint8_t -wy700_read(uint32_t addr, void *p) +wy700_read(uint32_t addr, void *priv) { - wy700_t *wy700 = (wy700_t *) p; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { + const wy700_t *wy700 = (wy700_t *) priv; + + if (wy700->wy700_mode & 0x80) { /* High-res mode. */ addr &= 0xFFFF; /* In 800-line modes, bit 0 of the control register sets the high bit of the * read address. */ @@ -512,21 +523,21 @@ wy700_recalctimings(wy700_t *wy700) void wy700_textline(wy700_t *wy700) { - int w = (wy700->wy700_mode == 0) ? 40 : 80; - int cw = (wy700->wy700_mode == 0) ? 32 : 16; - uint8_t chr; - uint8_t attr; - uint8_t bitmap[2]; - uint8_t *fontbase = &fontdatw[0][0]; - int blink; - int c; - int drawcursor; - int cursorline; - int mda = 0; - uint16_t addr; - uint8_t sc; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; + int w = (wy700->wy700_mode == 0) ? 40 : 80; + int cw = (wy700->wy700_mode == 0) ? 32 : 16; + uint8_t chr; + uint8_t attr; + uint8_t bitmap[2]; + const uint8_t *fontbase = &fontdatw[0][0]; + int blink; + int c; + int drawcursor; + int cursorline; + int mda = 0; + uint16_t addr; + uint8_t sc; + uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; /* The fake CRTC character height register selects whether MDA or CGA * attributes are used */ @@ -629,6 +640,9 @@ wy700_cgaline(wy700_t *wy700) case 3: ink = 16 + 15; break; + + default: + break; } if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) ink = 16; @@ -669,6 +683,9 @@ wy700_medresline(wy700_t *wy700) case 3: ink = 16 + 15; break; + + default: + break; } /* Display disabled? */ if (!(wy700->wy700_mode & 8)) @@ -724,6 +741,9 @@ wy700_hiresline(wy700_t *wy700) case 3: ink = 16 + 15; break; + + default: + break; } /* Display disabled? */ if (!(wy700->wy700_mode & 8)) @@ -745,9 +765,9 @@ wy700_hiresline(wy700_t *wy700) } void -wy700_poll(void *p) +wy700_poll(void *priv) { - wy700_t *wy700 = (wy700_t *) p; + wy700_t *wy700 = (wy700_t *) priv; int mode; if (!wy700->linepos) { @@ -857,10 +877,11 @@ wy700_poll(void *p) } void * -wy700_init(const device_t *info) +wy700_init(UNUSED(const device_t *info)) { int c; wy700_t *wy700 = malloc(sizeof(wy700_t)); + memset(wy700, 0, sizeof(wy700_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_wy700); @@ -959,18 +980,18 @@ wy700_init(const device_t *info) } void -wy700_close(void *p) +wy700_close(void *priv) { - wy700_t *wy700 = (wy700_t *) p; + wy700_t *wy700 = (wy700_t *) priv; free(wy700->vram); free(wy700); } void -wy700_speed_changed(void *p) +wy700_speed_changed(void *priv) { - wy700_t *wy700 = (wy700_t *) p; + wy700_t *wy700 = (wy700_t *) priv; wy700_recalctimings(wy700); } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 0c795d1324..fad5e4124d 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1,18 +1,18 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * IBM XGA emulation. + * IBM XGA emulation. * * * - * Authors: TheCollector1995. + * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #include #include @@ -30,77 +30,164 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/video.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_xga_device.h> #include "cpu.h" +#include <86box/plat_unused.h> -#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" -#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" +#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" +#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" +#define INMOS_XGA_BIOS_PATH "roms/video/xga/InMOS XGA - Fairchild NM27C256Q-150.BIN" static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; -static void xga_ext_outb(uint16_t addr, uint8_t val, void *p); -static uint8_t xga_ext_inb(uint16_t addr, void *p); +static void xga_ext_outb(uint16_t addr, uint8_t val, void *priv); +static uint8_t xga_ext_inb(uint16_t addr, void *priv); + +static void xga_writew(uint32_t addr, uint16_t val, void *priv); +static uint16_t xga_readw(uint32_t addr, void *priv); + +static void xga_render_4bpp(svga_t *svga); +static void xga_render_8bpp(svga_t *svga); +static void xga_render_16bpp(svga_t *svga); + +int xga_active = 0; + +#ifdef ENABLE_XGA_LOG +int xga_do_log = ENABLE_XGA_LOG; + +static void +xga_log(const char *fmt, ...) +{ + va_list ap; + + if (xga_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define xga_log(fmt, ...) +#endif + +void +svga_xga_out(uint16_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + + default: + break; + } + svga_out(addr, val, svga); +} + +uint8_t +svga_xga_in(uint16_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + uint8_t temp; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} void xga_updatemapping(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; + + xga_log("OpMode = %x, linear base = %08x, aperture cntl = %d, access mode = %x, map = %x, " + "endian reverse = %d, a5test = %d, XGA on = %d.\n", xga->op_mode, xga->linear_base, + xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, + xga->linear_endian_reverse, xga->a5_test, xga->on); - //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c); if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { - if (xga->aperture_cntl == 1) { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { + if (xga->aperture_cntl == 1) + mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + else + mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff; if (!xga->linear_endian_reverse) mem_mapping_disable(&xga->linear_mapping); } else if (xga->aperture_cntl == 0) { - mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff; - if (xga->pos_regs[4] & 1) - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - else if (xga->base_addr_1mb) + if (xga->base_addr_1mb) mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); else mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on) - xga->linear_endian_reverse = 1; - else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) - xga->linear_endian_reverse = 1; - xga->on = 0; - vga_on = !xga->on; - } else { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - mem_mapping_disable(&xga->linear_mapping); + + if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { + xga->on = 0; + vga_on = 1; + xga_log("A5 test valid.\n"); + } } - } else { - xga->on = 0; - vga_on = !xga->on; - mem_mapping_disable(&svga->mapping); - if (xga->aperture_cntl == 2) - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - mem_mapping_disable(&xga->linear_mapping); - //pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl); + + xga_log("XGA opmode (extended) = %d, disp mode = %d, aperture = %d, on = %d, linear endian reverse = %d.\n", xga->op_mode & 7, + xga->disp_cntl_2 & 7, xga->aperture_cntl, xga->on, xga->linear_endian_reverse); } + xga_log("VGA on = %d, map = %02x.\n", vga_on, svga->gdcreg[6] & 0x0c); } void xga_recalctimings(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; if (xga->on) { xga->v_total = xga->vtotal + 1; @@ -111,7 +198,7 @@ xga_recalctimings(svga_t *svga) xga->h_disp = (xga->hdisp + 1) << 3; - xga->rowoffset = (xga->hdisp + 1); + xga->rowoffset = xga->hdisp + 1; xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -126,20 +213,30 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; - switch (xga->clk_sel_1 & 0x0c) { + if ((xga->disp_cntl_2 & 7) == 2) + xga->rowoffset >>= 1; + else if ((xga->disp_cntl_2 & 7) == 4) + xga->rowoffset <<= 1; + + xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80); + switch ((xga->clk_sel_1 >> 2) & 3) { case 0: - if (xga->clk_sel_2 & 0x80) { + xga_log("HDISP VGA0 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp); + if (xga->clk_sel_2 & 0x80) svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0; - } else { + else svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } break; - case 4: + case 1: + xga_log("HDISP VGA1 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp); svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0; break; - case 0x0c: + case 3: svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; break; + + default: + break; } } } @@ -278,22 +375,29 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x50: + xga_log("Reg50 write = %02x.\n", val); xga->disp_cntl_1 = val; svga_recalctimings(svga); break; case 0x51: + xga_log("Reg51 write = %02x.\n", val); xga->disp_cntl_2 = val; - xga->on = ((val & 7) >= 3); - vga_on = !xga->on; + xga->on = ((val & 7) >= 2); + vga_on = !xga->on; svga_recalctimings(svga); break; case 0x54: + xga_log("Reg54 write = %02x.\n", val); xga->clk_sel_1 = val; svga_recalctimings(svga); break; + case 0x55: + xga->border_color = val; + break; + case 0x59: xga->direct_color = val; break; @@ -309,9 +413,9 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { if ((xga->op_mode & 7) >= 5) xga->cursor_data_on = 1; - else if (xga->sprite_pos >= 1) + else if ((xga->sprite_pos >= 1) || (((xga->disp_cntl_2 & 7) == 2) || (xga->disp_cntl_2 & 7) == 4)) xga->cursor_data_on = 1; - else if (xga->aperture_cntl == 0) { + else if (!xga->aperture_cntl) { if (xga->linear_endian_reverse && !(xga->access_mode & 8)) xga->cursor_data_on = 0; } @@ -323,11 +427,14 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 1; else xga->cursor_data_on = 0; - } else { + } else xga->cursor_data_on = 0; - } - } - // pclog("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); + } else if (!xga->sprite_pos && xga->cursor_data_on && !xga->aperture_cntl && xga->linear_endian_reverse) + xga->cursor_data_on = 0; + + + xga_log("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, + xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); break; case 0x62: @@ -361,10 +468,13 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; svga->vgapal[index].b = xga->pal_b; - svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + xga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); svga->dac_pos = 0; svga->dac_addr = (svga->dac_addr + 1) & 0xff; break; + + default: + break; } break; @@ -388,19 +498,24 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x70: + xga_log("Reg70 write = %02x.\n", val); xga->clk_sel_2 = val; svga_recalctimings(svga); break; + + default: + break; } } static void -xga_ext_outb(uint16_t addr, uint8_t val, void *p) +xga_ext_outb(uint16_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); - //pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); switch (addr & 0x0f) { case 0: xga->op_mode = val; @@ -410,20 +525,28 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) xga_updatemapping(svga); break; case 4: - xga->access_mode &= ~8; if ((xga->disp_cntl_2 & 7) == 4) xga->aperture_cntl = 0; break; - case 6: - break; case 8: xga->ap_idx = val; - //pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); + xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, + val, val & 0x3f); if ((xga->op_mode & 7) < 4) { xga->write_bank = xga->read_bank = 0; } else { - xga->write_bank = (xga->ap_idx & 0x3f) << 16; - xga->read_bank = xga->write_bank; + if (xga->base_addr_1mb) { + if (xga->aperture_cntl) { + xga->write_bank = (xga->ap_idx & 0x3f) << 16; + xga->read_bank = xga->write_bank; + } else { + xga->write_bank = (xga->ap_idx & 0x30) << 16; + xga->read_bank = xga->write_bank; + } + } else { + xga->write_bank = (xga->ap_idx & 0x3f) << 16; + xga->read_bank = xga->write_bank; + } } break; case 9: @@ -440,15 +563,18 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) xga->regs[xga->regs_idx] = val; xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]); break; + + default: + break; } } static uint8_t -xga_ext_inb(uint16_t addr, void *p) +xga_ext_inb(uint16_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; - uint8_t ret; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0; uint8_t index; switch (addr & 0x0f) { @@ -474,7 +600,10 @@ xga_ext_inb(uint16_t addr, void *p) case 0x0f: switch (xga->regs_idx) { case 4: - ret = (xga->bus & DEVICE_MCA) ? 1 : 0; + if (xga->bus & DEVICE_MCA) + ret = 0x01; /*32-bit MCA*/ + else + ret = 0x10; /*16-bit ISA*/ break; case 0x10: ret = xga->htotal & 0xff; @@ -587,6 +716,9 @@ xga_ext_inb(uint16_t addr, void *p) case 0x54: ret = xga->clk_sel_1; break; + case 0x55: + ret = xga->border_color; + break; case 0x59: ret = xga->direct_color; @@ -626,6 +758,9 @@ xga_ext_inb(uint16_t addr, void *p) svga->dac_addr = (svga->dac_addr + 1) & 0xff; ret = svga->vgapal[index].b; break; + + default: + break; } break; @@ -644,7 +779,8 @@ xga_ext_inb(uint16_t addr, void *p) break; case 0x6a: - // pclog("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, xga->sprite_pal_addr_idx_prefetch); + xga_log("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, + xga->sprite_pal_addr_idx_prefetch); ret = xga->sprite_data[xga->sprite_pos_prefetch]; xga->sprite_pos_prefetch = (xga->sprite_pos_prefetch + 1) & 0x3ff; break; @@ -653,14 +789,28 @@ xga_ext_inb(uint16_t addr, void *p) ret = xga->clk_sel_2; break; + case 0x74: + if (xga->bus & DEVICE_MCA) + ret = xga->regs[xga->regs_idx]; + else { + ret = (xga->dma_channel << 1); + if (xga->dma_channel) + ret |= 1; + } + break; + default: ret = xga->regs[xga->regs_idx]; break; } break; + + default: + break; } - //pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret); + xga_log("[%04X:%08X]: EXT INB = %02x, ret = %02x.\n\n", CS, cpu_state.pc, addr, ret); + return ret; } @@ -674,17 +824,17 @@ xga_ext_inb(uint16_t addr, void *p) #define READW(addr, dat) \ dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)]; -#define READW_REVERSE(addr, dat) \ - dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \ - dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8); +#define READW_INV(addr, dat) \ + dat = xga->vram[(addr + 1) & (xga->vram_mask)]; \ + dat |= (xga->vram[(addr) & (xga->vram_mask)] << 8); #define WRITEW(addr, dat) \ *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; -#define WRITEW_REVERSE(addr, dat) \ - xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \ - xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \ +#define WRITEW_INV(addr, dat) \ + xga->vram[((addr + 1)) & (xga->vram_mask)] = dat & 0xff; \ + xga->vram[((addr)) & (xga->vram_mask)] = dat >> 8; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; #define ROP(mix, d, s) \ @@ -745,7 +895,7 @@ xga_ext_inb(uint16_t addr, void *p) d = MIN(s, d); \ break; \ case 0x12: \ - d = MIN(0xff, s + d); \ + d = MIN(~0, s + d); \ break; \ case 0x13: \ d = MAX(0, d - s); \ @@ -762,12 +912,12 @@ xga_ext_inb(uint16_t addr, void *p) static uint32_t xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { - xga_t *xga = &svga->xga; - uint32_t addr = base; - int bits; - uint32_t byte; - uint8_t px; - int skip = 0; + const xga_t *xga = (xga_t *) svga->xga; + uint32_t addr = base; + int bits; + uint8_t byte; + uint8_t px; + int skip = 0; if (xga->base_addr_1mb) { if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) @@ -781,25 +931,32 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b addr += (x >> 3); if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - if (xga->linear_endian_reverse) - bits = 7 - (x & 7); - else - bits = (x & 7); - else { + + if (xga->linear_endian_reverse) bits = 7 - (x & 7); + else { + if (xga->accel.px_map_format[xga->accel.dst_map] & 8) { + if ((xga->accel.px_map_format[xga->accel.src_map] & 8) && (xga->accel.px_map_format[map] & 8)) + bits = (x & 7); + else + bits = 7 - (x & 7); + } else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + bits = (x & 7); + else + bits = 7 - (x & 7); + } } px = (byte >> bits) & 1; return px; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, UNUSED(int usesrc)) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; int bits; uint32_t byte; @@ -820,54 +977,64 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int addr += (x >> 3); if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - if (xga->linear_endian_reverse) - bits = 7 - (x & 7); - else - bits = (x & 7); - else { + + if (xga->linear_endian_reverse) bits = 7 - (x & 7); + else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + bits = (x & 7); + else + bits = 7 - (x & 7); } px = (byte >> bits) & 1; return px; + case 2: /*4-bit*/ + addr += (y * (width >> 1)); + addr += (x >> 1); + if (!skip) { + READ(addr, byte); + } else + byte = mem_readb_phys(addr); + + return byte; case 3: /*8-bit*/ addr += (y * width); addr += x; if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } + return byte; case 4: /*16-bit*/ addr += (y * (width << 1)); addr += (x << 1); - if (!skip) { - if (xga->accel.px_map_format[map] & 8) { - if (xga->linear_endian_reverse) { - READW(addr, byte); - } else { - READW_REVERSE(addr, byte); - } - } else { - READW(addr, byte); - } - } else { + if (xga->linear_endian_reverse) { byte = mem_readw_phys(addr); + if ((xga->access_mode & 7) == 4) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); + else if (xga->access_mode & 8) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); + } else { + if (!skip) { + READW(addr, byte); + } else + byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); } return byte; - } + default: + break; + } return 0; } static void xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; uint8_t byte; uint8_t mask; @@ -883,20 +1050,21 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui switch (xga->accel.px_map_format[map] & 7) { case 0: /*1-bit*/ - addr += (y * width >> 3); + addr += (y * (width >> 3)); addr += (x >> 3); if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { - if (xga->linear_endian_reverse) - mask = 1 << (7 - (x & 7)); - else - mask = 1 << (x & 7); - } else { + + if (xga->linear_endian_reverse) { mask = 1 << (7 - (x & 7)); + } else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { + mask = 1 << (x & 7); + } else { + mask = 1 << (7 - (x & 7)); + } } byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); if (pixel & 1) { @@ -912,6 +1080,29 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } mem_writeb_phys(addr, byte); break; + case 2: /*4-bit*/ + addr += (y * (width >> 1)); + addr += (x >> 1); + if (!skip) { + READ(addr, byte); + } else { + byte = mem_readb_phys(addr); + } + + if (xga->linear_endian_reverse) + mask = 0x0f << ((1 - (x & 1)) << 2); + else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + mask = 0x0f << ((x & 1) << 2); + else + mask = 0x0f << ((1 - (x & 1)) << 2); + } + byte = (byte & ~mask) | (pixel & mask); + if (!skip) { + WRITE(addr, byte); + } + mem_writeb_phys(addr, byte); + break; case 3: /*8-bit*/ addr += (y * width); addr += x; @@ -923,26 +1114,28 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui case 4: /*16-bit*/ addr += (y * width << 1); addr += (x << 1); - if (!skip) { - if (xga->accel.px_map_format[map] & 8) { - if (xga->linear_endian_reverse) { - WRITEW(addr, pixel); - } else { - WRITEW_REVERSE(addr, pixel); - } - } else { + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) + pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); + else if (xga->access_mode & 8) + pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); + } else { + if (!skip) { WRITEW(addr, pixel); } } mem_writew_phys(addr, pixel); break; + + default: + break; } } static void xga_short_stroke(svga_t *svga, uint8_t ssv) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t src_dat; uint32_t dest_dat; uint32_t old_dest_dat; @@ -952,17 +1145,17 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; int y = ssv & 0x0f; int x = 0; - int dx; - int dy; + int16_t dx; + int16_t dy; int dirx = 0; int diry = 0; dx = xga->accel.dst_map_x & 0x1fff; - if (xga->accel.dst_map_x & 0x1800) + if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; dy = xga->accel.dst_map_y & 0x1fff; - if (xga->accel.dst_map_y & 0x1800) + if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; switch ((ssv >> 5) & 7) { @@ -998,14 +1191,17 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dirx = 1; diry = 1; break; + + default: + break; } if (xga->accel.pat_src == 8) { while (y >= 0) { if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1024,8 +1220,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1044,9 +1240,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) } } - if (!y) { + if (!y) break; - } dx += dirx; dy += diry; @@ -1060,118 +1255,140 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) xga->accel.dst_map_y = dy; } -#define SWAP(a, b) \ - tmpswap = a; \ - a = b; \ - b = tmpswap; - static void xga_line_draw_write(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t src_dat; uint32_t dest_dat; - uint32_t old_dest_dat; + uint32_t old_dest_dat = 0x00000000; uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - int dminor; - int destxtmp; - int dmajor; - int err; - int tmpswap; - int steep = 1; - int xdir; - int ydir; int y = xga->accel.blt_width; int x = 0; - int dx; - int dy; - - dminor = ((int16_t) xga->accel.bres_k1); - if (xga->accel.bres_k1 & 0x2000) - dminor |= ~0x1fff; - dminor >>= 1; - - destxtmp = ((int16_t) xga->accel.bres_k2); - if (xga->accel.bres_k2 & 0x2000) - destxtmp |= ~0x1fff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; + int16_t dx; + int16_t dy; + int16_t cx; + int16_t cy; + int err = xga->accel.bres_err_term; + int draw_pixel = 0; - err = ((int16_t) xga->accel.bres_err_term); - if (xga->accel.bres_err_term & 0x2000) - destxtmp |= ~0x1fff; - - if (xga->accel.octant & 0x02) { - ydir = -1; - } else { - ydir = 1; - } - - if (xga->accel.octant & 0x04) { - xdir = -1; - } else { - xdir = 1; - } + cx = xga->accel.src_map_x & 0xfff; + cy = xga->accel.src_map_y & 0xfff; dx = xga->accel.dst_map_x & 0x1fff; - if (xga->accel.dst_map_x & 0x1800) + if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; dy = xga->accel.dst_map_y & 0x1fff; - if (xga->accel.dst_map_y & 0x1800) + if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; - if (xga->accel.octant & 0x01) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); - } + if ((xga->accel.command & 0x30) == 0x30) + xga_log("Line Draw Write: BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, XDIR=%i, YDIR=%i, steep=%s, ERR=%04x.\n", xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, xdir, ydir, (xga->accel.octant & 0x01) ? "0" : "1", err); + if (xga->accel.pat_src == 8) { - while (y >= 0) { - if (xga->accel.command & 0xc0) { - if (steep) { + if ((xga->accel.command & 0x30) == 0x30) { + while (y >= 0) { + draw_pixel = 0; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (x) + draw_pixel = 1; + } else { /*Top-to-Bottom*/ + if (y) + draw_pixel = 1; + } + } else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/ + draw_pixel = 1; + else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/ + draw_pixel = 1; + + if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + ROP(1, dest_dat, src_dat); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } + } + } + } else { + if (draw_pixel) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } + } + + if (x == xga->accel.blt_width) + break; + + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + + if (err >= 0) { + err += xga->accel.bres_k2; + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + } else + err += xga->accel.bres_k1; } else { - if ((dy >= xga->accel.mask_map_origin_x_off) && (dy <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dx >= xga->accel.mask_map_origin_y_off) && (dx <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + + if (err >= 0) { + err += xga->accel.bres_k2; + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + } else + err += xga->accel.bres_k1; + } + x++; + y--; + } + } else { + while (y >= 0) { + if (xga->accel.command & 0xc0) { + if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } - } - } else { - if (steep) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } else { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; @@ -1184,61 +1401,51 @@ xga_line_draw_write(svga_t *svga) else if (((xga->accel.command & 0x30) == 0x20) && y) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } - } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); - } } - } - if (!y) { - break; - } + if (!y) + break; - while (err > 0) { - dy += ydir; - err -= (dmajor << 1); + if (xga->accel.octant & 0x01) { + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + + if (err >= 0) { + err += xga->accel.bres_k2; + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + } else + err += xga->accel.bres_k1; + } else { + if (xga->accel.octant & 0x04) + dx--; + else + dx++; + + if (err >= 0) { + err += xga->accel.bres_k2; + if (xga->accel.octant & 0x02) + dy--; + else + dy++; + } else + err += xga->accel.bres_k1; + } + y--; + x++; } - - dx += xdir; - err += (dminor << 1); - - x++; - y--; } } - - if (steep) { - xga->accel.dst_map_x = dx; - xga->accel.dst_map_y = dy; - } else { - xga->accel.dst_map_x = dy; - xga->accel.dst_map_y = dx; - } } -static int16_t -xga_dst_wrap(int16_t addr) +static void +xga_bitblt(svga_t *svga) { - addr &= 0x1fff; - return (addr & 0x1800) == 0x1800 ? (addr | 0xf800) : addr; -} - -static void -xga_bitblt(svga_t *svga) -{ - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t src_dat; uint32_t dest_dat; uint32_t old_dest_dat; @@ -1252,21 +1459,14 @@ xga_bitblt(svga_t *svga) uint32_t srcwidth = xga->accel.px_map_width[xga->accel.src_map]; uint32_t patheight = xga->accel.px_map_height[xga->accel.pat_src]; uint32_t srcheight = xga->accel.px_map_height[xga->accel.src_map]; - int mix = 0; - int xdir; - int ydir; - - if (xga->accel.octant & 0x02) { - ydir = -1; - } else { - ydir = 1; - } - - if (xga->accel.octant & 0x04) { - xdir = -1; - } else { - xdir = 1; - } + uint32_t dstheight = xga->accel.px_map_height[xga->accel.dst_map]; + uint32_t frgdcol = xga->accel.frgd_color; + uint32_t bkgdcol = xga->accel.bkgd_color; + int16_t dx; + int16_t dy; + int mix = 0; + int xdir = (xga->accel.octant & 0x04) ? -1 : 1; + int ydir = (xga->accel.octant & 0x02) ? -1 : 1; xga->accel.x = xga->accel.blt_width & 0xfff; xga->accel.y = xga->accel.blt_height & 0xfff; @@ -1275,48 +1475,72 @@ xga_bitblt(svga_t *svga) xga->accel.sy = xga->accel.src_map_y & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; xga->accel.py = xga->accel.pat_map_y & 0xfff; - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); - xga->accel.dy = xga_dst_wrap(xga->accel.dst_map_y); + dx = xga->accel.dst_map_x & 0x1fff; + dy = xga->accel.dst_map_y & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + dx |= ~0x17ff; + if (xga->accel.dst_map_y >= 0x1800) + dy |= ~0x17ff; + xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth); xga->accel.pattern = 0; + xga->accel.filling = 0; + + xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, " + "pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, " + "usesrcvramfr=%d, usevrambk=%d.\n", + xga->linear_endian_reverse, xga->access_mode & 0x0f, ydir, xga->accel.command, + xga->accel.px_map_format[xga->accel.src_map] & 0x0f, + xga->accel.px_map_format[xga->accel.pat_src] & 0x0f, + xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, + xga->accel.src_map, xga->accel.pat_src, + xga->accel.dst_map, ((xga->accel.command >> 28) & 3), ((xga->accel.command >> 30) & 3)); if (xga->accel.pat_src == 8) { if (srcheight == 7) xga->accel.pattern = 1; else { if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) { - if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2) && xga->linear_endian_reverse) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) { + if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2)) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) xga->accel.pattern = 1; - } } } } - // pclog("Pattern Map = 8: CMD = %08x: SRCBase = %08x, DSTBase = %08x, from/to vram dir = %d, cmd dir = %06x\n", xga->accel.command, srcbase, dstbase, xga->from_to_vram, xga->accel.dir_cmd); - // pclog("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n", xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3]); + xga_log("PAT8: PatFormat=%x, SrcFormat=%x, DstFormat=%x.\n", xga->accel.px_map_format[xga->accel.pat_src] & 8, (xga->accel.px_map_format[xga->accel.src_map]), (xga->accel.px_map_format[xga->accel.dst_map])); + xga_log("Pattern Map = 8: CMD = %08x: SRCBase = %08x, DSTBase = %08x, from/to vram dir = %d, " + "cmd dir = %06x\n", xga->accel.command, srcbase, dstbase, xga->from_to_vram, + xga->accel.dir_cmd); + xga_log("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, " + "sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n", + xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map, + xga->accel.dst_map, xga->accel.py, xga->accel.sy, dy, + xga->accel.px_map_width[0], xga->accel.px_map_width[1], + xga->accel.px_map_width[2], xga->accel.px_map_width[3]); + while (xga->accel.y >= 0) { if (xga->accel.command & 0xc0) { - if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); - + if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(1, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } } } @@ -1324,15 +1548,19 @@ xga_bitblt(svga_t *svga) xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); else xga->accel.sx += xdir; - xga->accel.dx = xga_dst_wrap(xga->accel.dx + xdir); + + dx += xdir; xga->accel.x--; if (xga->accel.x < 0) { - xga->accel.x = (xga->accel.blt_width & 0xfff); + xga->accel.x = xga->accel.blt_width & 0xfff; - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); + dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + dx |= ~0x17ff; xga->accel.sx = xga->accel.src_map_x & 0xfff; - xga->accel.dy = xga_dst_wrap(xga->accel.dy + ydir); + dy += ydir; + if (xga->accel.pattern) xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); else @@ -1341,8 +1569,8 @@ xga_bitblt(svga_t *svga) xga->accel.y--; if (xga->accel.y < 0) { - xga->accel.dst_map_x = xga->accel.dx; - xga->accel.dst_map_y = xga->accel.dy; + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; return; } } @@ -1353,13 +1581,12 @@ xga_bitblt(svga_t *svga) else { if (dstwidth == (xga->h_disp - 1)) { if (srcwidth == (xga->h_disp - 1)) { - if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { + if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) xga->accel.pattern = 1; - } } } else { - if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) { + if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40)) xga->accel.pattern = 0; @@ -1371,69 +1598,153 @@ xga_bitblt(svga_t *svga) } } - // pclog("Pattern Map = %d: CMD = %08x: PATBase = %08x, SRCBase = %08x, DSTBase = %08x\n", xga->accel.pat_src, xga->accel.command, patbase, srcbase, dstbase); - // pclog("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n", xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3]); - while (xga->accel.y >= 0) { - mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); - - if (xga->accel.command & 0xc0) { - if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); + xga_log("PAT%d: PatFormat=%x, SrcFormat=%x, DstFormat=%x.\n", xga->accel.pat_src, xga->accel.px_map_format[xga->accel.pat_src] & 8, (xga->accel.px_map_format[xga->accel.src_map]), (xga->accel.px_map_format[xga->accel.dst_map])); + xga_log("XGA bitblt linear endian reverse=%d, octanty=%d, src command = %08x, pxsrcmap=%x, " + "pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, dstwidth=%d, dstheight=%d, srcwidth=%d, " + "srcheight=%d, dstbase=%08x, srcbase=%08x.\n", xga->linear_endian_reverse, ydir, + xga->accel.command, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, + xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.src_map, + xga->accel.pat_src, xga->accel.dst_map, dstwidth, dstheight, srcwidth, srcheight, + dstbase, srcbase); + xga_log("Pattern Map = %d: CMD = %08x: PATBase = %08x, SRCBase = %08x, DSTBase = %08x\n", + xga->accel.pat_src, xga->accel.command, patbase, srcbase, dstbase); + xga_log("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, " + "sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d, bkgdcol = %02x\n", + xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, + xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, + xga->accel.px_map_width[0], xga->accel.px_map_width[1], + xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol); + + if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) { + while (xga->accel.y >= 0) { + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); + if (mix) + xga->accel.filling = !xga->accel.filling; - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(mix, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + if (xga->accel.command & 0xc0) { + if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } + } + } + } else { + if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + if (xga->accel.filling) { + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(1, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } + } } } - } else { - if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; - else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); + xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); + xga->accel.px++; - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - old_dest_dat = dest_dat; - ROP(mix, dest_dat, src_dat); - dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + dx++; + xga->accel.x--; + if (xga->accel.x < 0) { + xga->accel.y--; + xga->accel.x = xga->accel.blt_width & 0xfff; + + dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + dx |= ~0x17ff; + + xga->accel.sx = xga->accel.src_map_x & 0xfff; + xga->accel.px = xga->accel.pat_map_x & 0xfff; + + xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); + xga->accel.py++; + + dy++; + xga->accel.filling = 0; + + if (xga->accel.y < 0) + return; } } + } else { + while (xga->accel.y >= 0) { + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); - xga->accel.sx += xdir; - if (xga->accel.pattern) - xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth); - else - xga->accel.px += xdir; - xga->accel.dx = xga_dst_wrap(xga->accel.dx + xdir); - xga->accel.x--; - if (xga->accel.x < 0) { - xga->accel.y--; - xga->accel.x = (xga->accel.blt_width & 0xfff); + if (xga->accel.command & 0xc0) { + if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { + if (mix) + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + else + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); - xga->accel.sx = xga->accel.src_map_x & 0xfff; - xga->accel.px = xga->accel.pat_map_x & 0xfff; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(mix, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } + } + } else { + if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { + if (mix) + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + else + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; + + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { + old_dest_dat = dest_dat; + ROP(mix, dest_dat, src_dat); + dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + } + } + } - xga->accel.sy += ydir; + xga->accel.sx += xdir; if (xga->accel.pattern) - xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight); + xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth); else - xga->accel.py += ydir; - xga->accel.dy = xga_dst_wrap(xga->accel.dy + ydir); + xga->accel.px += xdir; - if (xga->accel.y < 0) { - xga->accel.dst_map_x = xga->accel.dx; - xga->accel.dst_map_y = xga->accel.dy; - return; + dx += xdir; + xga->accel.x--; + if (xga->accel.x < 0) { + xga->accel.y--; + xga->accel.x = xga->accel.blt_width & 0xfff; + + dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + dx |= ~0x17ff; + + xga->accel.sx = xga->accel.src_map_x & 0xfff; + xga->accel.px = xga->accel.pat_map_x & 0xfff; + + xga->accel.sy += ydir; + if (xga->accel.pattern) + xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight); + else + xga->accel.py += ydir; + + dy += ydir; + + if (xga->accel.y < 0) { + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; + return; + } } } } @@ -1447,6 +1758,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (addr >= 0x1800) { switch (addr & 0x7f) { + case 0x11: + xga->accel.control = val; + break; + case 0x12: xga->accel.px_map_idx = val & 3; break; @@ -1507,7 +1822,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_err_term = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } else xga->accel.bres_err_term = (xga->accel.bres_err_term & 0x3f00) | val; break; @@ -1515,7 +1830,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_err_term = (xga->accel.bres_err_term & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_err_term |= ~0x3fff; + xga->accel.bres_err_term |= ~0x1fff; } break; @@ -1523,7 +1838,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k1 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } else xga->accel.bres_k1 = (xga->accel.bres_k1 & 0x3f00) | val; break; @@ -1531,7 +1846,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k1 = (xga->accel.bres_k1 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k1 |= ~0x3fff; + xga->accel.bres_k1 |= ~0x1fff; } break; @@ -1539,7 +1854,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len >= 2) { xga->accel.bres_k2 = val & 0x3fff; if (val & 0x2000) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } else xga->accel.bres_k2 = (xga->accel.bres_k2 & 0x3f00) | val; break; @@ -1547,7 +1862,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 1) { xga->accel.bres_k2 = (xga->accel.bres_k2 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - xga->accel.bres_k2 |= ~0x3fff; + xga->accel.bres_k2 |= ~0x1fff; } break; @@ -1559,7 +1874,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.short_stroke_vector3 = (xga->accel.short_stroke >> 16) & 0xff; xga->accel.short_stroke_vector4 = (xga->accel.short_stroke >> 24) & 0xff; - // pclog("1Vector = %02x, 2Vector = %02x, 3Vector = %02x, 4Vector = %02x\n", xga->accel.short_stroke_vector1, xga->accel.short_stroke_vector2, xga->accel.short_stroke_vector3, xga->accel.short_stroke_vector4); + xga_log("1Vector = %02x, 2Vector = %02x, 3Vector = %02x, 4Vector = %02x\n", + xga->accel.short_stroke_vector1, xga->accel.short_stroke_vector2, + xga->accel.short_stroke_vector3, xga->accel.short_stroke_vector4); + xga_short_stroke(svga, xga->accel.short_stroke_vector1); xga_short_stroke(svga, xga->accel.short_stroke_vector2); xga_short_stroke(svga, xga->accel.short_stroke_vector3); @@ -1649,6 +1967,30 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.plane_mask = (xga->accel.plane_mask & 0x00ffffff) | (val << 24); break; + case 0x54: + if (len == 4) + xga->accel.carry_chain = val; + else if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff0000) | val; + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffffff00) | val; + break; + case 0x55: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff00ff) | (val << 8); + break; + case 0x56: + if (len == 2) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x0000ffff) | (val << 16); + else + xga->accel.carry_chain = (xga->accel.carry_chain & 0xff00ffff) | (val << 16); + break; + case 0x57: + if (len == 1) + xga->accel.carry_chain = (xga->accel.carry_chain & 0x00ffffff) | (val << 24); + break; + + case 0x58: if (len == 4) xga->accel.frgd_color = val; @@ -1826,39 +2168,64 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) exec_command: xga->accel.octant = xga->accel.command & 0x07; xga->accel.draw_mode = xga->accel.command & 0x30; - xga->accel.mask_mode = xga->accel.command & 0xc0; xga->accel.pat_src = ((xga->accel.command >> 12) & 0x0f); xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f); xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); - // if (xga->accel.pat_src) { - // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x, planemask = %08x\n", - // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], - // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], - // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], - // xga->accel.px_map_height[xga->accel.src_map], - // xga->accel.pat_map_x, xga->accel.pat_map_y, - // xga->accel.dst_map_x, xga->accel.dst_map_y, - // xga->accel.src_map_x, xga->accel.src_map_y, - // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, - // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], - // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); - // //pclog("\n"); - // } +#ifdef ENABLE_XGA_LOG + if (xga->accel.pat_src) + xga_log("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, " + "dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, " + "srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, " + "sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, " + "srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x, " + "planemask = %08x\n\n", + CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), + xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], + xga->accel.px_map_width[xga->accel.dst_map], + xga->accel.px_map_width[xga->accel.src_map], + xga->accel.px_map_height[xga->accel.pat_src], + xga->accel.px_map_height[xga->accel.dst_map], + xga->accel.px_map_height[xga->accel.src_map], + xga->accel.pat_map_x, xga->accel.pat_map_y, + xga->accel.dst_map_x, xga->accel.dst_map_y, + xga->accel.src_map_x, xga->accel.src_map_y, + xga->accel.pat_src, xga->accel.dst_map, + xga->accel.src_map, xga->accel.px_map_base[xga->accel.dst_map], + xga->accel.px_map_base[xga->accel.src_map], + xga->accel.px_map_base[xga->accel.pat_src], + xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, + xga->accel.px_map_format[xga->accel.src_map] & 0x0f, + xga->accel.plane_mask); +#endif + switch ((xga->accel.command >> 24) & 0x0f) { + case 2: /*Short Stroke Vectors Read */ + xga_log("Short Stroke Vectors Read.\n"); + break; case 3: /*Bresenham Line Draw Read*/ - // pclog("Line Draw Read\n"); + xga_log("Line Draw Read\n"); break; - case 4: /*Short Stroke Vectors*/ + case 4: /*Short Stroke Vectors Write*/ + xga_log("Short Stroke Vectors Write.\n"); break; case 5: /*Bresenham Line Draw Write*/ + xga_log("Line Draw Write.\n"); xga_line_draw_write(svga); break; case 8: /*BitBLT*/ + xga_log("BitBLT.\n"); xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ - // pclog("Inverting BitBLT\n"); + xga_log("Inverting BitBLT\n"); + break; + case 0x0a: /*Area Fill*/ + xga_log("Area Fill BitBLT.\n"); + xga_bitblt(svga); + break; + + default: break; } } else if (len == 2) { @@ -1883,51 +2250,67 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) goto exec_command; } break; + + default: + break; } } } static void -xga_memio_writeb(uint32_t addr, uint8_t val, void *p) +xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; xga_mem_write(addr, val, xga, svga, 1); - // pclog("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); + + xga_log("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); } static void -xga_memio_writew(uint32_t addr, uint16_t val, void *p) +xga_memio_writew(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; xga_mem_write(addr, val, xga, svga, 2); - // pclog("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); + + xga_log("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); } static void -xga_memio_writel(uint32_t addr, uint32_t val, void *p) +xga_memio_writel(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; xga_mem_write(addr, val, xga, svga, 4); - // pclog("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); + + xga_log("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); } static uint8_t -xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) +xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) { uint8_t temp = 0; addr &= 0x1fff; - if (addr < 0x1800) { - temp = xga->bios_rom.rom[addr]; + if (xga_standalone_enabled) + temp = xga->bios_rom.rom[addr]; + else + temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { + case 0x11: + temp = xga->accel.control; + if (xga->accel.control & 0x08) + temp |= 0x10; + else + temp &= ~0x10; + break; + case 0x20: temp = xga->accel.bres_err_term & 0xff; break; @@ -1982,6 +2365,9 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) case 0x7b: temp = xga->accel.dst_map_y >> 8; break; + + default: + break; } } @@ -1989,37 +2375,39 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) } static uint8_t -xga_memio_readb(uint32_t addr, void *p) +xga_memio_readb(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint8_t temp; temp = xga_mem_read(addr, xga, svga); - // pclog("[%04X:%08X]: Read MEMIOB = %04x, temp = %02x\n", CS, cpu_state.pc, addr, temp); + xga_log("[%04X:%08X]: Read MEMIOB = %04x, temp = %02x\n", CS, cpu_state.pc, addr, temp); + return temp; } static uint16_t -xga_memio_readw(uint32_t addr, void *p) +xga_memio_readw(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint16_t temp; temp = xga_mem_read(addr, xga, svga); temp |= (xga_mem_read(addr + 1, xga, svga) << 8); - // pclog("[%04X:%08X]: Read MEMIOW = %04x, temp = %04x\n", CS, cpu_state.pc, addr, temp); + xga_log("[%04X:%08X]: Read MEMIOW = %04x, temp = %04x\n", CS, cpu_state.pc, addr, temp); + return temp; } static uint32_t -xga_memio_readl(uint32_t addr, void *p) +xga_memio_readl(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint32_t temp; temp = xga_mem_read(addr, xga, svga); @@ -2027,21 +2415,22 @@ xga_memio_readl(uint32_t addr, void *p) temp |= (xga_mem_read(addr + 2, xga, svga) << 16); temp |= (xga_mem_read(addr + 3, xga, svga) << 24); - // pclog("Read MEMIOL = %04x, temp = %08x\n", addr, temp); + xga_log("[%04X:%08X]: Read MEMIOL = %04x, temp = %08x\n", CS, cpu_state.pc, addr, temp); + return temp; } static void xga_hwcursor_draw(svga_t *svga, int displine) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint8_t dat = 0; int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; int x_pos; int y_pos; int comb = 0; uint32_t *p; - int idx = (xga->cursor_data_on) ? 32 : 0; + int idx = xga->cursor_data_on ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) xga->hwcursor_latch.addr += 16; @@ -2072,6 +2461,9 @@ xga_hwcursor_draw(svga_t *svga, int displine) /* Complement */ p[x_pos] ^= 0xffffff; break; + + default: + break; } } @@ -2092,8 +2484,9 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; + uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add]; for (int i = 0; i < svga->x_add; i++) - buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } static void @@ -2107,14 +2500,61 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - right = (overscan_x >> 1); + uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; + right = (overscan_x >> 1); for (int i = 0; i < right; i++) - buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; +} + +static void +xga_render_4bpp(svga_t *svga) +{ + xga_t *xga = (xga_t *) svga->xga; + uint32_t *p; + uint32_t dat; + + if ((xga->displine + svga->y_add) < 0) + return; + + if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { + p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + + if (xga->firstline_draw == 2000) + xga->firstline_draw = xga->displine; + xga->lastline_draw = xga->displine; + + for (int x = 0; x <= xga->h_disp; x += 16) { + dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; + + dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; + + xga->ma += 8; + p += 16; + } + xga->ma &= xga->vram_mask; + } } static void -xga_render_8bpp(xga_t *xga, svga_t *svga) +xga_render_8bpp(svga_t *svga) { + xga_t *xga = (xga_t *) svga->xga; uint32_t *p; uint32_t dat; @@ -2122,7 +2562,7 @@ xga_render_8bpp(xga_t *xga, svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; + p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2130,16 +2570,16 @@ xga_render_8bpp(xga_t *xga, svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 8) { dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); - p[0] = svga->pallook[dat & 0xff]; - p[1] = svga->pallook[(dat >> 8) & 0xff]; - p[2] = svga->pallook[(dat >> 16) & 0xff]; - p[3] = svga->pallook[(dat >> 24) & 0xff]; + p[0] = xga->pallook[dat & 0xff]; + p[1] = xga->pallook[(dat >> 8) & 0xff]; + p[2] = xga->pallook[(dat >> 16) & 0xff]; + p[3] = xga->pallook[(dat >> 24) & 0xff]; dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); - p[4] = svga->pallook[dat & 0xff]; - p[5] = svga->pallook[(dat >> 8) & 0xff]; - p[6] = svga->pallook[(dat >> 16) & 0xff]; - p[7] = svga->pallook[(dat >> 24) & 0xff]; + p[4] = xga->pallook[dat & 0xff]; + p[5] = xga->pallook[(dat >> 8) & 0xff]; + p[6] = xga->pallook[(dat >> 16) & 0xff]; + p[7] = xga->pallook[(dat >> 24) & 0xff]; xga->ma += 8; p += 8; @@ -2149,8 +2589,9 @@ xga_render_8bpp(xga_t *xga, svga_t *svga) } static void -xga_render_16bpp(xga_t *xga, svga_t *svga) +xga_render_16bpp(svga_t *svga) { + xga_t *xga = (xga_t *) svga->xga; int x; uint32_t *p; uint32_t dat; @@ -2159,13 +2600,13 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; + p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; xga->lastline_draw = xga->displine; - for (x = 0; x <= (xga->h_disp); x += 8) { + for (x = 0; x <= xga->h_disp; x += 8) { dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -2188,10 +2629,10 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) } static void -xga_write(uint32_t addr, uint8_t val, void *p) +xga_write(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; if (!xga->on) { svga_write(addr, val, svga); @@ -2204,171 +2645,187 @@ xga_write(uint32_t addr, uint8_t val, void *p) if (addr >= xga->vram_size) return; - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_b; + + if (xga->access_mode & 8) { + if ((xga->access_mode & 7) == 4) + addr ^= 1; + } xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; xga->vram[addr & xga->vram_mask] = val; } static void -xga_writeb(uint32_t addr, uint8_t val, void *p) +xga_writew(uint32_t addr, uint16_t val, void *priv) { - // pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); - xga_write(addr, val, p); -} + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; -static void -xga_writew(uint32_t addr, uint16_t val, void *p) -{ - // pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); - xga_write(addr, val, p); - xga_write(addr + 1, val >> 8, p); + if (!xga->on) { + svga_writew(addr, val, svga); + return; + } + + xga_write(addr, val & 0xff, svga); + xga_write(addr + 1, val >> 8, svga); } static void -xga_writel(uint32_t addr, uint32_t val, void *p) +xga_writel(uint32_t addr, uint32_t val, void *priv) { - // pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); - xga_write(addr, val, p); - xga_write(addr + 1, val >> 8, p); - xga_write(addr + 2, val >> 16, p); - xga_write(addr + 3, val >> 24, p); + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + if (!xga->on) { + svga_writel(addr, val, svga); + return; + } + + xga_write(addr, val & 0xff, svga); + xga_write(addr + 1, (val >> 8) & 0xff, svga); + xga_write(addr + 2, (val >> 16) & 0xff, svga); + xga_write(addr + 3, (val >> 24) & 0xff, svga); } -static void -xga_write_linear(uint32_t addr, uint8_t val, void *p) +static uint8_t +xga_read(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; if (!xga->on) { - svga_write_linear(addr, val, svga); - return; + ret = svga_read(addr, svga); + return ret; } - addr &= svga->decode_mask; + addr &= xga->banked_mask; + addr += xga->read_bank; if (addr >= xga->vram_size) - return; + return ret; - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_read_b; - xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; - xga->vram[addr & xga->vram_mask] = val; + if (xga->access_mode & 8) { + if ((xga->access_mode & 7) == 4) + addr ^= 1; + } + + ret = xga->vram[addr & xga->vram_mask]; + + return ret; } -static void -xga_writew_linear(uint32_t addr, uint16_t val, void *p) +static uint16_t +xga_readw(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint16_t ret = 0xffff; if (!xga->on) { - svga_writew_linear(addr, val, svga); - return; + ret = svga_readw(addr, svga); + return ret; } - if (xga->linear_endian_reverse) { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr + 1, val, p); - xga_write_linear(addr, val >> 8, p); - } else { - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); - } - } else { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr + 1, val, p); - xga_write_linear(addr, val >> 8, p); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); - } else { - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); - } - } + ret = xga_read(addr, svga); + ret |= (xga_read(addr + 1, svga) << 8); + + return ret; } -static void -xga_writel_linear(uint32_t addr, uint32_t val, void *p) +static uint32_t +xga_readl(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint32_t ret = 0xffffffff; if (!xga->on) { - svga_writel_linear(addr, val, svga); - return; + ret = svga_readl(addr, svga); + return ret; } - xga_write_linear(addr, val, p); - xga_write_linear(addr + 1, val >> 8, p); - xga_write_linear(addr + 2, val >> 16, p); - xga_write_linear(addr + 3, val >> 24, p); + ret = xga_read(addr, svga); + ret |= (xga_read(addr + 1, svga) << 8); + ret |= (xga_read(addr + 2, svga) << 16); + ret |= (xga_read(addr + 3, svga) << 24); + + return ret; } -static uint8_t -xga_read(uint32_t addr, void *p) +static void +xga_write_linear(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; - if (!xga->on) - return svga_read(addr, svga); + if (!xga->on) { + svga_write_linear(addr, val, svga); + return; + } - addr &= xga->banked_mask; - addr += xga->read_bank; + addr &= svga->decode_mask; if (addr >= xga->vram_size) - return 0xff; - - cycles -= video_timing_read_b; - - return xga->vram[addr & xga->vram_mask]; -} + return; -static uint8_t -xga_readb(uint32_t addr, void *p) -{ - uint8_t ret; + cycles -= svga->monitor->mon_video_timing_write_b; - ret = xga_read(addr, p); + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } else if (xga->access_mode & 8) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } + } - return ret; + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + xga->vram[addr & xga->vram_mask] = val; } -static uint16_t -xga_readw(uint32_t addr, void *p) +static void +xga_writew_linear(uint32_t addr, uint16_t val, void *priv) { - uint16_t ret; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; - ret = xga_read(addr, p); - ret |= (xga_read(addr + 1, p) << 8); + if (!xga->on) { + svga_writew_linear(addr, val, svga); + return; + } - return ret; + xga_write_linear(addr, val, priv); + xga_write_linear(addr + 1, val >> 8, priv); } -static uint32_t -xga_readl(uint32_t addr, void *p) +static void +xga_writel_linear(uint32_t addr, uint32_t val, void *priv) { - uint32_t ret; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; - ret = xga_read(addr, p); - ret |= (xga_read(addr + 1, p) << 8); - ret |= (xga_read(addr + 2, p) << 16); - ret |= (xga_read(addr + 3, p) << 24); + if (!xga->on) { + svga_writel_linear(addr, val, svga); + return; + } - return ret; + xga_write_linear(addr, val, priv); + xga_write_linear(addr + 1, val >> 8, priv); + xga_write_linear(addr + 2, val >> 16, priv); + xga_write_linear(addr + 3, val >> 24, priv); } static uint8_t -xga_read_linear(uint32_t addr, void *p) +xga_read_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; if (!xga->on) return svga_read_linear(addr, svga); @@ -2376,64 +2833,74 @@ xga_read_linear(uint32_t addr, void *p) addr &= svga->decode_mask; if (addr >= xga->vram_size) - return 0xff; + return ret; - cycles -= video_timing_read_b; + cycles -= svga->monitor->mon_video_timing_read_b; + + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } else if (xga->access_mode & 8) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } + } return xga->vram[addr & xga->vram_mask]; } static uint16_t -xga_readw_linear(uint32_t addr, void *p) +xga_readw_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; - uint16_t ret; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; + uint16_t ret; if (!xga->on) return svga_readw_linear(addr, svga); - if (xga->linear_endian_reverse) { - if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { - ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr + 1, p) | (xga_read_linear(addr, p) << 8); - } else - ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); - } else { - if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { - ret = xga_read_linear(addr + 1, p) | (xga_read_linear(addr, p) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); - } else - ret = xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8); - } + ret = xga_read_linear(addr, svga); + ret |= (xga_read_linear(addr + 1, svga) << 8); + return ret; } static uint32_t -xga_readl_linear(uint32_t addr, void *p) +xga_readl_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; + uint32_t ret; if (!xga->on) return svga_readl_linear(addr, svga); - return xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8) | (xga_read_linear(addr + 2, p) << 16) | (xga_read_linear(addr + 3, p) << 24); + ret = xga_read_linear(addr, svga); + ret |= (xga_read_linear(addr + 1, svga) << 8); + ret |= (xga_read_linear(addr + 2, svga) << 16); + ret |= (xga_read_linear(addr + 3, svga) << 24); + + return ret; } static void xga_do_render(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; + xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on); switch (xga->disp_cntl_2 & 7) { + case 2: + xga_render_4bpp(svga); + break; case 3: - xga_render_8bpp(xga, svga); + xga_render_8bpp(svga); break; case 4: - xga_render_16bpp(xga, svga); + xga_render_16bpp(svga); + break; + default: break; } @@ -2451,8 +2918,9 @@ xga_do_render(svga_t *svga) } void -xga_poll(xga_t *xga, svga_t *svga) +xga_poll(void *priv, svga_t *svga) { + xga_t *xga = (xga_t *) priv; uint32_t x; int wx; int wy; @@ -2478,12 +2946,11 @@ xga_poll(xga_t *xga, svga_t *svga) if (xga->firstline == 2000) { xga->firstline = xga->displine; - video_wait_for_buffer(); + video_wait_for_buffer_monitor(svga->monitor_index); } - if (xga->hwcursor_on) { + if (xga->hwcursor_on) xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; - } xga_do_render(svga); @@ -2505,15 +2972,10 @@ xga_poll(xga_t *xga, svga_t *svga) if (xga->sc == xga->rowcount) { xga->sc = 0; - if ((xga->disp_cntl_2 & 7) == 4) { - xga->maback += (xga->rowoffset << 4); - if (xga->interlace) - xga->maback += (xga->rowoffset << 4); - } else { + xga->maback += (xga->rowoffset << 3); + if (xga->interlace) xga->maback += (xga->rowoffset << 3); - if (xga->interlace) - xga->maback += (xga->rowoffset << 3); - } + xga->maback &= xga->vram_mask; xga->ma = xga->maback; } else { @@ -2524,13 +2986,14 @@ xga_poll(xga_t *xga, svga_t *svga) } xga->vc++; - xga->vc &= 2047; + xga->vc &= 0x7ff; if (xga->vc == xga->split) { if (xga->interlace && xga->oddeven) xga->ma = xga->maback = (xga->rowoffset << 1); else xga->ma = xga->maback = 0; + xga->ma = (xga->ma << 2); xga->maback = (xga->maback << 2); @@ -2595,14 +3058,16 @@ xga_poll(xga_t *xga, svga_t *svga) static uint8_t xga_mca_read(int port, void *priv) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; - uint8_t ret = xga->pos_regs[port & 7]; + const svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = xga->pos_regs[port & 7]; if (((port & 7) == 3) && !(ret & 1)) /*Always enable the mapping.*/ ret |= 1; - //pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]); + xga_log("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, + port & 7, xga->pos_regs[port & 7]); + return ret; } @@ -2610,7 +3075,7 @@ static void xga_mca_write(int port, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; /* MCA does not write registers below 0x0100. */ if (port < 0x0102) @@ -2619,8 +3084,8 @@ xga_mca_write(int port, uint8_t val, void *priv) io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); - xga->on = 0; - vga_on = !xga->on; + xga->on = 0; + vga_on = 1; xga->linear_endian_reverse = 0; xga->a5_test = 0; @@ -2642,39 +3107,46 @@ xga_mca_write(int port, uint8_t val, void *priv) else mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); } - //pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr); + + xga_log("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, " + "rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, + xga->instance, xga->rom_addr); } static uint8_t xga_mca_feedb(void *priv) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + const svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; return xga->pos_regs[2] & 1; } static void -xga_mca_reset(void *p) +xga_mca_reset(void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + mem_mapping_disable(&xga->bios_rom.mapping); + mem_mapping_disable(&xga->memio_mapping); xga->on = 0; - vga_on = !xga->on; + vga_on = 1; xga_mca_write(0x102, 0, svga); + xga->linear_endian_reverse = 0; + xga->a5_test = 0; } static void -xga_reset(void *p) +xga_reset(void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); - xga->on = 0; - vga_on = !xga->on; + xga->on = 0; + vga_on = 1; xga->linear_endian_reverse = 0; xga->a5_test = 0; } @@ -2683,25 +3155,186 @@ static uint8_t xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; + + if (!xga_standalone_enabled) { + switch (addr) { + case 0x0100: + case 0x0101: + if (xga->instance_isa == xga->instance_num) + ret = xga->pos_regs[addr & 7]; + else + ret = 0xff; + break; + case 0x0102: + case 0x0105: + ret = xga->pos_regs[addr & 7]; + break; + case 0x0106: + ret = xga->pos_idx >> 8; + break; + case 0x0107: + ret = xga->pos_idx & 0xff; + break; + case 0x0103: + if (!(xga->pos_idx & 3)) + ret = xga->pos_regs[3]; + else + ret = 0; + + xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + break; + case 0x0104: + switch (xga->pos_idx & 3) { + case 0: + ret = xga->pos_regs[4]; + break; + case 1: + ret = xga->pos_regs[0]; + break; + case 2: + ret = xga->pos_regs[1]; + break; + case 3: + ret = 0; + break; + + default: + break; + } + + xga_log("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + if (xga->instance_isa == xga->instance_num) + ret = xga->instance_isa; + else + ret = 0; + + ret |= xga->isa_pos_enable; + break; + + default: + break; + } + } else { + switch (addr) { + case 0x0100: + case 0x0101: + ret = xga->pos_regs[addr & 7]; + break; + case 0x0103: + ret = xga->pos_regs[3] | 7; + ret |= (xga->dma_channel << 3); + break; + case 0x0102: + case 0x0104: + case 0x0105: + case 0x0106: + case 0x0107: + ret = (xga_mca_read(addr, svga)); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + if (xga->instance_isa == xga->instance_num) + ret = xga->instance_isa; + else + ret = 0; + + ret |= xga->isa_pos_enable; + break; - return (xga_mca_read(addr, svga)); + default: + break; + } + } + return ret; } static void - * - xga_init(const device_t *info) +xga_pos_out(uint16_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + if (!xga_standalone_enabled) { + switch (addr) { + case 0x0106: + xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8); + break; + case 0x0107: + xga->pos_idx = (xga->pos_idx & 0xff00) | val; + xga_log("POS IDX Write = %04x.\n", xga->pos_idx); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + xga->isa_pos_enable = val & 0x08; + break; + + default: + break; + } + } else { + switch (addr) { + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + xga->isa_pos_enable = val & 0x08; + break; + + default: + break; + } + } +} + +static void * +xga_init(const device_t *info) { if (svga_get_pri() == NULL) return NULL; - svga_t *svga = svga_get_pri(); - xga_t *xga = &svga->xga; - FILE *f; - uint32_t temp; - uint8_t *rom = NULL; + svga_t *svga = svga_get_pri(); + xga_t *xga = (xga_t *) calloc(1, sizeof(xga_t)); + FILE *fp; + uint8_t *rom = NULL; - xga->type = device_get_config_int("type"); - xga->bus = info->flags; + svga->xga = xga; + + xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr"); + xga->instance_isa = device_get_config_int("instance"); + xga->type = device_get_config_int("type"); + xga->dma_channel = device_get_config_int("dma"); + xga->bus = info->flags; xga->vram_size = (1024 << 10); xga->vram_mask = xga->vram_size - 1; @@ -2714,20 +3347,18 @@ static void xga->linear_endian_reverse = 0; xga->a5_test = 0; - f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); - (void) fseek(f, 0L, SEEK_END); - temp = ftell(f); - (void) fseek(f, 0L, SEEK_SET); + fp = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); + (void) fseek(fp, 0L, SEEK_END); + (void) fseek(fp, 0L, SEEK_SET); rom = malloc(xga->bios_rom.sz); memset(rom, 0xff, xga->bios_rom.sz); - (void) fread(rom, xga->bios_rom.sz, 1, f); - temp -= xga->bios_rom.sz; - (void) fclose(f); + (void) !fread(rom, xga->bios_rom.sz, 1, fp); + (void) fclose(fp); xga->bios_rom.rom = rom; xga->bios_rom.mask = xga->bios_rom.sz - 1; - if (f != NULL) { + if (fp != NULL) { free(rom); } @@ -2739,25 +3370,28 @@ static void xga->rom_addr = 0; rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); - xga->pos_regs[2] = 1 | 0x0c | 0xf0; + if (!xga_standalone_enabled) + rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); + + xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr; xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->pos_regs[4] = 1 | 2; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); } - mem_mapping_add(&xga->video_mapping, 0, 0, xga_readb, xga_readw, xga_readl, - xga_writeb, xga_writew, xga_writel, + mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl, + xga_write, xga_writew, xga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, xga_write_linear, xga_writew_linear, xga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); + !xga_standalone_enabled ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); - mem_mapping_disable(&xga->video_mapping); mem_mapping_disable(&xga->linear_mapping); mem_mapping_disable(&xga->memio_mapping); @@ -2768,22 +3402,49 @@ static void mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga); } else { io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); + if (!xga_standalone_enabled) + io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga); + io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); } - return svga; } +static void * +svga_xga_init(const device_t *info) +{ + svga_t *svga = (svga_t *) calloc(1, sizeof(svga_t)); + + video_inform(VIDEO_FLAG_TYPE_XGA, &timing_xga_isa); + + svga_init(info, svga, svga, 1 << 18, /*256kB*/ + NULL, + svga_xga_in, svga_xga_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, svga_xga_in, NULL, NULL, svga_xga_out, NULL, NULL, svga); + + svga->bpp = 8; + svga->miscout = 1; + xga_active = 1; + + return xga_init(info); +} + static void -xga_close(void *p) +xga_close(void *priv) { - svga_t *svga = (svga_t *) p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; if (svga) { free(xga->vram); free(xga->changedvram); + + free(xga); } } @@ -2793,23 +3454,55 @@ xga_available(void) return rom_present(XGA_BIOS_PATH) && rom_present(XGA2_BIOS_PATH); } +static int +inmos_xga_available(void) +{ + return rom_present(INMOS_XGA_BIOS_PATH); +} + static void -xga_speed_changed(void *p) +xga_speed_changed(void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; svga_recalctimings(svga); } static void -xga_force_redraw(void *p) +xga_force_redraw(void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; svga->fullchange = svga->monitor->mon_changeframecount; } -static const device_config_t xga_configuration[] = { +static const device_config_t xga_mca_configuration[] = { + // clang-format off + { + .name = "type", + .description = "XGA type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "XGA-1", + .value = 0 + }, + { + .description = "XGA-2", + .value = 1 + }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_config_t xga_isa_configuration[] = { // clang-format off { .name = "type", @@ -2831,8 +3524,67 @@ static const device_config_t xga_configuration[] = { { .description = "" } } }, + { + .name = "instance", + .description = "Instance", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 6, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "0 (2100h-210Fh)", .value = 0 }, + { .description = "1 (2110h-211Fh)", .value = 1 }, + { .description = "2 (2120h-212Fh)", .value = 2 }, + { .description = "3 (2130h-213Fh)", .value = 3 }, + { .description = "4 (2140h-214Fh)", .value = 4 }, + { .description = "5 (2150h-215Fh)", .value = 5 }, + { .description = "6 (2160h-216Fh)", .value = 6 }, + { .description = "7 (2170h-217Fh)", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "ext_mem_addr", + .description = "MMIO address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x00f0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800h", .value = 0x0040 }, + { .description = "CA00h", .value = 0x0050 }, + { .description = "CC00h", .value = 0x0060 }, + { .description = "CE00h", .value = 0x0070 }, + { .description = "D000h", .value = 0x0080 }, + { .description = "D200h", .value = 0x0090 }, + { .description = "D400h", .value = 0x00a0 }, + { .description = "D600h", .value = 0x00b0 }, + { .description = "D800h", .value = 0x00c0 }, + { .description = "DA00h", .value = 0x00d0 }, + { .description = "DC00h", .value = 0x00e0 }, + { .description = "DE00h", .value = 0x00f0 }, + { .description = "" } + }, + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "DMA 6", .value = 6 }, + { .description = "DMA 7", .value = 7 }, + { .description = "" } + }, + }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xga_device = { @@ -2846,7 +3598,7 @@ const device_t xga_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_configuration + .config = xga_mca_configuration }; const device_t xga_isa_device = { @@ -2860,13 +3612,27 @@ const device_t xga_isa_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_configuration + .config = xga_isa_configuration +}; + +const device_t inmos_isa_device = { + .name = "INMOS XGA (ISA)", + .internal_name = "inmos_xga_isa", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = svga_xga_init, + .close = xga_close, + .reset = xga_reset, + { .available = inmos_xga_available }, + .speed_changed = xga_speed_changed, + .force_redraw = xga_force_redraw, + .config = xga_isa_configuration }; void xga_device_add(void) { - if (!xga_enabled) + if (!xga_standalone_enabled) return; if (machine_has_bus(machine, MACHINE_BUS_MCA)) diff --git a/src/video/video.c b/src/video/video.c index 7ecb0e5f92..01c3981182 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -78,8 +78,11 @@ volatile int screenshots = 0; uint8_t edatlookup[4][4]; +uint8_t egaremap2bpp[256]; uint8_t fontdat[2048][8]; /* IBM CGA font */ uint8_t fontdatm[2048][16]; /* IBM MDA font */ +uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */ +uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */ uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ uint8_t fontdat12x18[256][36]; /* IM1024 font */ @@ -106,7 +109,7 @@ void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy void *(*video_copy)(void *__restrict, const void *__restrict, size_t); #endif -PALETTE cgapal = { +PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, {0,0,0}, {21,63,21}, {63,21,21}, {63,63,21}, @@ -127,109 +130,108 @@ PALETTE cgapal = { {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, }; -PALETTE cgapal_mono[6] = { - { /* 0 - green, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05}, - {0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a}, - {0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01}, - {0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08}, - {0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, +PALETTE cgapal_mono[6] = { + { /* 0 - green, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05}, + {0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a}, + {0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01}, + {0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08}, + {0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, }, - { /* 1 - green, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05}, - {0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08}, - {0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08}, - {0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c}, - {0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, + { /* 1 - green, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05}, + {0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08}, + {0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08}, + {0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c}, + {0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, }, - { /* 2 - amber, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00}, - {0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00}, - {0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00}, - {0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00}, - {0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, + { /* 2 - amber, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00}, + {0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00}, + {0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00}, + {0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00}, + {0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, }, - { /* 3 - amber, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00}, - {0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00}, - {0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00}, - {0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00}, - {0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, + { /* 3 - amber, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00}, + {0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00}, + {0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00}, + {0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00}, + {0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, }, - { /* 4 - grey, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18}, - {0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28}, - {0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b}, - {0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22}, - {0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, + { /* 4 - grey, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18}, + {0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28}, + {0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b}, + {0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22}, + {0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, }, - { /* 5 - grey, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15}, - {0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22}, - {0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21}, - {0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d}, - {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, + { /* 5 - grey, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15}, + {0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22}, + {0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21}, + {0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d}, + {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, } }; -const uint32_t shade[5][256] = -{ - {0}, // RGB Color (unused) - {0}, // RGB Grayscale (unused) - { // Amber monitor - 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, - 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, - 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, - 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, - 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, - 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, - 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, - 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, - 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, - 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, - 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, - 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, - 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, - 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, - 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, - 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 - }, - { // Green monitor - 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, - 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, - 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, - 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, - 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, - 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, - 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, - 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, - 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, - 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, - 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, - 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, - 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, - 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, - 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, - 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 - }, - { // White monitor - 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, - 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, - 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, - 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, - 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, - 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, - 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, - 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, - 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, - 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, - 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, - 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, - 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, - 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, - 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, - 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec - } +const uint32_t shade[5][256] = { + {0}, // RGB Color (unused) + {0}, // RGB Grayscale (unused) + { // Amber monitor + 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, + 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, + 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, + 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, + 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, + 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, + 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, + 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, + 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, + 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, + 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, + 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, + 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, + 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, + 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, + 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 + }, + { // Green monitor + 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, + 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, + 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, + 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, + 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, + 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, + 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, + 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, + 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, + 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, + 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, + 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, + 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, + 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, + 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, + 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 + }, + { // White monitor + 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, + 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, + 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, + 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, + 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, + 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, + 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, + 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, + 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, + 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, + 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, + 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, + 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, + 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, + 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, + 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec + } }; typedef struct blit_data_struct { @@ -308,13 +310,13 @@ static png_infop info_ptr[MONITORS_NUM]; static void video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { - png_bytep *b_rgb = NULL; - FILE *fp = NULL; - uint32_t temp = 0x00000000; - blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + png_bytep *b_rgb = NULL; + FILE *fp = NULL; + uint32_t temp = 0x00000000; + const blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; /* create file */ - fp = plat_fopen((char *) fn, (char *) "wb"); + fp = plat_fopen(fn, (const char *) "wb"); if (!fp) { video_log("[video_take_screenshot] File %s could not be opened for writing", fn); return; @@ -423,8 +425,8 @@ void * video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size) #endif { - uint32_t *dest_ex = (uint32_t *) _Dst; - uint32_t *src_ex = (uint32_t *) _Src; + uint32_t *dest_ex = (uint32_t *) _Dst; + const uint32_t *src_ex = (const uint32_t *) _Src; _Size /= sizeof(uint32_t); @@ -496,8 +498,8 @@ pixel_to_color(uint8_t *pixels32, uint8_t pos) uint32_t temp; temp = *(pixels32 + pos) & 0x03; switch (temp) { - case 0: default: + case 0: return 0x00; case 1: return 0x07; @@ -599,8 +601,27 @@ cgapal_rebuild_monitor(int monitor_index) } } - if (cga_palette_monitor == 7) + if (cga_palette_monitor == 8) palette_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); + else if (cga_palette_monitor == 10) { + /* IBM 5153 CRT, colors by VileR */ + palette_lookup[0x10] = 0x00000000; + palette_lookup[0x11] = 0x000000c4; + palette_lookup[0x12] = 0x0000c400; + palette_lookup[0x13] = 0x0000c4c4; + palette_lookup[0x14] = 0x00c40000; + palette_lookup[0x15] = 0x00c400c4; + palette_lookup[0x16] = 0x00c47e00; + palette_lookup[0x17] = 0x00c4c4c4; + palette_lookup[0x18] = 0x004e4e4e; + palette_lookup[0x19] = 0x004e4edc; + palette_lookup[0x1a] = 0x004edc4e; + palette_lookup[0x1b] = 0x004ef3f3; + palette_lookup[0x1c] = 0x00dc4e4e; + palette_lookup[0x1d] = 0x00f34ef3; + palette_lookup[0x1e] = 0x00f3f34e; + palette_lookup[0x1f] = 0x00ffffff; + } } void @@ -774,23 +795,27 @@ hline(bitmap_t *b, int x1, int y, int x2, uint32_t col) } void -blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys) +blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs), UNUSED(int ys)) { + // } void -stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) +stretch_blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int xs1), UNUSED(int ys1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs2), UNUSED(int ys2)) { + // } void -rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col) +rectfill(UNUSED(bitmap_t *b), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(uint32_t col)) { + // } void -set_palette(PALETTE p) +set_palette(UNUSED(PALETTE p)) { + // } void @@ -806,9 +831,9 @@ destroy_bitmap(bitmap_t *b) bitmap_t * create_bitmap(int x, int y) { - bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint32_t *))); + bitmap_t *b = calloc(sizeof(bitmap_t), (y * sizeof(uint32_t *))); - b->dat = malloc((size_t) x * y * 4); + b->dat = calloc((size_t) x * y, 4); for (int c = 0; c < y; c++) b->line[c] = &(b->dat[c * x]); b->w = x; @@ -877,29 +902,27 @@ video_monitor_close(int monitor_index) void video_init(void) { - int c; - int d; uint8_t total[2] = { 0, 1 }; - for (c = 0; c < 16; c++) { + for (uint8_t c = 0; c < 16; c++) { cga_2_table[c] = (total[(c >> 3) & 1] << 0) | (total[(c >> 2) & 1] << 8) | (total[(c >> 1) & 1] << 16) | (total[(c >> 0) & 1] << 24); } - for (c = 0; c < 64; c++) { + for (uint8_t c = 0; c < 64; c++) { cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; if ((c & 0x17) == 6) cgapal[c + 64].g >>= 1; } - for (c = 0; c < 64; c++) { + for (uint8_t c = 0; c < 64; c++) { cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; } - for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { + for (uint8_t c = 0; c < 4; c++) { + for (uint8_t d = 0; d < 4; d++) { edatlookup[c][d] = 0; if (c & 1) edatlookup[c][d] |= 1; @@ -912,24 +935,36 @@ video_init(void) } } + for (uint16_t c = 0; c < 256; c++) { + egaremap2bpp[c] = 0; + if (c & 0x01) + egaremap2bpp[c] |= 0x01; + if (c & 0x04) + egaremap2bpp[c] |= 0x02; + if (c & 0x10) + egaremap2bpp[c] |= 0x04; + if (c & 0x40) + egaremap2bpp[c] |= 0x08; + } + video_6to8 = malloc(4 * 256); - for (c = 0; c < 256; c++) + for (uint16_t c = 0; c < 256; c++) video_6to8[c] = calc_6to8(c); video_8togs = malloc(4 * 256); - for (c = 0; c < 256; c++) + for (uint16_t c = 0; c < 256; c++) video_8togs[c] = c | (c << 16) | (c << 24); video_8to32 = malloc(4 * 256); - for (c = 0; c < 256; c++) + for (uint16_t c = 0; c < 256; c++) video_8to32[c] = calc_8to32(c); video_15to32 = malloc(4 * 65536); - for (c = 0; c < 65536; c++) + for (uint32_t c = 0; c < 65536; c++) video_15to32[c] = calc_15to32(c & 0x7fff); video_16to32 = malloc(4 * 65536); - for (c = 0; c < 65536; c++) + for (uint32_t c = 0; c < 65536; c++) video_16to32[c] = calc_16to32(c); memset(monitors, 0, sizeof(monitors)); @@ -1087,6 +1122,19 @@ loadfont_common(FILE *f, int format) for (d = 0; d < 8; d++) fontdat[c][d] = fgetc(f) & 0xff; break; + + + case 11: /* PC200 */ + for (d = 0; d < 4; d++) { + /* There are 4 fonts in the ROM */ + for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm2[256 * d + c][0], 1, 16, f); + for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat2[256 * d + c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + } + break; } (void) fclose(f); @@ -1095,14 +1143,14 @@ loadfont_common(FILE *f, int format) void loadfont_ex(char *s, int format, int offset) { - FILE *f; + FILE *fp; - f = rom_fopen(s, "rb"); - if (f == NULL) + fp = rom_fopen(s, "rb"); + if (fp == NULL) return; - fseek(f, offset, SEEK_SET); - loadfont_common(f, format); + fseek(fp, offset, SEEK_SET); + loadfont_common(fp, format); } void @@ -1115,8 +1163,10 @@ uint32_t video_color_transform(uint32_t color) { uint8_t *clr8 = (uint8_t *) &color; - /* if (!video_grayscale && !invert_display) - return color; */ +#if 0 + if (!video_grayscale && !invert_display) + return color; +#endif if (video_grayscale) { if (video_graytype) { if (video_graytype == 1) @@ -1129,7 +1179,7 @@ video_color_transform(uint32_t color) case 2: case 3: case 4: - color = (uint32_t) shade[video_grayscale][color]; + color = shade[video_grayscale][color]; break; default: clr8[3] = 0; diff --git a/src/vnc.c b/src/vnc.c index 8743c1e17e..7b4b1f7b09 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -46,15 +46,6 @@ static int ptr_x; static int ptr_y; static int ptr_but; -typedef struct { - int buttons; - int dx; - int dy; - int dwheel; -} MOUSESTATE; - -static MOUSESTATE ms; - #ifdef ENABLE_VNC_LOG int vnc_do_log = ENABLE_VNC_LOG; @@ -82,24 +73,31 @@ vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl) vnc_kbinput(down ? 1 : 0, (int) k); } -void -vnc_mouse_poll(void) +static void +vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) { - static int b = 0; - if (ms.dx != 0 || ms.dy != 0) { - mouse_x += ms.dx; - mouse_y += ms.dy; + int dx; + int dy; + int b; - ms.dx = 0; - ms.dy = 0; + b = 0x00; + if (but & 0x01) + b |= 0x01; + if (but & 0x02) + b |= 0x04; + if (but & 0x04) + b |= 0x02; + mouse_set_buttons_ex(b); + ptr_but = but; - // pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); - } + dx = (x - ptr_x) / 0.96; /* TODO: Figure out the correct scale factor for X and Y. */ + dy = (y - ptr_y) / 0.96; - if (b != ms.buttons) { - mouse_buttons = ms.buttons; - b = ms.buttons; - } + /* VNC uses absolute positions within the window, no deltas. */ + mouse_scale(dx, dy); + + ptr_x = x; + ptr_y = y; mouse_x_abs = (double)ptr_x / (double)allowedX; mouse_y_abs = (double)ptr_y / (double)allowedY; @@ -108,31 +106,12 @@ vnc_mouse_poll(void) if (mouse_y_abs > 1.0) mouse_y_abs = 1.0; if (mouse_x_abs < 0.0) mouse_x_abs = 0.0; if (mouse_y_abs < 0.0) mouse_y_abs = 0.0; -} - -static void -vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) -{ - ms.buttons = 0; - if (but & 0x01) - ms.buttons |= 0x01; - if (but & 0x02) - ms.buttons |= 0x04; - if (but & 0x04) - ms.buttons |= 0x02; - ptr_but = but; - - /* VNC uses absolute positions within the window, no deltas. */ - ms.dx += (x - ptr_x) / 0.96; /* TODO: Figure out the correct scale factor for X and Y. */ - ms.dy += (y - ptr_y) / 0.96; - ptr_x = x; - ptr_y = y; rfbDefaultPtrAddEvent(but, x, y, cl); } static void -vnc_clientgone(rfbClientPtr cl) +vnc_clientgone(UNUSED(rfbClientPtr cl)) { vnc_log("VNC: client disconnected: %s\n", cl->host); @@ -143,7 +122,9 @@ vnc_clientgone(rfbClientPtr cl) vnc_log("VNC: no clients, pausing..\n"); /* Disable the mouse. */ - // plat_mouse_capture(0); +#if 0 + plat_mouse_capture(0); +#endif mouse_set_poll_ex(NULL); plat_pause(1); @@ -161,15 +142,16 @@ vnc_newclient(rfbClientPtr cl) /* Reset the mouse. */ ptr_x = allowedX / 2; ptr_y = allowedY / 2; - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - memset(&ms, 0, sizeof(MOUSESTATE)); + mouse_clear_coords(); + mouse_clear_buttons(); /* We now have clients, un-pause the emulator if needed. */ vnc_log("VNC: unpausing..\n"); /* Enable the mouse. */ - // plat_mouse_capture(1); +#if 0 + plat_mouse_capture(1); +#endif mouse_set_poll_ex(vnc_mouse_poll); plat_pause(0); @@ -325,7 +307,7 @@ vnc_pause(void) } void -vnc_take_screenshot(wchar_t *fn) +vnc_take_screenshot(UNUSED(wchar_t *fn)) { vnc_log("VNC: take_screenshot\n"); } diff --git a/src/vnc_keymap.c b/src/vnc_keymap.c index 923f6ecf05..599ba1d9b2 100644 --- a/src/vnc_keymap.c +++ b/src/vnc_keymap.c @@ -623,21 +623,21 @@ static int keysyms_ff[] = { #ifdef ENABLE_VNC_KEYMAP_LOG int vnc_keymap_do_log = ENABLE_VNC_KEYMAP_LOG; -#endif static void -vnc_keymap_log(const char *format, ...) +vnc_keymap_log(const char *fmt, ...) { -#ifdef ENABLE_VNC_KEYMAP_LOG va_list ap; if (vnc_keymap_do_log) { - va_start(ap, format); - pclog_ex(format, ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); va_end(ap); } -#endif } +#else +# define vnc_keymap_log(fmt, ...) +#endif void vnc_kbinput(int down, int k) @@ -665,8 +665,8 @@ vnc_kbinput(int down, int k) /* Send this scancode sequence to the PC keyboard. */ switch (scan >> 8) { - case 0x00: default: + case 0x00: if (scan & 0xff) keyboard_input(down, scan & 0xff); break; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 4b60cb9309..a80458938b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,15 +64,15 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA - MGA := y - endif ifndef OLIVETTI OLIVETTI := y endif ifndef OPEN_AT OPEN_AT := y endif + ifndef OPL4ML + OPL4ML := y + endif ifndef PAS16 PAS16 := y endif @@ -128,15 +128,15 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA - MGA := n - endif ifndef OLIVETTI OLIVETTI := n endif ifndef OPEN_AT OPEN_AT := n endif + ifndef OPL4ML + OPL4ML := n + endif ifndef PAS16 PAS16 := n endif @@ -242,13 +242,13 @@ PROG := 86Box # Nothing should need changing from here on.. # ######################################################################### VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu cpu/softfloat \ - cdrom chipset device disk disk/minivhd floppy \ + cpu/808x cdrom chipset device disk disk/minivhd floppy \ game machine mem printer \ sio sound \ sound/munt sound/munt/c_interface sound/munt/sha1 \ sound/munt/srchelper sound/munt/srchelper/srctools/src \ sound/resid-fp sound/ymfm \ - scsi video network network/slirp win + scsi video network win WINDRES := windres STRIP := strip @@ -269,8 +269,8 @@ else endif ifeq ($(CLANG), y) - CPP := ${TOOL_PREFIX}clang++ - CC := ${TOOL_PREFIX}clang + CPP := clang++ + CC := clang else CPP := ${TOOL_PREFIX}g++ CC := ${TOOL_PREFIX}gcc @@ -304,17 +304,38 @@ ifeq ($(DEBUG), y) ifndef COPTIM COPTIM := -Og endif + ifndef CXXOPTIM + ifeq ($(CLANG), y) + CXXOPTIM := -Os + else + CXXOPTIM := -Og + endif + endif else DFLAGS += -g0 ifeq ($(OPTIM), y) AOPTIM := -mtune=native ifndef COPTIM - COPTIM := -O3 -ffp-contract=fast -flto + CXXOPTIM := -O3 -ffp-contract=fast -flto + endif + ifndef CXXOPTIM + ifeq ($(CLANG), y) + CXXOPTIM := -Os -ffp-contract=fast -flto + else + CXXOPTIM := -O3 -ffp-contract=fast -flto + endif endif else ifndef COPTIM COPTIM := -O3 endif + ifndef CXXOPTIM + ifeq ($(CLANG), y) + CXXOPTIM := -Os + else + CXXOPTIM := -O3 + endif + endif endif endif ifeq ($(AVX), y) @@ -475,15 +496,15 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif - ifeq ($(MGA), y) - OPTS += -DUSE_MGA - DEVBROBJ += vid_mga.o - endif - ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif + ifeq ($(OPL4ML), y) + OPTS += -DUSE_OPL4ML + DEVBROBJ += midi_opl4.o midi_opl4_yrw801.o + endif + ifeq ($(PAS16), y) OPTS += -DUSE_PAS16 DEVBROBJ += snd_pas16.o @@ -531,7 +552,9 @@ CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ # Add freetyp2 references through pkgconfig CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` -CXXFLAGS := $(CFLAGS) +CXXFLAGS := $(OPTS) $(DFLAGS) $(CXXOPTIM) $(AOPTIM) \ + $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ + -fno-strict-aliasing CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition @@ -541,21 +564,23 @@ CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ + nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo.o \ + fifo8.o usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ $(VNCOBJ) -MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o +MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o mmu_2386.o rom.o row.o \ + smram.o spd.o sst_flash.o CPUOBJ := $(DYNARECOBJ) \ $(CGTOBJ) \ cpu.o cpu_table.o fpu.o x86.o \ 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ - x86seg.o x87.o x87_timings.o \ + x86_ops_mmx.o x86seg_common.o x86seg_2386.o x86seg.o x87.o x87_timings.o \ f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \ softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o CHIPSETOBJ := 82c100.o acc2168.o \ + compaq_386.o \ contaq_82c59x.o \ cs4031.o cs8230.o \ ali1429.o ali1435.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ @@ -563,7 +588,7 @@ CHIPSETOBJ := 82c100.o acc2168.o \ ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ ioapic.o \ neat.o \ - opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \ + opti283.o opti291.o opti391.o opti495.o opti602.o opti822.o opti895.o opti5x7.o \ scamp.o scat.o \ stpc.o \ wd76c10.o vl82c480.o \ @@ -603,12 +628,14 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm mouse_bus.o \ mouse_serial.o mouse_ps2.o \ mouse_wacom_tablet.o \ - phoenix_486_jumper.o serial_passthrough.o + nec_mate_unk.o phoenix_486_jumper.o \ + serial_passthrough.o \ + unittester.o SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ - sio_it8661f.o \ + sio_it86x1f.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ sio_prime3b.o sio_prime3c.o \ sio_w83787f.o \ @@ -633,6 +660,7 @@ HDDOBJ := hdd.o \ hdc_xta.o \ hdc_esdi_at.o hdc_esdi_mca.o \ hdc_xtide.o hdc_ide.o \ + hdc_ide_ali5213.o \ hdc_ide_opti611.o \ hdc_ide_cmd640.o hdc_ide_cmd646.o \ hdc_ide_sff8038i.o @@ -654,23 +682,18 @@ SCSIOBJ := scsi.o scsi_device.o \ scsi_ncr5380.o scsi_ncr53c8xx.o \ scsi_pcscsi.o scsi_spock.o -SLIRPOBJ := net_slirp.o tinyglib.o \ - arp_table.o bootp.o cksum.o dhcpv6.o dnssearch.o if.o \ - ip_icmp.o ip_input.o ip_output.o \ - ip6_icmp.o ip6_input.o ip6_output.o \ - mbuf.o misc.o sbuf.o slirp.o socket.o \ - tcp_input.o tcp_output.o tcp_subr.o tcp_timer.o \ - udp.o udp6.o \ - util.o version.o \ - NETOBJ := network.o \ net_pcap.o \ - ${SLIRPOBJ} \ + net_slirp.o \ net_dp8390.o net_3c501.o \ net_3c503.o net_ne2000.o \ net_pcnet.o net_wd8003.o \ net_plip.o net_event.o \ - net_null.o + net_null.o \ + net_eeprom_nmc93cxx.o \ + net_tulip.o \ + net_rtl8139.o \ + net_l80225.o PRINTOBJ := png.o prt_cpmap.o \ prt_escp.o prt_text.o prt_ps.o @@ -720,8 +743,11 @@ VIDOBJ := agpgart.o video.o \ vid_vga.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ + vid_ati_mach8.o \ + vid_ati68875_ramdac.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_bt48x_ramdac.o \ + vid_chips_69000.o \ vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ vid_cl54xx.o \ vid_et3000.o \ @@ -741,6 +767,7 @@ VIDOBJ := agpgart.o video.o \ vid_s3.o vid_s3_virge.o \ vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ vid_ogc.o \ + vid_mga.o \ vid_nga.o \ vid_tvp3026_ramdac.o \ vid_xga.o @@ -795,24 +822,43 @@ else MWIN := -mwindows endif +LIBS := -lfreetype -lfluidsynth -lslirp -lbz2 -lharfbuzz -lgraphite2 -lbrotlidec \ + -lbrotlicommon -lusp10 -lrpcrt4 -lgomp -lsndfile -lflac -lmp3lame -lmpg123 \ + -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline \ + -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv + ifeq ($(OPENAL), y) - LIBS := $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ + -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ + -luuid -lws2_32 else ifeq ($(FAUDIO), y) - LIBS := $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ + -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ + -luuid -lws2_32 else - LIBS := $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 \ + -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid \ + -lws2_32 endif endif ifeq ($(RTMIDI), y) - LIBS += -lrtmidi -lwinmm + ifeq ($(CLANG), y) + LIBS += -lrtmidi.dll -lwinmm + else + LIBS += -lrtmidi -lwinmm + endif endif ifeq ($(VNC), y) LIBS += $(VNCLIB) -lws2_32 endif -LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ +ifeq ($(CLANG), y) + LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++.dll +else + LIBS += -lpng -lz -lwsock32 -liphlpapi -lpsapi -lhid -lsetupapi -luxtheme -static -lstdc++ +endif ifneq ($(X64), y) ifneq ($(ARM64), y) LIBS += -Wl,--large-address-aware diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 5734931634..cbda41e7eb 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Grafika:" #define STR_VIDEO_2 "Grafika 2:" #define STR_VOODOO "Použít grafický akcelerátor Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/a" +#define STR_IBM8514 "Grafika IBM 8514/A" #define STR_XGA "Grafika XGA" #define STR_MOUSE "Myš:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Nastala chyba při inicializaci knihovny FluidSynth." IDS_2081 "Sběrnice" IDS_2082 "Soubor" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketová mechanika %i (%s): %ls" IDS_2110 "Všechny obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Rozšířené sektorové obrazy (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Základní sektorové obrazy (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Obrazy magnetického toku (*.FDI)\0*.FDI\0Obrazy povrchu (*.86F;*.MFM)\0*.86F;*.MFM\0Všechny soubory (*.*)\0*.*\0" - IDS_2111 "Nastala chyba při inicializaci knihovny FreeType" - IDS_2112 "Nastala chyba při inicializaci knihovny SDL, je potřeba SDL2.dll" IDS_2113 "Opravdu chcete resetovat emulovaný počítač?" IDS_2114 "Opravdu chcete ukončit 86Box?" IDS_2115 "Nastala chyba při inicializaci knihovny Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "O programu 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Emulátor starých počítačů\n\nAutoři: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." + IDS_2127 "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." IDS_2128 "OK" IDS_2129 "Hardware není dostupný" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Ujistěte se, že je nainstalován " LIB_NAME_PCAP " a používáte síťové připojení s ním kompatibilní." IDS_2131 "Neplatná konfigurace" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " je potřeba pro emulaci ESC/P tiskáren." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " je potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " je potřeba pro MIDI výstup přes knihovnu FluidSynth." IDS_2135 "Vstup do režimu celé obrazovky" IDS_2136 "Nezobrazovat dále tuto zprávu" IDS_2137 "Neukončovat" diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 0dc8a47547..9859d3d26a 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Videokarte:" #define STR_VIDEO_2 "Videokarte 2:" #define STR_VOODOO "Voodoo-Grafik" -#define STR_IBM8514 "IBM 8514/a-Grafik" +#define STR_IBM8514 "IBM 8514/A-Grafik" #define STR_XGA "XGA-Grafik" #define STR_MOUSE "Maus:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "FluidSynth konnte nicht initialisiert werden" IDS_2081 "Bus" IDS_2082 "Datei" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Diskette %i (%s): %ls" IDS_2110 "Alle Images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Fortgeschrittene Sektorimages (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basissektorimages (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Fluximages (*.FDI)\0*.FDI\0Oberflächenimages (*.86F;*.MFM)\0*.86F;*.MFM\0Alle Dateien (*.*)\0*.*\0" - IDS_2111 "FreeType konnte nicht initialisiert werden" - IDS_2112 "SDL konnte nicht initialisiert werden, die Datei SDL2.dll wird benötigt" IDS_2113 "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" IDS_2114 "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" IDS_2115 "Ghostscript konnte nicht initialisiert werden" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "Über 86Box" IDS_2126 "86Box Version " EMU_VERSION - IDS_2127 "Ein Emulator für alte Computer\n\nAutoren: Sarah Walker, Miran Grča, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." + IDS_2127 "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." IDS_2128 "OK" IDS_2129 "Hardware nicht verfügbar" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Bitte stellen Sie sicher, dass " LIB_NAME_PCAP " installiert ist und sie eine " LIB_NAME_PCAP "-kompatible Netzwerkverbindung nutzen." IDS_2131 "Ungültige Konfiguration" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " wird für die ESC/P-Druckeremulation benötigt." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " wird für die FluidSynth-MIDI-Ausgabe benötigt." IDS_2135 "Vollbildmodus wird aktiviert" IDS_2136 "Diese Nachricht nicht mehr anzeigen" IDS_2137 "Nicht beenden" diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 299d100adf..a974b1862c 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" @@ -293,10 +293,10 @@ END #define STR_JOY3 "Joystick 3..." #define STR_JOY4 "Joystick 4..." -#define STR_SOUND1 "Sound card 1:" -#define STR_SOUND2 "Sound card 2:" -#define STR_SOUND3 "Sound card 3:" -#define STR_SOUND4 "Sound card 4:" +#define STR_SOUND1 "Sound card #1:" +#define STR_SOUND2 "Sound card #2:" +#define STR_SOUND3 "Sound card #3:" +#define STR_SOUND4 "Sound card #4:" #define STR_MIDI_OUT "MIDI Out Device:" #define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Unable to initialize FluidSynth" IDS_2081 "Bus" IDS_2082 "File" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2111 "Unable to initialize FreeType" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "About 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." IDS_2128 "OK" IDS_2129 "Hardware not available" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." IDS_2131 "Invalid configuration" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." IDS_2135 "Entering fullscreen mode" IDS_2136 "Don't show this message again" IDS_2137 "Don't exit" diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index 5c6932a627..c12fb4a450 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Mouse:" @@ -293,10 +293,10 @@ END #define STR_JOY3 "Joystick 3..." #define STR_JOY4 "Joystick 4..." -#define STR_SOUND1 "Sound card 1:" -#define STR_SOUND2 "Sound card 2:" -#define STR_SOUND3 "Sound card 3:" -#define STR_SOUND4 "Sound card 4:" +#define STR_SOUND1 "Sound card #1:" +#define STR_SOUND2 "Sound card #2:" +#define STR_SOUND3 "Sound card #3:" +#define STR_SOUND4 "Sound card #4:" #define STR_MIDI_OUT "MIDI Out Device:" #define STR_MIDI_IN "MIDI In Device:" #define STR_MPU401 "Standalone MPU-401" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Unable to initialize FluidSynth" IDS_2081 "Bus" IDS_2082 "File" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2111 "Unable to initialize FreeType" - IDS_2112 "Unable to initialize SDL, SDL2.dll is required" IDS_2113 "Are you sure you want to hard reset the emulated machine?" IDS_2114 "Are you sure you want to exit 86Box?" IDS_2115 "Unable to initialize Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "About 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." + IDS_2127 "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." IDS_2128 "OK" IDS_2129 "Hardware not available" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." IDS_2131 "Invalid configuration" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." IDS_2135 "Entering fullscreen mode" IDS_2136 "Don't show this message again" IDS_2137 "Don't exit" diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 8a9e436a9a..4888c09f47 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "Ratón:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Incapaz de inicializar FluidSynth" IDS_2081 "Bus" IDS_2082 "Archivo" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas las Imágenes (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2111 "Incapaz de inicializar FreeType" - IDS_2112 "Incapaz de inicializar SDL, se requiere SDL2.dll" IDS_2113 "¿Seguro que quieres resetear la máquina emulada?" IDS_2114 "¿Seguro que quieres cerrar 86Box?" IDS_2115 "Incapaz de inicializar Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "Acerca de 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." + IDS_2127 "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." IDS_2128 "Aceptar" IDS_2129 "Hardware no disponible" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Asegúrate de que " LIB_NAME_PCAP " está instalado y de que estás en una conexión de red compatible con " LIB_NAME_PCAP "." IDS_2131 "Configuración inválida" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " es necesaria para emulación de impresión ESC/P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " es necesario para salida MIDI FluidSynth." IDS_2135 "Entrando en modo pantalla completa" IDS_2136 "No mostrar más este mensaje" IDS_2137 "No salir" diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 3f8cdf8b2b..029cce6c03 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Näytönohjain:" #define STR_VIDEO_2 "Näytönohjain 2:" #define STR_VOODOO "Voodoo-grafiikkasuoritin" -#define STR_IBM8514 "IBM 8514/a-grafiikkasuoritin" +#define STR_IBM8514 "IBM 8514/A-grafiikkasuoritin" #define STR_XGA "XGA-grafiikkasuoritin" #define STR_MOUSE "Hiiri:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "FluidSynthin alustus epäonnistui" IDS_2081 "Väylä" IDS_2082 "Tiedosto" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u Mt (CHS: %i, %i, %i)" IDS_2109 "Levyke %i (%s): %ls" IDS_2110 "Kaikki levykuvat (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Kehittyneet sektorilevykuvat (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Perussektorilevykuvat (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux-levykuvat (*.FDI)\0*.FDI\0Pintalevykuvat (*.86F;*.MFM)\0*.86F;*.MFM\0Kaikki tiedostot (*.*)\0*.*\0" - IDS_2111 "FreeType:n alustus epäonnistui" - IDS_2112 "SDL:n alustus epäonnistui. Tarvitaan SDL2.dll" IDS_2113 "Haluatko varmasti käynnistää emuloidun tietokoneen uudelleen?" IDS_2114 "Haluatko varmasti sulkea 86Boxin?" IDS_2115 "Ghostscriptin alustus epäonnistui" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "Tietoja 86Box:sta" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." + IDS_2127 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." IDS_2128 "OK" IDS_2129 "Laitteisto ei ole saatavilla" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Varmista, että " LIB_NAME_PCAP " on asennettu ja että verkkoyhteytesi on " LIB_NAME_PCAP "-yhteensopiva." IDS_2131 "Virheelliset määritykset" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " vaaditaan ESC/P-tulostimen emuloimiseksi." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " vaaditaan FluidSynth MIDI-ulostuloa varten." IDS_2135 "Siirrytään koko näytön tilaan" IDS_2136 "Älä näytä tätä viestiä uudelleen" IDS_2137 "Älä poistu" diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index f5b65a741b..425656c28a 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vidéo:" #define STR_VIDEO_2 "Vidéo 2:" #define STR_VOODOO "Graphique Voodoo" -#define STR_IBM8514 "Graphique IBM 8514/a" +#define STR_IBM8514 "Graphique IBM 8514/A" #define STR_XGA "Graphique XGA" #define STR_MOUSE "Souris:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Impossible d'initialiser FluidSynth" IDS_2081 "Bus" IDS_2082 "File" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u Mo (CTS: %i, %i, %i)" IDS_2109 "Disquette %i (%s): %ls" IDS_2110 "Toutes les images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Images du secteur avancés (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Images du secteur basiques (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Images du flux (*.FDI)\0*.FDI\0Images de surface (*.86F;*.MFM)\0*.86F;*.MFM\0Tous les fichiers (*.*)\0*.*\0" - IDS_2111 "Impossible d'initialiser FreeType" - IDS_2112 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" IDS_2113 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" IDS_2114 "Etes-vous sûr de vouloir quitter 86Box?" IDS_2115 "Impossible d'initialiser Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "À propos de 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Un émulateur de vieux ordinateurs\n\nAuteurs: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." + IDS_2127 "Un émulateur de vieux ordinateurs\n\nAuteurs: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." IDS_2128 "OK" IDS_2129 "Matériel non disponible" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." IDS_2131 "Configuration non valide" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " est nécessaire pour l'émulation de l'imprimante ESC/P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " est nécessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " est nécessaire pour la sortie MIDI FluidSynth." IDS_2135 "Entrer en mode plein écran" IDS_2136 "Ne pas montrer ce message à nouveau" IDS_2137 "Ne pas sortir" diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 743e14b6f8..f01b2a8810 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_IBM8514 "IBM 8514/A grafika" #define STR_XGA "XGA grafika" #define STR_MOUSE "Miš:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Nije moguće inicijalizirati FluidSynth" IDS_2081 "Bus" IDS_2082 "Datoteka" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Sve slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Sve datoteke (*.*)\0*.*\0" - IDS_2111 "Nije moguće inicijalizirati FreeType" - IDS_2112 "Nije moguće inicijalizirati SDL, SDL2.dll je potrebno" IDS_2113 "Jeste li sigurni da želite hard resetirati emulirani sistem?" IDS_2114 "Jeste li sigurni da želite zatvoriti 86Box?" IDS_2115 "Nije moguće inicijalizirati GhostScript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "O programu 86Box" IDS_2126 "86Box verzija " EMU_VERSION - IDS_2127 "Emulator starih računala\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." + IDS_2127 "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." IDS_2128 "U redu" IDS_2129 "Hardver nije dostupan" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Provjerite je li " LIB_NAME_PCAP " instaliran i jeste li na mreži, kompadibilnoj s " LIB_NAME_PCAP "." IDS_2131 "Nevažeća konfiguracija" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " je potrebno za emuliranje ESC/P pisača." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " je potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " je potrebno za FluidSynth MIDI izlaz." IDS_2135 "Ulazim u cijelozaslonski način" IDS_2136 "Ne pokazi više ovu poruku" IDS_2137 "Ne izlazi" diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index b4fc976d66..52189426a1 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -288,7 +288,7 @@ END #define STR_VIDEO "Videokártya:" #define STR_VIDEO_2 "Videokártya 2:" #define STR_VOODOO "Voodoo-gyorsítókártya" -#define STR_IBM8514 "IBM 8514/a-gyorsítókártya" +#define STR_IBM8514 "IBM 8514/A-gyorsítókártya" #define STR_XGA "XGA-gyorsítókártya" #define STR_MOUSE "Egér:" @@ -439,7 +439,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Nem sikerült a FluidSynth inicializálása" IDS_2081 "Busz" IDS_2082 "Fájl" IDS_2083 "C" @@ -470,8 +469,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Minden képfájl (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Továbbfejlesztett szektor képek (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Alapvető szektor képek (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux képekfájlok (*.FDI)\0*.FDI\0Felületi képfájlok (*.86F;*.MFM)\0*.86F;*.MFM\0Minden fájl (*.*)\0*.*\0" - IDS_2111 "A FreeType inicializálása nem lehetséges" - IDS_2112 "Az SDL inicializálása nem lehetséges, az SDL2.dll fájl szükséges" IDS_2113 "Biztosan szeretné újraindítani az emulált gépet?" IDS_2114 "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" IDS_2115 "Nem sikerült inicializálni a Ghostscript-et" @@ -486,7 +483,7 @@ BEGIN IDS_2124 "Mentés" IDS_2125 "A 86Box névjegye" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Régi számítógépek emulátora\n\nFejlesztők: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." + IDS_2127 "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." IDS_2128 "OK" IDS_2129 "Hardver nem elérhető" #ifdef _WIN32 @@ -497,23 +494,11 @@ BEGIN IDS_2130 "Győződjön meg hogy a(z) " LIB_NAME_PCAP " telepítve van és jelenleg a " LIB_NAME_PCAP "-kompatibilis kapcsolatot használja." IDS_2131 "Érvénytelen konfiguráció" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " szükséges az ESC/P nyomtató emulációhoz." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " szükséges a FluidSynth MIDI kimenethez." IDS_2135 "Teljes képernyős módra váltás" IDS_2136 "Ne jelenítse meg újra ezt az üzenetet " IDS_2137 "Ne lépjen ki" diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index c5a726062d..e5868caa00 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -284,7 +284,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Grafica Voodoo" -#define STR_IBM8514 "Grafica IBM 8514/a" +#define STR_IBM8514 "Grafica IBM 8514/A" #define STR_XGA "Grafica XGA" #define STR_MOUSE "Mouse:" @@ -435,7 +435,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Impossibile inizializzare FluidSynth" IDS_2081 "Bus" IDS_2082 "File" IDS_2083 "C" @@ -466,8 +465,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Floppy %i (%s): %ls" IDS_2110 "Tutte le immagini (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Immagini da settori avanzati (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagini da settori basilari (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Immagini flusso (*.FDI)\0*.FDI\0Immagini da superficie (*.86F;*.MFM)\0*.86F;*.MFM\0Tutti i file (*.*)\0*.*\0" - IDS_2111 "Impossibile inizializzare FreeType" - IDS_2112 "Impossibile inizializzare SDL, SDL2.dll è necessario" IDS_2113 "Sei sicuro di voler riavviare la macchina emulata?" IDS_2114 "Sei sicuro di voler uscire da 86Box?" IDS_2115 "Impossibile inizializzare Ghostscript" @@ -483,7 +480,7 @@ BEGIN IDS_2125 "Informazioni su 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Un emulatore di computer vecchi\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." + IDS_2127 "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." IDS_2128 "OK" IDS_2129 "Hardware non disponibile" #ifdef _WIN32 @@ -494,23 +491,11 @@ BEGIN IDS_2130 "Controlla se " LIB_NAME_PCAP " è installato e che tu sia connesso ad una connessione " LIB_NAME_PCAP " compatibile." IDS_2131 "Configurazione invalida" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " è richesto per l'emuazione di stampanti ESC/P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript. (.ps)" -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " è richiesto per l'output FluidSynth MIDI." IDS_2135 "Entrando nella modalità schermo intero" IDS_2136 "Non mostrare più questo messaggio" IDS_2137 "Non uscire" diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index 36e42e357f..4090abf00b 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -15,12 +15,12 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT MainMenu MENU DISCARDABLE BEGIN - POPUP "動作(&A)" + POPUP "操作(&A)" BEGIN MENUITEM "キーボードはキャプチャが必要(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "右CTRLを左ALTへ(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "右CTRLを左ALTへ変換(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR - MENUITEM "ハードリセット(&H)...", IDM_ACTION_HRESET + MENUITEM "ハード リセット(&H)...", IDM_ACTION_HRESET MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC @@ -34,9 +34,9 @@ BEGIN MENUITEM "ステータスバーを隠す(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM "ツールバーを隠す(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "&Show non-primary monitors", IDM_VID_MONITORS - MENUITEM "ウィンドウのサイズをリサイズ可能(&R)", IDM_VID_RESIZE - MENUITEM "ウィンドウのサイズと位置を記憶(&E)", IDM_VID_REMEMBER + MENUITEM "プライマリ以外のモニターを表示(&S)", IDM_VID_MONITORS + MENUITEM "ウィンドウのサイズを変更可能(&R)", IDM_VID_RESIZE + MENUITEM "ウィンドウのサイズと位置を保存(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR POPUP "レンダラー(&N)" BEGIN @@ -49,8 +49,8 @@ BEGIN #endif END MENUITEM SEPARATOR - MENUITEM "ウィンドウのサイズを指定...", IDM_VID_SPECIFY_DIM - MENUITEM "4:3アスペクト比を固定(&O)", IDM_VID_FORCE43 + MENUITEM "ディメンションを指定...", IDM_VID_SPECIFY_DIM + MENUITEM "4:3の縦横比を強制表示(&O)", IDM_VID_FORCE43 POPUP "ウィンドウの表示倍率(&W)" BEGIN MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X @@ -71,22 +71,22 @@ BEGIN END MENUITEM "HiDPIスケーリング(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR - MENUITEM "フルスクリーン(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN - POPUP "フルスクリーンのスケール(&S)" + MENUITEM "全画面表示(&F)\tCtrl+Alt+PgUp", IDM_VID_FULLSCREEN + POPUP "全画面の拡大表示モード(&S)" BEGIN - MENUITEM "フルスクリーンに拡大(&F)", IDM_VID_FS_FULL + MENUITEM "ストレッチ モード(&F)", IDM_VID_FS_FULL MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "正方形ピクセル(アスペクト比を維持)(&S)", IDM_VID_FS_KEEPRATIO MENUITEM "整数倍(&I)", IDM_VID_FS_INT END POPUP "E&GA/(S)VGAの設定" BEGIN - MENUITEM "色を反転(&I)", IDM_VID_INVERT + MENUITEM "色反転(&I)", IDM_VID_INVERT POPUP "画面タイプ(&T)" BEGIN MENUITEM "RGB(カラー)(&C)", IDM_VID_GRAY_RGB MENUITEM "RGB(グレースケール)(&R)", IDM_VID_GRAY_MONO - MENUITEM "モニター(琥珀色)(&A)", IDM_VID_GRAY_AMBER + MENUITEM "モニター(黄色)(&A)", IDM_VID_GRAY_AMBER MENUITEM "モニター(緑色)(&G)", IDM_VID_GRAY_GREEN MENUITEM "モニター(白色)(&W)", IDM_VID_GRAY_WHITE END @@ -111,10 +111,10 @@ BEGIN MENUITEM SEPARATOR MENUITEM "環境設定(&P)...", IDM_PREFERENCES #ifdef DISCORD - MENUITEM "Discordとの連携機能(&D)", IDM_DISCORD + MENUITEM "Discord連携機能(&D)", IDM_DISCORD #endif MENUITEM SEPARATOR - MENUITEM "音量を調節(&G)...", IDM_SND_GAIN + MENUITEM "音量調整(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR MENUITEM "トレース開始\tCtrl+T", IDM_ACTION_BEGIN_TRACE @@ -123,7 +123,7 @@ BEGIN END POPUP "ヘルプ(&H)" BEGIN - MENUITEM "ドキュメント(&D)...", IDM_DOCS + MENUITEM "文書(&D)...", IDM_DOCS MENUITEM "86Boxのバージョン情報(&A)...", IDM_ABOUT END END @@ -140,11 +140,11 @@ BEGIN MENUITEM "新規イメージ(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "既存のイメージを開く(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "録音(&R)", IDM_CASSETTE_RECORD + MENUITEM "記録(&R)", IDM_CASSETTE_RECORD MENUITEM "再生(&P)", IDM_CASSETTE_PLAY - MENUITEM "冒頭に巻き戻す(&R)", IDM_CASSETTE_REWIND + MENUITEM "先頭まで巻き戻す(&R)", IDM_CASSETTE_REWIND MENUITEM "最後まで早送り(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR MENUITEM "取り出す(&J)", IDM_CASSETTE_EJECT @@ -168,7 +168,7 @@ BEGIN MENUITEM "新規イメージ(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "既存のイメージを開く(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "86Fイメージにエクスポート(&X)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR @@ -197,7 +197,7 @@ BEGIN MENUITEM "新規イメージ(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "既存のイメージを開く(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "取り出す(&J)", IDM_ZIP_EJECT MENUITEM "前のイメージを再読み込み(&R)", IDM_ZIP_RELOAD @@ -211,7 +211,7 @@ BEGIN MENUITEM "新規イメージ(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "既存のイメージを開く(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "既存のイメージを開く(書き込み保護)(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "既存のイメージを開く(書き込み禁止)(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "取り出す(&J)", IDM_MO_EJECT MENUITEM "前のイメージを再読み込み(&R)", IDM_MO_RELOAD @@ -241,49 +241,49 @@ END // #define STR_PREFERENCES "環境設定" -#define STR_SND_GAIN "音量ゲイン" +#define STR_SND_GAIN "音量調整" #define STR_NEW_FLOPPY "新規のイメージ" #define STR_CONFIG "設定" -#define STR_SPECIFY_DIM "メインウィンドウのサイズ指定" +#define STR_SPECIFY_DIM "メイン ウィンドウのサイズ指定" #define STR_OK "OK" #define STR_CANCEL "キャンセル" -#define STR_GLOBAL "これらの設定をグローバル既定値として保存する(&G)" +#define STR_GLOBAL "これらの設定をグローバル既定値として保存(&G)" #define STR_DEFAULT "既定値(&D)" #define STR_LANGUAGE "言語:" -#define STR_ICONSET "アイコンセット:" +#define STR_ICONSET "アイコン セット:" -#define STR_GAIN "ゲイン値" +#define STR_GAIN "音量" #define STR_FILE_NAME "ファイル名:" -#define STR_DISK_SIZE "ディスクサイズ:" -#define STR_RPM_MODE "回転数モード:" +#define STR_DISK_SIZE "ディスク サイズ:" +#define STR_RPM_MODE "RPMモード:" #define STR_PROGRESS "進行状況:" #define STR_WIDTH "幅:" #define STR_HEIGHT "高さ:" -#define STR_LOCK_TO_SIZE "このサイズをロックする" +#define STR_LOCK_TO_SIZE "サイズを固定" -#define STR_MACHINE_TYPE "マシンタイプ:" +#define STR_MACHINE_TYPE "マシン タイプ:" #define STR_MACHINE "マシン:" #define STR_CONFIGURE "設定" #define STR_CPU_TYPE "CPUタイプ:" #define STR_CPU_SPEED "速度:" #define STR_FPU "FPU:" -#define STR_WAIT_STATES "待機状態:" +#define STR_WAIT_STATES "ウェイト ステート:" #define STR_MB "MB" #define STR_MEMORY "メモリ:" #define STR_TIME_SYNC "時刻同期機能" -#define STR_DISABLED "無効にする" -#define STR_ENABLED_LOCAL "有効にする (現地時間)" -#define STR_ENABLED_UTC "有効にする (UTC)" -#define STR_DYNAREC "動的リコンパイラ" +#define STR_DISABLED "無効" +#define STR_ENABLED_LOCAL "有効(現地時間)" +#define STR_ENABLED_UTC "有効(UTC)" +#define STR_DYNAREC "動的再コンパイル" #define STR_SOFTFLOAT "Softfloat FPU" #define STR_VIDEO "ビデオカード:" -#define STR_VIDEO_2 "ビデオカード 2:" +#define STR_VIDEO_2 "ビデオカード2:" #define STR_VOODOO "Voodooグラフィック" -#define STR_IBM8514 "IBM 8514/aグラフィック" +#define STR_IBM8514 "IBM 8514/Aグラフィック" #define STR_XGA "XGAグラフィック" #define STR_MOUSE "マウス:" @@ -293,25 +293,25 @@ END #define STR_JOY3 "ジョイスティック3..." #define STR_JOY4 "ジョイスティック4..." -#define STR_SOUND1 "サウンドカード 1:" -#define STR_SOUND2 "サウンドカード 2:" -#define STR_SOUND3 "サウンドカード 3:" -#define STR_SOUND4 "サウンドカード 4:" +#define STR_SOUND1 "サウンド カード1:" +#define STR_SOUND2 "サウンド カード2:" +#define STR_SOUND3 "サウンド カード3:" +#define STR_SOUND4 "サウンド カード4:" #define STR_MIDI_OUT "MIDI出力デバイス:" #define STR_MIDI_IN "MIDI入力デバイス:" #define STR_MPU401 "独立型MPU-401" -#define STR_FLOAT "FLOAT32サウンドを使用する" +#define STR_FLOAT "FLOAT32サウンドを使用" #define STR_FM_DRIVER "FMシンセドライバー" -#define STR_FM_DRV_NUKED "Nuked (高精度化)" -#define STR_FM_DRV_YMFM "YMFM (より速く)" +#define STR_FM_DRV_NUKED "Nuked(高精度化)" +#define STR_FM_DRV_YMFM "YMFM(より速く)" #define STR_NET_TYPE "ネットワークタイプ:" #define STR_PCAP "PCapデバイス:" #define STR_NET "ネットワークアダプター:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET1 "ネットワーク カード1:" +#define STR_NET2 "ネットワーク カード2:" +#define STR_NET3 "ネットワーク カード3:" +#define STR_NET4 "ネットワーク カード4:" #define STR_COM1 "COM1デバイス:" #define STR_COM2 "COM2デバイス:" @@ -321,23 +321,23 @@ END #define STR_LPT2 "LPT2デバイス:" #define STR_LPT3 "LPT3デバイス:" #define STR_LPT4 "LPT4デバイス:" -#define STR_SERIAL1 "シリアルポート1" -#define STR_SERIAL2 "シリアルポート2" -#define STR_SERIAL3 "シリアルポート3" -#define STR_SERIAL4 "シリアルポート4" -#define STR_PARALLEL1 "パラレルポート1" -#define STR_PARALLEL2 "パラレルポート2" -#define STR_PARALLEL3 "パラレルポート3" -#define STR_PARALLEL4 "パラレルポート4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" - -#define STR_HDC "HDコントローラー:" -#define STR_FDC "FDコントローラー:" -#define STR_IDE_TER "第三のIDEコントローラー" -#define STR_IDE_QUA "第四のIDEコントローラー" +#define STR_SERIAL1 "シリアル ポート1" +#define STR_SERIAL2 "シリアル ポート2" +#define STR_SERIAL3 "シリアル ポート3" +#define STR_SERIAL4 "シリアル ポート4" +#define STR_PARALLEL1 "パラレル ポート1" +#define STR_PARALLEL2 "パラレル ポート2" +#define STR_PARALLEL3 "パラレル ポート3" +#define STR_PARALLEL4 "パラレル ポート4" +#define STR_SERIAL_PASS1 "シリアル ポート パススルー対応1" +#define STR_SERIAL_PASS2 "シリアル ポート パススルー対応2" +#define STR_SERIAL_PASS3 "シリアル ポート パススルー対応3" +#define STR_SERIAL_PASS4 "シリアル ポート パススルー対応4" + +#define STR_HDC "HDDコントローラー:" +#define STR_FDC "FDDコントローラー:" +#define STR_IDE_TER "第三IDEコントローラー" +#define STR_IDE_QUA "第四IDEコントローラー" #define STR_SCSI "SCSI" #define STR_SCSI_1 "コントローラー1:" #define STR_SCSI_2 "コントローラー2:" @@ -345,14 +345,14 @@ END #define STR_SCSI_4 "コントローラー4:" #define STR_CASSETTE "カセット" -#define STR_HDD "ハードディスク:" +#define STR_HDD "ハード ディスク:" #define STR_NEW "新規(&N)..." #define STR_EXISTING "既定(&E)..." #define STR_REMOVE "除去(&R)" #define STR_BUS "バス:" #define STR_CHANNEL "チャンネル:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "速度:" #define STR_SPECIFY "参照(&S)..." #define STR_SECTORS "セクター:" @@ -361,11 +361,11 @@ END #define STR_SIZE_MB "サイズ(MB):" #define STR_TYPE "タイプ:" #define STR_IMG_FORMAT "イメージ形式:" -#define STR_BLOCK_SIZE "ブロックサイズ:" +#define STR_BLOCK_SIZE "ブロック サイズ:" -#define STR_FLOPPY_DRIVES "フロッピードライブ:" +#define STR_FLOPPY_DRIVES "フロッピー ドライブ:" #define STR_TURBO "高速タイミング" -#define STR_CHECKBPB "BPBをチェック" +#define STR_CHECKBPB "BPBチェック" #define STR_CDROM_DRIVES "CD-ROMドライブ:" #define STR_CD_SPEED "速度:" @@ -374,7 +374,7 @@ END #define STR_250 "ZIP 250" #define STR_ISARTC "ISA RTCカード:" -#define STR_ISAMEM "ISAメモリー拡張カード" +#define STR_ISAMEM "ISAメモリ拡張カード" #define STR_ISAMEM_1 "カード1:" #define STR_ISAMEM_2 "カード2:" #define STR_ISAMEM_3 "カード3:" @@ -402,39 +402,38 @@ BEGIN IDS_2053 "速度" IDS_2054 "ZIP %03i %i (%s): %ls" IDS_2055 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Boxで使用可能なROMイメージが見つかりませんでした。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" + IDS_2056 "86Boxで使用可能なROMイメージが見つかりません。\n\nROMセットをダウンロードして、「roms」ディレクトリに解凍してください。" IDS_2057 "(空)" IDS_2058 "ZIPイメージ (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0すべてのファイル (*.*)\0*.*\0" IDS_2059 "高速" IDS_2060 "オン" IDS_2061 "オフ" - IDS_2062 "すべてのイメージ (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本的なセクターイメージ (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面イメージ (*.86F)\0*.86F\0" - IDS_2063 "roms/machinesディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" + IDS_2062 "すべてのイメージ (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0ベーシック セクター イメージ (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0サーフェス イメージ (*.86F)\0*.86F\0" + IDS_2063 "roms/machines ディレクトリにROMがないため、マシン「%hs」は使用できません。使用可能なマシンに切り替えます。" END STRINGTABLE DISCARDABLE BEGIN - IDS_2064 "roms/videoディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" + IDS_2064 "roms/video ディレクトリにROMがないため、ビデオカード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" IDS_2065 "マシン" - IDS_2066 "画面表示" + IDS_2066 "ディスプレイ" IDS_2067 "入力デバイス" IDS_2068 "サウンド" IDS_2069 "ネットワーク" - IDS_2070 "ポート (COM & LPT)" - IDS_2071 "ストレージコントローラ" - IDS_2072 "ハードディスク" - IDS_2073 "フロッピー/CD-ROMドライブ" - IDS_2074 "その他のリムーバブルデバイス" - IDS_2075 "その他の周辺装置" - IDS_2076 "表面イメージ (*.86F)\0*.86F\0" - IDS_2077 "クリックするとマウスをキャプチャします" - IDS_2078 "F8+F12キーでマウスを解放します" - IDS_2079 "F8+F12キーまたは中ボタンでマウスを解放します" + IDS_2070 "ポート (COM/LPT)" + IDS_2071 "ストレージ コントローラ" + IDS_2072 "ハード ディスク" + IDS_2073 "フロッピー/CD-ROMドライブ" + IDS_2074 "他のリムーバブル デバイス" + IDS_2075 "他の周辺デバイス" + IDS_2076 "サーフェス イメージ (*.86F)\0*.86F\0" + IDS_2077 "左クリックでマウスをキャプチャします" + IDS_2078 "F8+F12キーを押してマウスを解放します" + IDS_2079 "F8+F12キーまたは中クリックでマウスを解放します" END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "FluidSynthが初期化できません" IDS_2081 "バス" IDS_2082 "ファイル" IDS_2083 "C" @@ -442,32 +441,30 @@ BEGIN IDS_2085 "S" IDS_2086 "MB" IDS_2087 "Speed" - IDS_2088 "BPBをチェック" + IDS_2088 "BPBチェック" IDS_2089 "KB" IDS_2090 "ビデオレンダラーが初期化できません。" IDS_2091 "既定値" - IDS_2092 "%iつの待機状態" + IDS_2092 "%iつのウェイト ステート" IDS_2093 "タイプ" IDS_2094 "PCapのセットアップに失敗しました" IDS_2095 "PCapデバイスがありません" - IDS_2096 "不正なPCapデバイスです" + IDS_2096 "不正なPCapデバイス" IDS_2097 "標準ジョイスティック(2ボタン)" IDS_2098 "標準ジョイスティック(4ボタン)" IDS_2099 "標準ジョイスティック(6ボタン)" IDS_2100 "標準ジョイスティック(8ボタン)" IDS_2101 "CH Flightstick Pro" - IDS_2102 "Microsoft SideWinder Pad" - IDS_2103 "Thrustmaster Flight Control System" + IDS_2102 "Microsoft SideWinderパッド" + IDS_2103 "Thrustmaster飛行制御システム" IDS_2104 "なし" - IDS_2105 "キーボードアクセラレータを読み込めません。" - IDS_2106 "生の入力が登録できません。" + IDS_2105 "キーボード アクセラレータを読み込めません。" + IDS_2106 "生入力が登録できません。" IDS_2107 "%u" - IDS_2108 "%u MB (CHS: %i, %i, %i)" + IDS_2108 "%u MB (CHS値: %i、%i、%i)" IDS_2109 "フロッピー %i (%s): %ls" - IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスドセクターイメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本セクターイメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0表面イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" - IDS_2111 "FreeTypeが初期化できません" - IDS_2112 "SDLが初期化できません。SDL2.dllが必要です" - IDS_2113 "使用中のマシンをハードリセットしますか?" + IDS_2110 "すべてのイメージ (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0アドバンスド セクター イメージ (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0ベーシック セクター イメージ (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0フラックスイメージ (*.FDI)\0*.FDI\0サーフェス イメージ (*.86F;*.MFM)\0*.86F;*.MFM\0すべてのファイル (*.*)\0*.*\0" + IDS_2113 "使用中のマシンをハードリ セットしますか?" IDS_2114 "86Boxを終了しますか?" IDS_2115 "Ghostscriptが初期化できません" IDS_2116 "光磁気 %i (%ls): %ls" @@ -477,12 +474,12 @@ BEGIN IDS_2120 "終了" IDS_2121 "ROMが見つかりません" IDS_2122 "設定を保存しますか?" - IDS_2123 "保存すると使用中のマシンがハードリセットされます。" + IDS_2123 "使用中のマシンがハードリ セットされます。" IDS_2124 "保存" IDS_2125 "86Boxのバージョン情報" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "古いパソコンのエミュレーター\n\n著者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" + IDS_2127 "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" IDS_2128 "OK" IDS_2129 "ハードウェアが利用できません" #ifdef _WIN32 @@ -491,102 +488,90 @@ BEGIN #define LIB_NAME_PCAP "libpcap" #endif IDS_2130 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" - IDS_2131 "不正な設定です" -#ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "ESC/Pプリンタのエミュレーションには" LIB_NAME_FREETYPE "が必要です。" + IDS_2131 "無効な設定" #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2133 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信されたドキュメントは、PostScript(.ps)ファイルとして保存されます。" -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "FluidSynthのMIDI出力には" LIB_NAME_FLUIDSYNTH "が必要です。" - IDS_2135 "フルスクリーンに切り替えています" + IDS_2133 "PostScriptファイルをPDFに自動変換するには" LIB_NAME_GS "が必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" + IDS_2135 "全画面モードを入力" IDS_2136 "今後、このメッセージを表示しない" IDS_2137 "終了しない" IDS_2138 "リセット" IDS_2139 "リセットしない" IDS_2140 "光磁気イメージ (*.IM?;*.MDI)\0*.IM?;*.MDI\0すべてのファイル (*.*)\0*.*\0" IDS_2141 "CD-ROMイメージ (*.ISO;*.CUE)\0*.ISO;*.CUE\0すべてのファイル (*.*)\0*.*\0" - IDS_2142 "%hs デバイスの設定" - IDS_2143 "モニターのスリープモード" + IDS_2142 "%hs のデバイス設定" + IDS_2143 "モニターのスリープ モード" IDS_2144 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" IDS_2145 "OpenGL設定" - IDS_2146 "サポートされていない設定を読み込んでいます" - IDS_2147 "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" + IDS_2146 "読み込んでいる設定がサポートされません" + IDS_2147 "選択したマシンに基づくCPUタイプのフィルター機能は、使用中のマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。しかし、マシンのBIOSや他のソフトウェアと互換性がない場合があります。\n\nこの設定を有効にすることは公式にはサポートされておらず、バグレポートは無効として中止される可能性があります。" IDS_2148 "続行" IDS_2149 "カセット: %s" - IDS_2150 "カセットイメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" + IDS_2150 "カセット イメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" IDS_2151 "カートリッジ %i: %ls" - IDS_2152 "カートリッジイメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" + IDS_2152 "カートリッジ イメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" IDS_2153 "レンダラーの初期化エラー" - IDS_2154 "OpenGL (3.0コア) レンダラーが初期化できませんでした。別のレンダラーを使用してください。" + IDS_2154 "OpenGL (3.0コア) レンダラーが初期化できません。別のレンダラーを使用してください。" IDS_2155 "実行を再開" IDS_2156 "実行を一時停止" - IDS_2157 "Ctrl+Alt+DELを押し" - IDS_2158 "Ctrl+Alt+Escを押し" + IDS_2157 "Ctrl+Alt+DELを押す" + IDS_2158 "Ctrl+Alt+Escを押す" IDS_2159 "ハードリセット" IDS_2160 "ACPIシャットダウン" IDS_2161 "設定" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" + IDS_2162 "タイプ" + IDS_2163 "動的再コンパイル禁止" + IDS_2164 "旧型の動的再コンパイル" + IDS_2165 "新型の動的再コンパイル" + IDS_2166 "「roms/video」ディレクトリにROMがないため、ビデオカード#2「%hs」は使用できません。2枚目のビデオカードを無効にします。" + IDS_2167 "ネットワーク ドライバの初期化に失敗しました。" + IDS_2168 "ネットワーク設定がヌル ドライバに切り替えられます" END STRINGTABLE DISCARDABLE BEGIN - IDS_4096 "ハードディスク (%s)" + IDS_4096 "ハード ディスク (%s)" IDS_4097 "%01i:%01i" IDS_4098 "%01i" - IDS_4099 "MFM/RLLまたはESDIのCD-ROMドライブが存在しません" + IDS_4099 "MFM/RLLやESDI CD-ROMドライブが存在しません" IDS_4100 "カスタム..." - IDS_4101 "カスタム (大型)..." + IDS_4101 "カスタム (大容量)..." IDS_4102 "新規のディスクを追加" IDS_4103 "既定のディスクを追加" - IDS_4104 "HDIディスクイメージは4GBを超えることはできません。" - IDS_4105 "ディスクイメージは127GBを超えることはできません。" - IDS_4106 "ハードディスクイメージ (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0すべてのファイル (*.*)\0*.*\0" + IDS_4104 "HDIディスク イメージは4GBを超えることはできません。" + IDS_4105 "ディスク イメージは127GBを超えることはできません。" + IDS_4106 "ハード ディスク イメージ (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0すべてのファイル (*.*)\0*.*\0" IDS_4107 "ファイルの読み込みができません" IDS_4108 "ファイルの書き込みができません" - IDS_4109 "512以外のセクタサイズを持つHDIまたはHDXイメージはサポートされていません。" - IDS_4110 "USBはまだサポートされていません" - IDS_4111 "ディスクイメージファイルが既に存在します" + IDS_4109 "512以外のセクタ サイズを持つHDIまたはHDXイメージは対応していません。" + IDS_4110 "USBはまだ非対応です" + IDS_4111 "ディスク イメージ ファイルが既に存在します" IDS_4112 "有効なファイル名を指定してください。" - IDS_4113 "ディスクイメージが作成されました" + IDS_4113 "ディスク イメージが作成されました" IDS_4114 "ファイルが存在し、読み取り可能であることを確認してください。" IDS_4115 "ファイルが書き込み可能なディレクトリに保存されていることを確認してください。" - IDS_4116 "ディスクイメージのサイズが大きすぎます" + IDS_4116 "ディスク イメージのサイズが大きすぎます" IDS_4117 "新規ドライブをパーティション分割し、フォーマットを必ずしといてください。" - IDS_4118 "選択したファイルが上書きされます。使っていいですか?" - IDS_4119 "サポートされていないディスクイメージ" + IDS_4118 "選択したファイルは上書きされます。よろしいですか?" + IDS_4119 "非対応のディスク イメージ" IDS_4120 "上書き" IDS_4121 "上書きしない" IDS_4122 "Rawイメージ (.img)" IDS_4123 "HDIイメージ (.hdi)" IDS_4124 "HDXイメージ (.hdx)" - IDS_4125 "VHD(容量固定)(.vhd)" - IDS_4126 "VHD(容量可変)(.vhd)" - IDS_4127 "VHD(差分)(.vhd)" + IDS_4125 "VHD (容量固定) (.vhd)" + IDS_4126 "VHD (容量可変) (.vhd)" + IDS_4127 "VHD (差分) (.vhd)" IDS_4128 "大型ブロック (2 MB)" IDS_4129 "小型ブロック (512 KB)" IDS_4130 "VHDファイル (*.VHD)\0*.VHD\0すべてのファイル (*.*)\0*.*\0" IDS_4131 "親VHDの選択" - IDS_4132 "親イメージがディファレンシングイメージの作成の後に修正した可能性があります。\n\nイメージファイルの移動、コピーまたはこのディスクを作成したプログラムにバグが発生した可能性があります。\n\nタイムスタンプを修正しますか?" - IDS_4133 "親ディスクと子ディスクのタイムスタンプが一致しません" - IDS_4134 "VHD のタイムスタンプを修正できませんでした。" + IDS_4132 "親イメージが差分イメージの作成の後に変更される可能性があります。\n\nイメージ ファイルが移動またはコピーされたか、イメージ ファイルを作成したプログラムにバグが発生した可能性があります。\n\nタイム スタンプを修正しますか?" + IDS_4133 "親ディスクと子ディスクのタイム スタンプが一致しません" + IDS_4134 "VHD のタイム スタンプを修正できません。" IDS_4135 "%01i:%02i" IDS_4352 "MFM/RLL" @@ -638,10 +623,10 @@ BEGIN IDS_5910 "5.25"" 1 GB" IDS_5911 "5.25"" 1.3 GB" - IDS_6144 "規定の回転数" - IDS_6145 "1%低い回転数" - IDS_6146 "1.5%低い回転数" - IDS_6147 "2%低い回転数" + IDS_6144 "既定RPM" + IDS_6145 "1%低いRPM" + IDS_6146 "1.5%低いRPM" + IDS_6147 "2%低いRPM" IDS_7168 "(システム既定値)" END diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 14fff915e0..7550e0779c 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "비디오 카드:" #define STR_VIDEO_2 "비디오 카드 2:" #define STR_VOODOO "Voodoo 그래픽" -#define STR_IBM8514 "IBM 8514/a 그래픽" +#define STR_IBM8514 "IBM 8514/A 그래픽" #define STR_XGA "XGA 그래픽" #define STR_MOUSE "마우스:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "FluidSynth를 초기화할 수 없습니다" IDS_2081 "버스" IDS_2082 "파일" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "플로피 %i (%s): %ls" IDS_2110 "모든 이미지 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0어드밴스드 섹터 이미지 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0기본 섹터 이미지 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0플럭스 이미지 (*.FDI)\0*.FDI\0표면 이미지 (*.86F;*.MFM)\0*.86F;*.MFM\0모든 파일 (*.*)\0*.*\0" - IDS_2111 "FreeType을 초기화할 수 없습니다" - IDS_2112 "SDL을 초기화할 수 없습니다. SDL2.dll이 필요합니다" IDS_2113 "실행중인 머신을 재시작하시겠습니까?" IDS_2114 "86Box를 끝내시겠습니까?" IDS_2115 "Ghostscript를 초기화할 수 없습니다" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "86Box에 대해" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "고전 컴퓨터 에뮬레이터\n\n저자: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." + IDS_2127 "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." IDS_2128 "확인" IDS_2129 "하드웨어를 이용할 수 없습니다" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 LIB_NAME_PCAP "이 설치되었는지 " LIB_NAME_PCAP "에 대응하는 네트워크에 접속되어 있는지 확인해 주세요." IDS_2131 "올바르지 않은 설정입니다" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "ESC/P 프린터 에뮬레이션에 " LIB_NAME_FREETYPE "이(가) 필요합니다." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS "은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 PostScript (.ps) 파일로 저장됩니다." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "FluidSynth의 MIDI 출력에 " LIB_NAME_FLUIDSYNTH "이(가) 필요합니다." IDS_2135 "전체 화면으로 전환" IDS_2136 "이 메시지 그만 보기" IDS_2137 "끝내지 않기" diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index 0cbadf2967..6234150451 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Wideo:" #define STR_VIDEO_2 "Wideo 2:" #define STR_VOODOO "Grafika Voodoo" -#define STR_IBM8514 "Grafika IBM 8514/a" +#define STR_IBM8514 "Grafika IBM 8514/A" #define STR_XGA "Grafika XGA" #define STR_MOUSE "Mysz:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Nie można zainicjować FluidSynth" IDS_2081 "Magistrala" IDS_2082 "Plik" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Dyskietka %i (%s): %ls" IDS_2110 "Wszystkie obrazy (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Zaawansowane obrazy sektorów (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Podstawowe obrazy sektorów (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Obrazy powierzchniowe (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2111 "Nie można zainicjować FreeType" - IDS_2112 "Nie można zainicjować SDL, wymagany SDL2.dll" IDS_2113 "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" IDS_2114 "Jesteś pewien że chcesz zakończyć 86Box?" IDS_2115 "Nie można zainicjować Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "O 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Emulator starych komputerów\n\nAutorzy: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." + IDS_2127 "Emulator starych komputerów\n\nAutorzy: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i inni.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." IDS_2128 "OK" IDS_2129 "Sprzęt niedostępny" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Sprawdź, czy " LIB_NAME_PCAP " jest zainstalowany i czy posiadasz połączenie sieciowe kompatybilne z " LIB_NAME_PCAP "." IDS_2131 "Nieprawidłowa konfiguracja" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " jest wymagany do emulacji drukarki ESC-P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " jest wymagany dla wyjścia FluidSynth MIDI." IDS_2135 "Przechodzenie do trybu pełnoekranowego" IDS_2136 "Nie pokazuj więcej tego komunikatu" IDS_2137 "Nie kończ" diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index ceb530c43c..4f72a41a4b 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -26,7 +26,7 @@ BEGIN MENUITEM "&Reinicialização completa...", IDM_ACTION_HRESET MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR MENUITEM "&Pausar", IDM_ACTION_PAUSE MENUITEM SEPARATOR @@ -286,7 +286,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_IBM8514 "Gráficos IBM 8514/A" #define STR_XGA "Gráficos XGA" #define STR_MOUSE "Mouse:" @@ -311,10 +311,10 @@ END #define STR_NET_TYPE "Tipo de rede:" #define STR_PCAP "Dispositivo PCap:" #define STR_NET "Adaptador de rede:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET1 "Placa de rede 1:" +#define STR_NET2 "Placa de rede 2:" +#define STR_NET3 "Placa de rede 3:" +#define STR_NET4 "Placa de rede 4:" #define STR_COM1 "Dispositivo COM1:" #define STR_COM2 "Dispositivo COM2:" @@ -332,10 +332,10 @@ END #define STR_PARALLEL2 "Porta paralela 2" #define STR_PARALLEL3 "Porta paralela 3" #define STR_PARALLEL4 "Porta paralela 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_SERIAL_PASS1 "Encaminhamento de porta serial 1" +#define STR_SERIAL_PASS2 "Encaminhamento de porta serial 2" +#define STR_SERIAL_PASS3 "Encaminhamento de porta serial 3" +#define STR_SERIAL_PASS4 "Encaminhamento de porta serial 4" #define STR_HDC "Controlador HD:" #define STR_FDC "Controlador FD:" @@ -437,7 +437,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Não foi possível inicializar o FluidSynth" IDS_2081 "Barramento" IDS_2082 "Arquivo" IDS_2083 "CI" @@ -468,8 +467,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens de setor avançado (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens de setor básico (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os arquivos (*.*)\0*.*\0" - IDS_2111 "Não foi possível inicializar o FreeType" - IDS_2112 "Não é possível inicializar o SDL, é necessário o SDL2.dll" IDS_2113 "Tem certeza de que deseja reiniciar completamente a máquina emulada?" IDS_2114 "Tem certeza de que deseja sair do 86Box?" IDS_2115 "Não é possível inicializar o Ghostscript" @@ -485,7 +482,7 @@ BEGIN IDS_2125 "Sobre o 86Box" IDS_2126 "86Box versão" EMU_VERSION - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." + IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." IDS_2128 "OK" IDS_2129 "Hardware não disponível" #ifdef _WIN32 @@ -496,23 +493,11 @@ BEGIN IDS_2130 "Certifique-se de que " LIB_NAME_PCAP " esteja instalado e que você tenha uma conexão de rede compatível com " LIB_NAME_PCAP "." IDS_2131 "Configuração inválida" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " é necessário para emulação de impressora ESC/P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth." IDS_2135 "Entrando no modo de tela cheia" IDS_2136 "Não exibir esta mensagem novamente" IDS_2137 "Não sair" @@ -540,13 +525,13 @@ BEGIN IDS_2159 "Reinicialização completa" IDS_2160 "Desligamento por ACPI" IDS_2161 "Configurações" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" + IDS_2162 "Tipo" + IDS_2163 "Sem recompilador dinâmico" + IDS_2164 "Recompilador dinâmico antigo" + IDS_2165 "Novo recompilador dinâmico" + IDS_2166 "A placa de vídeo #2 ""%hs"" não está disponível devido à ausência de ROMs no diretório roms/video. Desabilitando a segunda placa de vídeo." + IDS_2167 "Falha ao inicializar o driver de rede" + IDS_2168 "A configuração de rede será alterada para o driver nulo" END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index c1dd53ca53..c17cfe362a 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Vídeo:" #define STR_VIDEO_2 "Vídeo 2:" #define STR_VOODOO "Gráficos Voodoo" -#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_IBM8514 "Gráficos IBM 8514/A" #define STR_XGA "Gráficos XGA" #define STR_MOUSE "Rato:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Não foi possível inicializar o FluidSynth" IDS_2081 "Barramento" IDS_2082 "Ficheiro" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CCS: %i, %i, %i)" IDS_2109 "Disquete %i (%s): %ls" IDS_2110 "Todas as imagens (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Imagens avançadas de sector (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Imagens básicas de sector (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Imagens de fluxo (*.FDI)\0*.FDI\0Imagens de superfície (*.86F;*.MFM)\0*.86F;*.MFM\0Todos os ficheiros (*.*)\0*.*\0" - IDS_2111 "Não foi possível inicializar o FreeType" - IDS_2112 "Não foi possível inicializar o SDL. O ficheiro SDL2.dll é necessário!" IDS_2113 "Tem a certeza de que quer um reinício completo da máquina emulada?" IDS_2114 "Tem a certeza de que quer sair do 86Box?" IDS_2115 "Não foi possível inicializar o Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "Acerca do 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." + IDS_2127 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." IDS_2128 "OK" IDS_2129 "Hardware não disponível" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Certifique-se de que a biblioteca " LIB_NAME_PCAP " está instalada e de que está a utilizar uma ligação de rede compatível com a biblioteca " LIB_NAME_PCAP "." IDS_2131 "Configuração inválida" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " é requerida para a emulação de impressora ESC/P." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " é necessário para a saída MIDI FluidSynth MIDI." IDS_2135 "A entrar no modo de ecrã cheio" IDS_2136 "Não mostrar mais esta mensagem" IDS_2137 "Não sair" diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 8b3e4fbc34..719dd5a358 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Видеокарта:" #define STR_VIDEO_2 "Видеокарта 2:" #define STR_VOODOO "Ускоритель Voodoo" -#define STR_IBM8514 "Ускоритель IBM 8514/a" +#define STR_IBM8514 "Ускоритель IBM 8514/A" #define STR_XGA "Ускоритель XGA" #define STR_MOUSE "Мышь:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Невозможно инициализировать FluidSynth" IDS_2081 "Шина" IDS_2082 "Файл" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Все образы (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Расширенные образы секторов (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основные образы секторов (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образы Flux (*.FDI)\0*.FDI\0Образы Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Все файлы (*.*)\0*.*\0" - IDS_2111 "Невозможно инициализировать FreeType" - IDS_2112 "Невозможно инициализировать SDL, требуется SDL2.dll" IDS_2113 "Вы уверены, что хотите выполнить холодную перезагрузку эмулируемой машины?" IDS_2114 "Вы уверены, что хотите выйти из 86Box?" IDS_2115 "Невозможно инициализировать Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "О 86Box" IDS_2126 "86Box v." EMU_VERSION - IDS_2127 "Эмулятор старых компьютеров\n\nАвторы: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." + IDS_2127 "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." IDS_2128 "OK" IDS_2129 "Оборудование недоступно" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Убедитесь, что " LIB_NAME_PCAP " установлен и ваше сетевое соединение, совместимо с " LIB_NAME_PCAP "." IDS_2131 "Недопустимая конфигурация" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "Для эмуляции принтера ESC/P требуется " LIB_NAME_FREETYPE "." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " требуется для автоматического преобразования файлов PostScript в PDF.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "Для FluidSynth MIDI-вывода требуется " LIB_NAME_FLUIDSYNTH "." IDS_2135 "Вход в полноэкранный режим" IDS_2136 "Больше не показывать это сообщение" IDS_2137 "Не выходить" diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index 439c97330f..3a8b12dbbf 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Video:" #define STR_VIDEO_2 "Video 2:" #define STR_VOODOO "Voodoo grafika" -#define STR_IBM8514 "IBM 8514/a grafika" +#define STR_IBM8514 "IBM 8514/A grafika" #define STR_XGA "XGA grafika" #define STR_MOUSE "Miška:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Ne morem inicializirati FluidSynth" IDS_2081 "Vodilo" IDS_2082 "Datoteka" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disketa %i (%s): %ls" IDS_2110 "Vse slike (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Napredne sektorske slike (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Osnovne sektorske slike (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Tokovne slike (*.FDI)\0*.FDI\0Površinske slike (*.86F;*.MFM)\0*.86F;*.MFM\0Vse datoteke (*.*)\0*.*\0" - IDS_2111 "Ne morem inicializirati FreeType" - IDS_2112 "Ne morem inicializirati SDL, potrebna je knjižica SDL2.dll" IDS_2113 "Ste prepričani, da želite ponovno zagnati emulirani sistem?" IDS_2114 "Ste prepričani, da želite zapreti 86Box?" IDS_2115 "Ne morem inicializirati Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "O programu 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Emulator starih računalnikov\n\nAvtorji: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." + IDS_2127 "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." IDS_2128 "V redu" IDS_2129 "Strojna oprema ni na voljo" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Prepičajte se, da je nameščen " LIB_NAME_PCAP " in da ste na omrežni povezavi, združljivi z " LIB_NAME_PCAP IDS_2131 "Neveljavna konfiguracija" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " je potreben za emuliranje ESC/P tiskalnika." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " je potreben za samodejno pretvorbo PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " je potreben za FluidSynth MIDI izhod." IDS_2135 "Preklapljam v celozaslonski način" IDS_2136 "Ne pokaži več tega sporočila" IDS_2137 "Prekliči izhod" diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index a9a6bbbbc3..80a436c5d1 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Ekran kartı:" #define STR_VIDEO_2 "Ekran kartı 2:" #define STR_VOODOO "Voodoo Grafikleri" -#define STR_IBM8514 "IBM 8514/a Grafikleri" +#define STR_IBM8514 "IBM 8514/A Grafikleri" #define STR_XGA "XGA Grafikleri" #define STR_MOUSE "Fare:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "FluidSynth başlatılamadı" IDS_2081 "Veri yolu" IDS_2082 "Dosya" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "Disket %i (%s): %ls" IDS_2110 "Tüm imajlar (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Gelişmiş sektör imajları (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basit sektör imajları (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Yüzey imajları (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2111 "FreeType başlatılamadı" - IDS_2112 "SDL başlatılamadı, SDL2.dll gerekmektedir" IDS_2113 "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" IDS_2114 "86Box'tan çıkmak istediğinize emin misiniz?" IDS_2115 "Ghostscript başlatılamadı" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "86Box Hakkında" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "Bir eski bilgisayar emülatörü\n\nYapanlar: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." + IDS_2127 "Bir eski bilgisayar emülatörü\n\nYapanlar: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, ve diğerleri.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." IDS_2128 "Tamam" IDS_2129 "Donanım mevcut değil" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "" LIB_NAME_PCAP " kurulu olduğundan ve " LIB_NAME_PCAP "-uyumlu bir internet ağında bulunduğunuzdan emin olun." IDS_2131 "Geçersiz konfigürasyon" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 LIB_NAME_FREETYPE " ESC/P yazıcı emülasyonu için gereklidir." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 LIB_NAME_FLUIDSYNTH " FluidSynth MIDI çıkışı için gereklidir." IDS_2135 "Tam ekran moduna geçiliyor" IDS_2136 "Bu mesajı bir daha gösterme" IDS_2137 "Çıkış yapma" diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index 49f5573e76..53f401e814 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -283,7 +283,7 @@ END #define STR_VIDEO "Відеокарта:" #define STR_VIDEO_2 "Відеокарта 2:" #define STR_VOODOO "Прискорювач Voodoo" -#define STR_IBM8514 "Прискорювач IBM 8514/a" +#define STR_IBM8514 "Прискорювач IBM 8514/A" #define STR_XGA "Прискорювач XGA" #define STR_MOUSE "Миша:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Неможливо ініціалізувати FluidSynth" IDS_2081 "Шина" IDS_2082 "Файл" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u МБ (CHS: %i, %i, %i)" IDS_2109 "Дисковод %i (%s): %ls" IDS_2110 "Усі образи (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Розширені образи секторів (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Основні образи секторів (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Образи Flux (*.FDI)\0*.FDI\0Образи Surface (*.86F;*.MFM)\0*.86F;*.MFM\0Усі файли (*.*)\0*.*\0" - IDS_2111 "Неможливо ініціалізувати FreeType" - IDS_2112 "Неможливо ініціалізувати SDL, потрібно SDL2.dll" IDS_2113 "Ви впевнені, що хочете виконати холодне перезавантаження емульованої машини?" IDS_2114 "Ви впевнені, що хочете вийти з 86Box?" IDS_2115 "Неможливо ініціалізувати Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "Про 86Box" IDS_2126 "86Box v." EMU_VERSION - IDS_2127 "Емулятор старих комп'ютерів\n\nАвтори: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." + IDS_2127 "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." IDS_2128 "OK" IDS_2129 "Обладнання недоступне" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "Переконайтесь, що " LIB_NAME_PCAP " встановлений і ваше мережеве з'єднання, сумісне з " LIB_NAME_PCAP "." IDS_2131 "Неприпустима конфігурація" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "Для емуляції принтера ESC/P потрібно " LIB_NAME_FREETYPE "." -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " потрібно для автоматичного перетворення файлів PostScript в PDF.\n\nсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів PostScript (.ps)." -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "Для FluidSynth MIDI-висновку потрібно " LIB_NAME_FLUIDSYNTH "." IDS_2135 "Вхід у повноекранний режим" IDS_2136 "Більше не показувати це повідомлення" IDS_2137 "Не виходити" diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 807f5f3a0a..1139de4eab 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -34,7 +34,7 @@ BEGIN MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM "隐藏工具栏(&T)", IDM_VID_HIDE_TOOLBAR MENUITEM SEPARATOR - MENUITEM "Show non-primary monitors(&S)", IDM_VID_MONITORS + MENUITEM "显示次要显示器(&S)", IDM_VID_MONITORS MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR @@ -137,10 +137,10 @@ CassetteSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_CASSETTE_IMAGE_NEW + MENUITEM "新建映像(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "打开已存在的映像(&E)...", IDM_CASSETTE_IMAGE_EXISTING + MENUITEM "打开已存在的映像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "录制(&R)", IDM_CASSETTE_RECORD MENUITEM "播放(&P)", IDM_CASSETTE_PLAY @@ -155,7 +155,7 @@ CartridgeSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "镜像(&I)...", IDM_CARTRIDGE_IMAGE + MENUITEM "映像(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT END @@ -165,10 +165,10 @@ FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_FLOPPY_IMAGE_NEW + MENUITEM "新建映像(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "打开已存在的映像(&E)...", IDM_FLOPPY_IMAGE_EXISTING + MENUITEM "打开已存在的映像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR @@ -183,9 +183,9 @@ BEGIN MENUITEM "静音(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY - MENUITEM "载入上一个镜像(&R)", IDM_CDROM_RELOAD + MENUITEM "载入上一个映像(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR - MENUITEM "镜像(&I)...", IDM_CDROM_IMAGE + MENUITEM "映像(&I)...", IDM_CDROM_IMAGE MENUITEM "文件夹(&F)...", IDM_CDROM_DIR END END @@ -194,13 +194,13 @@ ZIPSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_ZIP_IMAGE_NEW + MENUITEM "新建映像(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "打开已存在的映像(&E)...", IDM_ZIP_IMAGE_EXISTING + MENUITEM "打开已存在的映像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "弹出(&J)", IDM_ZIP_EJECT - MENUITEM "载入上一个镜像(&R)", IDM_ZIP_RELOAD + MENUITEM "载入上一个映像(&R)", IDM_ZIP_RELOAD END END @@ -208,13 +208,13 @@ MOSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "新建镜像(&N)...", IDM_MO_IMAGE_NEW + MENUITEM "新建映像(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR - MENUITEM "打开已存在的镜像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "打开已存在的映像(&E)...", IDM_MO_IMAGE_EXISTING + MENUITEM "打开已存在的映像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "弹出(&J)", IDM_MO_EJECT - MENUITEM "载入上一个镜像(&R)", IDM_MO_RELOAD + MENUITEM "载入上一个映像(&R)", IDM_MO_RELOAD END END @@ -242,7 +242,7 @@ END #define STR_PREFERENCES "首选项" #define STR_SND_GAIN "音量增益" -#define STR_NEW_FLOPPY "新建镜像" +#define STR_NEW_FLOPPY "新建映像" #define STR_CONFIG "设置" #define STR_SPECIFY_DIM "指定主窗口大小" @@ -276,15 +276,15 @@ END #define STR_TIME_SYNC "时间同步" #define STR_DISABLED "禁用" #define STR_ENABLED_LOCAL "启用 (本地时间)" -#define STR_ENABLED_UTC "启用 (UTC)" +#define STR_ENABLED_UTC "启用 (协调世界时)" #define STR_DYNAREC "动态重编译器" -#define STR_SOFTFLOAT "Softfloat FPU" +#define STR_SOFTFLOAT "软浮点 FPU" #define STR_VIDEO "显卡:" #define STR_VIDEO_2 "显卡 2:" -#define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" -#define STR_XGA "XGA Graphics" +#define STR_VOODOO "Voodoo 显卡" +#define STR_IBM8514 "IBM 8514/A 显卡" +#define STR_XGA "XGA 显卡" #define STR_MOUSE "鼠标:" #define STR_JOYSTICK "操纵杆:" @@ -308,10 +308,10 @@ END #define STR_NET_TYPE "网络类型:" #define STR_PCAP "PCap 设备:" #define STR_NET "网络适配器:" -#define STR_NET1 "Network card 1:" -#define STR_NET2 "Network card 2:" -#define STR_NET3 "Network card 3:" -#define STR_NET4 "Network card 4:" +#define STR_NET1 "网卡 1:" +#define STR_NET2 "网卡 2:" +#define STR_NET3 "网卡 3:" +#define STR_NET4 "网卡 4:" #define STR_COM1 "COM1 设备:" #define STR_COM2 "COM2 设备:" @@ -329,10 +329,10 @@ END #define STR_PARALLEL2 "并口 2" #define STR_PARALLEL3 "并口 3" #define STR_PARALLEL4 "并口 4" -#define STR_SERIAL_PASS1 "Serial port passthrough 1" -#define STR_SERIAL_PASS2 "Serial port passthrough 2" -#define STR_SERIAL_PASS3 "Serial port passthrough 3" -#define STR_SERIAL_PASS4 "Serial port passthrough 4" +#define STR_SERIAL_PASS1 "串口直通 1" +#define STR_SERIAL_PASS2 "串口直通 2" +#define STR_SERIAL_PASS3 "串口直通 3" +#define STR_SERIAL_PASS4 "串口直通 4" #define STR_HDC "硬盘控制器:" #define STR_FDC "软盘控制器:" @@ -347,12 +347,12 @@ END #define STR_HDD "硬盘:" #define STR_NEW "新建(&N)..." -#define STR_EXISTING "已有镜像(&E)..." +#define STR_EXISTING "已有映像(&E)..." #define STR_REMOVE "移除(&R)" #define STR_BUS "总线:" #define STR_CHANNEL "通道:" #define STR_ID "ID:" -#define STR_SPEED "Speed:" +#define STR_SPEED "速度:" #define STR_SPECIFY "指定(&S)..." #define STR_SECTORS "扇区(S):" @@ -360,7 +360,7 @@ END #define STR_CYLS "柱面(C):" #define STR_SIZE_MB "大小 (MB):" #define STR_TYPE "类型:" -#define STR_IMG_FORMAT "镜像格式:" +#define STR_IMG_FORMAT "映像格式:" #define STR_BLOCK_SIZE "块大小:" #define STR_FLOPPY_DRIVES "软盘驱动器:" @@ -401,14 +401,14 @@ BEGIN IDS_2052 "按下 Ctrl+Alt+PgDn 返回到窗口模式。" IDS_2053 "速度" IDS_2054 "ZIP %03i %i (%s): %ls" - IDS_2055 "ZIP 镜像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到任何可用的 ROM 镜像。\n\n请下载ROM 包并将其解压到 ""roms"" 文件夹。" + IDS_2055 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" + IDS_2056 "86Box 找不到任何可用的 ROM 映像。\n\n请下载ROM 包并将其解压到 ""roms"" 文件夹中。" IDS_2057 "(空)" - IDS_2058 "ZIP 镜像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有文件 (*.*)\0*.*\0" + IDS_2058 "ZIP 映像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有文件 (*.*)\0*.*\0" IDS_2059 "加速" IDS_2060 "开" IDS_2061 "关" - IDS_2062 "所有镜像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区镜像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面镜像 (*.86F)\0*.86F\0" + IDS_2062 "所有映像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区映像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面映像 (*.86F)\0*.86F\0" IDS_2063 "由于 roms/machines 文件夹中缺少合适的 ROM,机型 ""%hs"" 不可用。将切换到其他可用机型。" END @@ -426,7 +426,7 @@ BEGIN IDS_2073 "软盘/光盘驱动器" IDS_2074 "其他可移动设备" IDS_2075 "其他外围设备" - IDS_2076 "表面镜像 (*.86F)\0*.86F\0" + IDS_2076 "表面映像 (*.86F)\0*.86F\0" IDS_2077 "单击窗口捕捉鼠标" IDS_2078 "按下 F8+F12 释放鼠标" IDS_2079 "按下 F8+F12 或鼠标中键释放鼠标" @@ -434,14 +434,13 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "无法初始化 FluidSynth" IDS_2081 "总线" IDS_2082 "文件" IDS_2083 "C" IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Speed" + IDS_2087 "速度" IDS_2088 "检查 BPB" IDS_2089 "KB" IDS_2090 "无法初始化视频渲染器。" @@ -464,14 +463,12 @@ BEGIN IDS_2107 "%u" IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "软盘 %i (%s): %ls" - IDS_2110 "所有镜像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区镜像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区镜像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 镜像 (*.FDI)\0*.FDI\0表面镜像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" - IDS_2111 "无法初始化 FreeType" - IDS_2112 "无法初始化 SDL,需要 SDL2.dll" + IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" IDS_2113 "确定要硬重置模拟器吗?" IDS_2114 "确定要退出 86Box 吗?" IDS_2115 "无法初始化 Ghostscript" IDS_2116 "磁光盘 %i (%ls): %ls" - IDS_2117 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2117 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" IDS_2118 "欢迎使用 86Box!" IDS_2119 "内部控制器" IDS_2120 "退出" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "关于 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" + IDS_2127 "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" IDS_2128 "确定" IDS_2129 "硬件不可用" #ifdef _WIN32 @@ -493,30 +490,18 @@ BEGIN IDS_2130 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" IDS_2131 "无效配置" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "ESC/P 打印机模拟需要" LIB_NAME_FREETYPE -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "FluidSynth MIDI 输出需要" LIB_NAME_FLUIDSYNTH IDS_2135 "正在进入全屏模式" - IDS_2136 "不要再显示此消息" + IDS_2136 "不再显示此消息" IDS_2137 "不退出" IDS_2138 "重置" IDS_2139 "不重置" - IDS_2140 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2141 "光盘镜像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" + IDS_2140 "磁光盘映像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2141 "光盘映像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" IDS_2142 "%hs 设备配置" IDS_2143 "显示器处在睡眠状态" IDS_2144 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" @@ -525,9 +510,9 @@ BEGIN IDS_2147 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" IDS_2148 "继续" IDS_2149 "磁带: %s" - IDS_2150 "磁带镜像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" + IDS_2150 "磁带映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" IDS_2151 "卡带 %i: %ls" - IDS_2152 "卡带镜像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" + IDS_2152 "卡带映像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" IDS_2153 "初始化渲染器时出错" IDS_2154 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" IDS_2155 "恢复执行" @@ -537,13 +522,13 @@ BEGIN IDS_2159 "硬重置" IDS_2160 "ACPI 关机" IDS_2161 "设置" - IDS_2162 "Type" - IDS_2163 "No Dynarec" - IDS_2164 "Old Dynarec" - IDS_2165 "New Dynarec" - IDS_2166 "Video card #2 ""%hs"" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." - IDS_2167 "Failed to initialize network driver" - IDS_2168 "The network configuration will be switched to the null driver" + IDS_2162 "类型" + IDS_2163 "无动态重编译" + IDS_2164 "旧式动态重编译" + IDS_2165 "新式动态重编译" + IDS_2166 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 #2 ""%hs"" 不可用。将禁用第二张显卡。" + IDS_2167 "初始化网络驱动程序失败" + IDS_2168 "网络配置将切换为空驱动程序" END STRINGTABLE DISCARDABLE @@ -556,27 +541,27 @@ BEGIN IDS_4101 "自定义 (大容量)..." IDS_4102 "添加新硬盘" IDS_4103 "添加已存在的硬盘" - IDS_4104 "HDI 磁盘镜像不能超过 4 GB。" - IDS_4105 "磁盘镜像不能超过 127 GB。" - IDS_4106 "硬盘镜像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有文件 (*.*)\0*.*\0" + IDS_4104 "HDI 磁盘映像不能超过 4 GB。" + IDS_4105 "磁盘映像不能超过 127 GB。" + IDS_4106 "硬盘映像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有文件 (*.*)\0*.*\0" IDS_4107 "无法读取文件" IDS_4108 "无法写入文件" - IDS_4109 "不支持非 512 字节扇区大小的 HDI 或 HDX 镜像。" + IDS_4109 "不支持非 512 字节扇区大小的 HDI 或 HDX 映像。" IDS_4110 "尚未支持 USB" - IDS_4111 "磁盘镜像文件已存在" + IDS_4111 "磁盘映像文件已存在" IDS_4112 "请指定有效的文件名。" - IDS_4113 "已创建磁盘镜像" + IDS_4113 "已创建磁盘映像" IDS_4114 "请确定此文件已存在并可读取。" IDS_4115 "请确定此文件保存在可写目录中。" - IDS_4116 "磁盘镜像太大" - IDS_4117 "请记得为新创建的镜像分区并格式化。" + IDS_4116 "磁盘映像太大" + IDS_4117 "请记得为新创建的映像分区并格式化。" IDS_4118 "选定的文件将被覆盖。确定继续使用此文件吗?" - IDS_4119 "不支持的磁盘镜像" + IDS_4119 "不支持的磁盘映像" IDS_4120 "覆盖" IDS_4121 "不覆盖" - IDS_4122 "原始镜像 (.img)" - IDS_4123 "HDI 镜像 (.hdi)" - IDS_4124 "HDX 镜像 (.hdx)" + IDS_4122 "原始映像 (.img)" + IDS_4123 "HDI 映像 (.hdi)" + IDS_4124 "HDX 映像 (.hdx)" IDS_4125 "固定大小 VHD (.vhd)" IDS_4126 "动态大小 VHD (.vhd)" IDS_4127 "差分 VHD (.vhd)" @@ -584,7 +569,7 @@ BEGIN IDS_4129 "小块 (512 KB)" IDS_4130 "VHD 文件 (*.VHD)\0*.VHD\0所有文件 (*.*)\0*.*\0" IDS_4131 "选择父 VHD 文件" - IDS_4132 "父映像可能在创建差异镜像后被修改。\n\n如果镜像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" + IDS_4132 "父映像可能在创建差异映像后被修改。\n\n如果映像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" IDS_4133 "父盘与子盘的时间戳不匹配" IDS_4134 "无法修复 VHD 时间戳。" IDS_4135 "%01i:%02i" diff --git a/src/win/languages/zh-TW.rc b/src/win/languages/zh-TW.rc index 76d40d8280..58324442d1 100644 --- a/src/win/languages/zh-TW.rc +++ b/src/win/languages/zh-TW.rc @@ -109,7 +109,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "擷圖(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "首選項(&P)...", IDM_PREFERENCES + MENUITEM "偏好設定(&P)...", IDM_PREFERENCES #ifdef DISCORD MENUITEM "啟用 Discord 整合(&D)", IDM_DISCORD #endif @@ -240,7 +240,7 @@ END // Dialog // -#define STR_PREFERENCES "首選項" +#define STR_PREFERENCES "偏好設定" #define STR_SND_GAIN "音量增益" #define STR_NEW_FLOPPY "新增映像" #define STR_CONFIG "設定" @@ -274,7 +274,7 @@ END #define STR_MB "MB" #define STR_MEMORY "記憶體:" #define STR_TIME_SYNC "時間同步" -#define STR_DISABLED "禁用" +#define STR_DISABLED "停用" #define STR_ENABLED_LOCAL "啟用 (本地時間)" #define STR_ENABLED_UTC "啟用 (UTC)" #define STR_DYNAREC "動態重編譯器" @@ -283,7 +283,7 @@ END #define STR_VIDEO "顯示卡:" #define STR_VIDEO_2 "顯示卡 2:" #define STR_VOODOO "Voodoo Graphics" -#define STR_IBM8514 "IBM 8514/a Graphics" +#define STR_IBM8514 "IBM 8514/A Graphics" #define STR_XGA "XGA Graphics" #define STR_MOUSE "滑鼠:" @@ -293,10 +293,10 @@ END #define STR_JOY3 "搖桿 3..." #define STR_JOY4 "搖桿 4..." -#define STR_SOUND1 "音訊卡 1:" -#define STR_SOUND2 "音訊卡 2:" -#define STR_SOUND3 "音訊卡 3:" -#define STR_SOUND4 "音訊卡 4:" +#define STR_SOUND1 "音效卡 1:" +#define STR_SOUND2 "音效卡 2:" +#define STR_SOUND3 "音效卡 3:" +#define STR_SOUND4 "音效卡 4:" #define STR_MIDI_OUT "MIDI 輸出裝置:" #define STR_MIDI_IN "MIDI 輸入裝置:" #define STR_MPU401 "獨立 MPU-401" @@ -357,7 +357,7 @@ END #define STR_SPECIFY "指定(&S)..." #define STR_SECTORS "磁區(S):" #define STR_HEADS "磁頭(H):" -#define STR_CYLS "柱面(C):" +#define STR_CYLS "磁柱(C):" #define STR_SIZE_MB "大小 (MB):" #define STR_TYPE "類型:" #define STR_IMG_FORMAT "映像格式:" @@ -434,7 +434,6 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "無法初始化 FluidSynth" IDS_2081 "匯流排" IDS_2082 "檔案" IDS_2083 "C" @@ -465,8 +464,6 @@ BEGIN IDS_2108 "%u MB (CHS: %i, %i, %i)" IDS_2109 "軟碟 %i (%s): %ls" IDS_2110 "所有映像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0進階磁區映像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本磁區映像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 映像 (*.FDI)\0*.FDI\0表面映像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有檔案 (*.*)\0*.*\0" - IDS_2111 "無法初始化 FreeType" - IDS_2112 "無法初始化 SDL,需要 SDL2.dll" IDS_2113 "確定要硬重設模擬器嗎?" IDS_2114 "確定要退出 86Box 嗎?" IDS_2115 "無法初始化 Ghostscript" @@ -482,7 +479,7 @@ BEGIN IDS_2125 "關於 86Box" IDS_2126 "86Box v" EMU_VERSION - IDS_2127 "一個舊式電腦模擬器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" + IDS_2127 "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" IDS_2128 "確定" IDS_2129 "硬體不可用" #ifdef _WIN32 @@ -493,23 +490,11 @@ BEGIN IDS_2130 "請確認 " LIB_NAME_PCAP " 已安裝且使用相容 " LIB_NAME_PCAP " 的網路連線。" IDS_2131 "無效設定" #ifdef _WIN32 -#define LIB_NAME_FREETYPE "freetype.dll" -#else -#define LIB_NAME_FREETYPE "libfreetype" -#endif - IDS_2132 "ESC/P 印表機模擬需要" LIB_NAME_FREETYPE -#ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif IDS_2133 LIB_NAME_GS " 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 PostScript (.ps) 檔案。" -#ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#endif - IDS_2134 "FluidSynth MIDI 輸出需要" LIB_NAME_FLUIDSYNTH IDS_2135 "正在進入全螢幕模式" IDS_2136 "不要再顯示此消息" IDS_2137 "不退出" @@ -522,7 +507,7 @@ BEGIN IDS_2144 "OpenGL 著色器 (*.GLSL)\0*.GLSL\0所有檔案 (*.*)\0*.*\0" IDS_2145 "OpenGL 選項" IDS_2146 "正在載入一個不受支援的設定" - IDS_2147 "此模擬電腦禁用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" + IDS_2147 "此模擬電腦停用了基於選定電腦的 CPU 類型過濾。\n\n能夠選中與所選機器本不相容的 CPU,但是可能會遇到與機器 BIOS 或其他軟體不相容的問題。\n\n啟用此設定不受官方支援,並且提交的任何錯誤報告可能會視為無效而關閉。" IDS_2148 "繼續" IDS_2149 "磁帶: %s" IDS_2150 "磁帶映像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有檔案 (*.*)\0*.*\0" @@ -605,11 +590,11 @@ BEGIN IDS_5120 "光碟 %i (%s): %s" - IDS_5376 "禁用" + IDS_5376 "停用" IDS_5381 "ATAPI" IDS_5382 "SCSI" - IDS_5632 "禁用" + IDS_5632 "停用" IDS_5637 "ATAPI (%01i:%01i)" IDS_5638 "SCSI (%01i:%02i)" diff --git a/src/win/win.c b/src/win/win.c index 4d3b7c1a01..d77ab32fd0 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -51,6 +51,7 @@ #include <86box/path.h> #define GLOBAL #include <86box/plat.h> +#include <86box/plat_dynld.h> #include <86box/thread.h> #include <86box/ui.h> #ifdef USE_VNC @@ -65,30 +66,31 @@ # include #endif -typedef struct { +typedef struct rc_str_t { WCHAR str[1024]; } rc_str_t; /* Platform Public data, specific. */ HINSTANCE hinstance; /* application instance */ HANDLE ghMutex; -uint32_t lang_id, lang_sys; /* current and system language ID */ +uint32_t lang_id; /* current and system language ID */ +uint32_t lang_sys; /* current and system language ID */ DWORD dwSubLangID; int acp_utf8; /* Windows supports UTF-8 codepage */ volatile int cpu_thread_run = 1; /* Local data. */ -static HANDLE thMain; -static rc_str_t *lpRCstr2048 = NULL, - *lpRCstr4096 = NULL, - *lpRCstr4352 = NULL, - *lpRCstr4608 = NULL, - *lpRCstr5120 = NULL, - *lpRCstr5376 = NULL, - *lpRCstr5632 = NULL, - *lpRCstr5888 = NULL, - *lpRCstr6144 = NULL, - *lpRCstr7168 = NULL; +static HANDLE thMain; +static rc_str_t *lpRCstr2048 = NULL; +static rc_str_t *lpRCstr4096 = NULL; +static rc_str_t *lpRCstr4352 = NULL; +static rc_str_t *lpRCstr4608 = NULL; +static rc_str_t *lpRCstr5120 = NULL; +static rc_str_t *lpRCstr5376 = NULL; +static rc_str_t *lpRCstr5632 = NULL; +static rc_str_t *lpRCstr5888 = NULL; +static rc_str_t *lpRCstr6144 = NULL; +static rc_str_t *lpRCstr7168 = NULL; static int vid_api_inited = 0; static char *argbuf; static int first_use = 1; @@ -302,7 +304,7 @@ plat_get_string(int i) else str = lpRCstr7168[i - 7168].str; - return ((wchar_t *) str); + return str; } #ifdef MTR_ENABLED @@ -382,7 +384,9 @@ ProcessCommandLine(char ***argv) { char **args; int argc_max; - int i, q, argc; + int i; + int q; + int argc; if (acp_utf8) { i = strlen(GetCommandLineA()) + 1; @@ -399,7 +403,7 @@ ProcessCommandLine(char ***argv) args = (char **) malloc(sizeof(char *) * argc_max); if (args == NULL) { free(argbuf); - return (0); + return 0; } /* parse commandline into argc/argv format */ @@ -423,11 +427,11 @@ ProcessCommandLine(char ***argv) args = realloc(args, sizeof(char *) * argc_max); if (args == NULL) { free(argbuf); - return (0); + return 0; } } - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != ' '))) + while ((argbuf[i]) && (q ? (argbuf[i] != q) : (argbuf[i] != ' '))) i++; if (argbuf[i]) { @@ -440,7 +444,7 @@ ProcessCommandLine(char ***argv) args[argc] = NULL; *argv = args; - return (argc); + return argc; } /* For the Windows platform, this is the start of the application. */ @@ -448,7 +452,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) { char **argv = NULL; - int argc, i; + int argc; + int i; /* Initialize the COM library for the main thread. */ CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -486,7 +491,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) free(argbuf); free(argv); - return (1); + return 1; } extern int gfxcard[2]; @@ -506,14 +511,16 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) free(argbuf); free(argv); - return (i); + return i; } void main_thread(void *param) { - uint32_t old_time, new_time; - int drawits, frames; + uint32_t old_time; + uint32_t new_time; + int drawits; + int frames; framecountx = 0; title_update = 1; @@ -626,7 +633,7 @@ plat_tempfile(char *bufp, char *prefix, char *suffix) else strcpy(bufp, ""); - GetSystemTime(&SystemTime); + GetLocalTime(&SystemTime); sprintf(&bufp[strlen(bufp)], "%d%02d%02d-%02d%02d%02d-%03d%s", SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, @@ -648,14 +655,15 @@ plat_getcwd(char *bufp, int max) free(temp); } - return (0); + return 0; } int plat_chdir(char *path) { wchar_t *temp; - int len, ret; + int len; + int ret; if (acp_utf8) return (_chdir(path)); @@ -674,7 +682,8 @@ plat_chdir(char *path) FILE * plat_fopen(const char *path, const char *mode) { - wchar_t *pathw, *modew; + wchar_t *pathw; + wchar_t *modew; int len; FILE *fp; @@ -725,7 +734,7 @@ plat_remove(char *path) } void -path_normalize(char *path) +path_normalize(UNUSED(char *path)) { /* No-op */ } @@ -734,9 +743,20 @@ path_normalize(char *path) void path_slash(char *path) { - if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) { + if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) strcat(path, "\\"); - } +} + +/* Return a trailing (back)slash if necessary. */ +const char * +path_get_slash(char *path) +{ + char *ret = ""; + + if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) + ret = "\\"; + + return ret; } /* Check if the given path is absolute or not. */ @@ -744,9 +764,9 @@ int path_abs(char *path) { if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/')) - return (1); + return 1; - return (0); + return 0; } /* Return the last element of a pathname. */ @@ -768,8 +788,8 @@ plat_get_basename(const char *path) void path_get_dirname(char *dest, const char *path) { - int c = (int) strlen(path); - char *ptr; + int c = (int) strlen(path); + const char *ptr; ptr = (char *) path; @@ -798,7 +818,7 @@ path_get_filename(char *s) c--; } - return (s); + return s; } char * @@ -807,7 +827,7 @@ path_get_extension(char *s) int c = strlen(s) - 1; if (c <= 0) - return (s); + return s; while (c && s[c] != '.') c--; @@ -854,23 +874,24 @@ plat_dir_check(char *path) free(temp); } - return (((dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY))) ? 1 : 0); + return ((dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) ? 1 : 0); } int plat_dir_create(char *path) { - int ret, len; + int ret; + int len; wchar_t *temp; if (acp_utf8) - return (int) SHCreateDirectoryExA(NULL, path, NULL); + return SHCreateDirectoryExA(NULL, path, NULL); else { len = mbstoc16s(NULL, path, 0) + 1; temp = malloc(len * sizeof(wchar_t)); mbstoc16s(temp, path, len); - ret = (int) SHCreateDirectoryExW(NULL, temp, NULL); + ret = SHCreateDirectoryExW(NULL, temp, NULL); free(temp); @@ -929,7 +950,7 @@ plat_init_rom_paths(void) } void -plat_munmap(void *ptr, size_t size) +plat_munmap(void *ptr, UNUSED(size_t size)) { VirtualFree(ptr, 0, MEM_RELEASE); } @@ -947,7 +968,8 @@ plat_timer_read(void) static LARGE_INTEGER plat_get_ticks_common(void) { - LARGE_INTEGER EndingTime, ElapsedMicroseconds; + LARGE_INTEGER EndingTime; + LARGE_INTEGER ElapsedMicroseconds; if (first_use) { QueryPerformanceFrequency(&Frequency); @@ -991,23 +1013,21 @@ plat_delay_ms(uint32_t count) int plat_vidapi(char *name) { - int i; - /* Default/System is SDL Hardware. */ if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) - return (1); + return 1; /* If DirectDraw or plain SDL was specified, return SDL Software. */ if (!strcasecmp(name, "ddraw") || !strcasecmp(name, "sdl")) - return (1); + return 1; - for (i = 0; i < RENDERERS_NUM; i++) { + for (uint8_t i = 0; i < RENDERERS_NUM; i++) { if (vid_apis[i].name && !strcasecmp(vid_apis[i].name, name)) - return (i); + return i; } /* Default value. */ - return (1); + return 1; } /* Return the VIDAPI name for the given number. */ @@ -1038,7 +1058,7 @@ plat_vidapi_name(int api) break; } - return (name); + return name; } int @@ -1062,13 +1082,13 @@ plat_setvid(int api) i = vid_apis[vid_api].init((void *) hwndRender); endblit(); if (!i) - return (0); + return 0; device_force_redraw(); vid_api_inited = 1; - return (1); + return 1; } /* Tell the renderers about a new screen resolution. */ @@ -1110,7 +1130,8 @@ void plat_setfullscreen(int on) { RECT rect; - int temp_x, temp_y; + int temp_x; + int temp_y; int dpi = win_get_dpi(hwndMain); /* Are we changing from the same state to the same state? */ @@ -1229,7 +1250,7 @@ plat_language_code(char *langcode) wchar_t *temp = malloc(len * sizeof(wchar_t)); mbstoc16s(temp, langcode, len); - LCID lcid = LocaleNameToLCID((LPWSTR) temp, 0); + LCID lcid = LocaleNameToLCID(temp, 0); free(temp); return lcid; @@ -1250,6 +1271,41 @@ plat_language_code_r(uint32_t lcid, char *outbuf, int len) c16stombs(outbuf, buffer, len); } +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + char cpu_string[] = "Unknown"; + strncpy(outbuf, cpu_string, len); +} + +void +plat_set_thread_name(void *thread, const char *name) +{ + /* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */ + static void *kernel32_handle = NULL; + static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; + static dllimp_t kernel32_imports[] = { + // clang-format off + { "SetThreadDescription", &pSetThreadDescription }, + { NULL, NULL } + // clang-format on + }; + + if (!kernel32_handle) { + kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); + if (!kernel32_handle) { + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ + pSetThreadDescription = NULL; + } + } + + if (pSetThreadDescription) { + size_t len = strlen(name) + 1; + wchar_t wname[len + 1]; + mbstowcs(wname, name, len); + pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); + } +} + void take_screenshot(void) { @@ -1280,3 +1336,11 @@ endblit(void) { ReleaseMutex(ghMutex); } + +double +plat_get_dpi(void) +{ + UINT dpi = win_get_dpi(hwndRender); + + return ((double) dpi) / 96.0; +} diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index 27e4e0a492..58bd85c652 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -8,11 +8,9 @@ * * Handle the platform-side of CDROM/ZIP/MO drives. * - * - * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, + * Jasmine Iwanek, * * Copyright 2016-2018 Miran Grca. * Copyright 2017-2018 Fred N. van Kempen. @@ -72,7 +70,7 @@ cassette_eject(void) } void -cartridge_mount(uint8_t id, char *fn, uint8_t wp) +cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) { cart_close(id); cart_load(id, fn); @@ -115,9 +113,9 @@ floppy_eject(uint8_t id) } void -plat_cdrom_ui_update(uint8_t id, uint8_t reload) +plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) { - cdrom_t *drv = &cdrom[id]; + const cdrom_t *drv = &cdrom[id]; if (drv->host_drive == 0) { ui_sb_update_icon_state(SB_CDROM | id, 1); @@ -138,6 +136,8 @@ cdrom_mount(uint8_t id, char *fn) cdrom[id].ops->exit(&(cdrom[id])); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); + if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '/')) + fn[strlen(fn) - 1] = '\\'; cdrom_image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ if (cdrom[id].insert) diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 0f233cb3a0..92ab6b6149 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -44,7 +44,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { HWND h; @@ -64,8 +64,8 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) const device_config_bios_t *bios; char s[512]; char file_filter[512]; - char *str; - char *val_str; + const char *str; + const char *val_str; wchar_t ws[512]; wchar_t *wstr; LPTSTR lptsTemp; @@ -121,7 +121,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) mbstowcs(lptsTemp, bios->name, strlen(bios->name) + 1); p = 0; for (d = 0; d < bios->files_no; d++) - p += !!rom_present((char *) bios->files[d]); + p += !!rom_present(bios->files[d]); if (p == bios->files_no) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) lptsTemp); if (!strcmp(val_str, bios->internal_name)) diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index b58ef88d02..15b00bf3f4 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -160,7 +160,9 @@ file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save) { OPENFILENAME ofn; BOOL r; - /* DWORD err; */ +#if 0 + DWORD err; +#endif int old_dopause; /* Initialize OPENFILENAME */ diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 5658b14d5d..9b264a7006 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -36,6 +36,7 @@ plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present = 0; +int has_slider = 0; static LPDIRECTINPUT8 lpdi; static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL }; @@ -83,7 +84,7 @@ DIEnumDeviceObjectsCallback( plat_joystick_t *state = (plat_joystick_t *) pvRef; if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis) { - if (state->nr_axes < 8) { + if (state->nr_axes < MAX_JOY_AXES) { memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); if (lpddoi->guidType == GUID_XAxis) @@ -98,27 +99,24 @@ DIEnumDeviceObjectsCallback( state->axis[state->nr_axes].id = 4; else if (lpddoi->guidType == GUID_RzAxis) state->axis[state->nr_axes].id = 5; + else if (lpddoi->guidType == GUID_Slider) { + state->axis[state->nr_axes].id = 6 + has_slider; + has_slider++; + } state->nr_axes++; } } else if (lpddoi->guidType == GUID_Button) { - if (state->nr_buttons < 32) { + if (state->nr_buttons < MAX_JOY_BUTTONS) { memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_buttons++; } } else if (lpddoi->guidType == GUID_POV) { - if (state->nr_povs < 4) { + if (state->nr_povs < MAX_JOY_POVS) { memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; } - } else if (lpddoi->guidType == GUID_Slider) { - if (state->nr_sliders < 2) { - memcpy(state->slider[state->nr_sliders].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); - state->slider[state->nr_sliders].id = state->nr_sliders | SLIDER; - joystick_log("Slider %i : %s %x %x\n", state->nr_sliders, state->slider[state->nr_sliders].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_sliders++; - } } return DIENUM_CONTINUE; @@ -170,6 +168,7 @@ joystick_init() joystick_log(" Buttons = %i\n", devcaps.dwButtons); joystick_log(" POVs = %i\n", devcaps.dwPOVs); + has_slider = 0; lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) @@ -234,8 +233,6 @@ joystick_get_axis(int joystick_nr, int mapping) return 0; else return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; - } else if (mapping & SLIDER) { - return plat_joystick_state[joystick_nr].s[mapping & 3]; } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } @@ -269,13 +266,13 @@ joystick_process(void) plat_joystick_state[c].a[3] = joystate.lRx; plat_joystick_state[c].a[4] = joystate.lRy; plat_joystick_state[c].a[5] = joystate.lRz; - plat_joystick_state[c].s[0] = joystate.rglSlider[0]; - plat_joystick_state[c].s[1] = joystate.rglSlider[1]; + plat_joystick_state[c].a[6] = joystate.rglSlider[0]; + plat_joystick_state[c].a[7] = joystate.rglSlider[1]; - for (b = 0; b < 16; b++) + for (b = 0; b < MAX_JOY_BUTTONS; b++) plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - for (b = 0; b < 4; b++) + for (b = 0; b < MAX_JOY_POVS; b++) plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; // joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } @@ -318,7 +315,7 @@ joystick_process(void) } void -win_joystick_handle(PRAWINPUT raw) +win_joystick_handle(UNUSED(PRAWINPUT raw)) { // Nothing to be done here, atleast currently } diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index 6f2a1e4c04..bb05c3f5c6 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -10,11 +10,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * GH Cao, + * Jasmine Iwanek, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. * Copyright 2020 GH Cao. * Copyright 2021-2023 Jasmine Iwanek. @@ -36,6 +35,29 @@ #include <86box/gameport.h> #include <86box/win.h> +/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */ +#ifndef HID_USAGE_SIMULATION_AILERON +# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0) +#endif +#ifndef HID_USAGE_SIMULATION_ELEVATOR +# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8) +#endif +#ifndef HID_USAGE_SIMULATION_ACCELLERATOR +# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4) +#endif +#ifndef HID_USAGE_SIMULATION_BRAKE +# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5) +#endif +#ifndef HID_USAGE_SIMULATION_CLUTCH +# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6) +#endif +#ifndef HID_USAGE_SIMULATION_SHIFTER +# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7) +#endif +#ifndef HID_USAGE_SIMULATION_STEERING +# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8) +#endif + #ifdef ENABLE_JOYSTICK_LOG int joystick_do_log = ENABLE_JOYSTICK_LOG; @@ -66,14 +88,14 @@ typedef struct { USHORT bitsize; LONG max; LONG min; - } axis[8]; + } axis[MAX_JOY_AXES]; struct raw_pov_t { USAGE usage; USHORT link; LONG max; LONG min; - } pov[4]; + } pov[MAX_JOY_POVS]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -86,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; void joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - if (joy->nr_buttons >= 32) + if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; if (usage < 1 || usage > 128) return; @@ -99,9 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - LONG center; - - if (joy->nr_axes >= 8) + if (joy->nr_axes >= MAX_JOY_AXES) return; switch (prop->Range.UsageMin) { @@ -123,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS case HID_USAGE_GENERIC_RZ: sprintf(joy->axis[joy->nr_axes].name, "RZ"); break; + case HID_USAGE_GENERIC_SLIDER: + sprintf(joy->axis[joy->nr_axes].name, "Slider"); + break; + case HID_USAGE_GENERIC_DIAL: + sprintf(joy->axis[joy->nr_axes].name, "Dial"); + break; + case HID_USAGE_GENERIC_WHEEL: + sprintf(joy->axis[joy->nr_axes].name, "Wheel"); + break; + case HID_USAGE_SIMULATION_AILERON: + sprintf(joy->axis[joy->nr_axes].name, "Aileron"); + break; + case HID_USAGE_SIMULATION_ELEVATOR: + sprintf(joy->axis[joy->nr_axes].name, "Elevator"); + break; + case HID_USAGE_SIMULATION_RUDDER: + sprintf(joy->axis[joy->nr_axes].name, "Rudder"); + break; + case HID_USAGE_SIMULATION_THROTTLE: + sprintf(joy->axis[joy->nr_axes].name, "Throttle"); + break; + case HID_USAGE_SIMULATION_ACCELLERATOR: + sprintf(joy->axis[joy->nr_axes].name, "Accelerator"); + break; + case HID_USAGE_SIMULATION_BRAKE: + sprintf(joy->axis[joy->nr_axes].name, "Brake"); + break; + case HID_USAGE_SIMULATION_CLUTCH: + sprintf(joy->axis[joy->nr_axes].name, "Clutch"); + break; + case HID_USAGE_SIMULATION_SHIFTER: + sprintf(joy->axis[joy->nr_axes].name, "Shifter"); + break; + case HID_USAGE_SIMULATION_STEERING: + sprintf(joy->axis[joy->nr_axes].name, "Steering"); + break; default: return; } @@ -140,20 +196,17 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS * Some joysticks will send -1 in LogicalMax, like Xbox Controllers * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1ULL << prop->BitSize) - 1); } rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - center = (rawjoy->axis[joy->nr_axes].max - rawjoy->axis[joy->nr_axes].min + 1) / 2; - - if (center != 0x00) - joy->nr_axes++; + joy->nr_axes++; } void joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) + if (joy->nr_povs >= MAX_JOY_POVS) return; sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); @@ -373,10 +426,10 @@ win_joystick_handle(PRAWINPUT raw) /* Read axes */ for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; - ULONG uvalue = 0; - LONG value = 0; - LONG center = (axis->max - axis->min + 1) / 2; + const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -401,14 +454,16 @@ win_joystick_handle(PRAWINPUT raw) } plat_joystick_state[j].a[a] = value; - // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#if 0 + joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); +#endif } /* read povs */ for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; - ULONG uvalue = 0; - LONG value = -1; + const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); @@ -421,9 +476,13 @@ win_joystick_handle(PRAWINPUT raw) plat_joystick_state[j].p[p] = value; - // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#if 0 + joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); +#endif } - // joystick_log("\n"); +#if 0 + joystick_log("\n"); +#endif } static int @@ -451,7 +510,7 @@ joystick_process(void) { int d; - if (joystick_type == 7) + if (joystick_type == JS_TYPE_NONE) return; for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { diff --git a/src/win/win_joystick_xinput.c b/src/win/win_joystick_xinput.c index a1c380668f..f313522a9a 100644 --- a/src/win/win_joystick_xinput.c +++ b/src/win/win_joystick_xinput.c @@ -10,11 +10,10 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * GH Cao, + * Jasmine Iwanek, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. * Copyright 2019 GH Cao. * Copyright 2021-2023 Jasmine Iwanek. @@ -140,6 +139,7 @@ joystick_init() void joystick_close() { + // } void @@ -262,7 +262,7 @@ joystick_process(void) } void -win_joystick_handle(PRAWINPUT raw) +win_joystick_handle(UNUSED(PRAWINPUT raw)) { // Nothing to be done here, atleast currently } diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 0e4f581dd1..416e7858df 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -54,9 +54,6 @@ rebuild_axis_button_selections(HWND hdlg) sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) s); } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) (LPCSTR) plat_joystick_state[joystick - 1].slider[d].name); - } SendMessage(h, CB_SETCURSEL, sel, 0); EnableWindow(h, TRUE); } else @@ -111,21 +108,15 @@ get_axis(HWND hdlg, int id) HWND h = GetDlgItem(hdlg, id); int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) return axis_sel; axis_sel -= nr_axes; - if (axis_sel < nr_povs * 2) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - axis_sel -= nr_povs; - - return SLIDER | (axis_sel >> 1); + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int @@ -150,7 +141,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { HWND h; int c; @@ -188,8 +179,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); else if (mapping & POV_Y) SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else if (mapping & SLIDER) - SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0); else SendMessage(h, CB_SETCURSEL, mapping, 0); id += 2; @@ -247,7 +236,7 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); id += 2; } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { h = GetDlgItem(hdlg, id); joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); id += 2; diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index 72f8561f0d..54be91e6ca 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -55,15 +55,15 @@ convert_scan_code(UINT16 scan_code) void keyboard_getkeymap(void) { - WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - WCHAR *valueName = L"Scancode Map"; + const WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const WCHAR *valueName = L"Scancode Map"; unsigned char buf[32768]; DWORD bufSize; HKEY hKey; int j; - UINT32 *bufEx2; + const UINT32 *bufEx2; int scMapCount; - UINT16 *bufEx; + const UINT16 *bufEx; int scancode_unmapped; int scancode_mapped; diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index 93d7396aec..549a495b99 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -26,7 +26,7 @@ #include <86box/win.h> #define MACHINE_HAS_IDE (machine_has_flags(machine, MACHINE_IDE_QUAD)) -#define MACHINE_HAS_SCSI (machine_has_flags(machine, MACHINE_SCSI_DUAL)) +#define MACHINE_HAS_SCSI (machine_has_flags(machine, MACHINE_SCSI)) #define CASSETTE_FIRST 0 #define CARTRIDGE_FIRST CASSETTE_FIRST + 1 @@ -544,6 +544,10 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) int ret = 0; int wp = 0; +#ifdef __clang__ + BROWSEINFO bi; +#endif + id = LOWORD(wParam) & 0x00ff; switch (LOWORD(wParam) & 0xff00) { @@ -651,10 +655,15 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_CDROM_DIR: +#ifndef __clang__ BROWSEINFO bi = { .hwndOwner = hwnd, .ulFlags = BIF_EDITBOX }; +#else + bi.hwndOwner = hwnd; + bi.ulFlags = BIF_EDITBOX; +#endif OleInitialize(NULL); int old_dopause = dopause; plat_pause(1); @@ -714,10 +723,10 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; default: - return (0); + return 0; } - return (1); + return 1; } HMENU diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c index 3e31f12dec..f2b185eaa2 100644 --- a/src/win/win_mouse.c +++ b/src/win/win_mouse.c @@ -10,37 +10,26 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * GH Cao, + * Jasmine Iwanek, * - * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. * Copyright 2019 GH Cao. * Copyright 2021-2023 Jasmine Iwanek. */ #include #include +#include #include #include #include <86box/86box.h> #include <86box/mouse.h> +#include <86box/pic.h> #include <86box/plat.h> #include <86box/win.h> int mouse_capture; -double mouse_sensitivity = 1.0; /* Unused. */ -double mouse_x_error = 0.0; /* Unused. */ -double mouse_y_error = 0.0; /* Unused. */ - -typedef struct { - int buttons; - int dx; - int dy; - int dwheel; -} MOUSESTATE; - -MOUSESTATE mousestate; void win_mouse_init(void) @@ -57,8 +46,6 @@ win_mouse_init(void) ridev.usUsage = 0x02; if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) fatal("plat_mouse_init: RegisterRawInputDevices failed\n"); - - memset(&mousestate, 0, sizeof(MOUSESTATE)); } void @@ -66,52 +53,64 @@ win_mouse_handle(PRAWINPUT raw) { RAWMOUSE state = raw->data.mouse; static int x; + static int delta_x; static int y; + static int delta_y; + static int b; + static int delta_z; + + b = mouse_get_buttons_ex(); /* read mouse buttons and wheel */ if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - mousestate.buttons |= 1; + b |= 1; else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - mousestate.buttons &= ~1; + b &= ~1; if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - mousestate.buttons |= 4; + b |= 4; else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - mousestate.buttons &= ~4; + b &= ~4; if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - mousestate.buttons |= 2; + b |= 2; else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - mousestate.buttons &= ~2; + b &= ~2; if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - mousestate.buttons |= 8; + b |= 8; else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - mousestate.buttons &= ~8; + b &= ~8; if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - mousestate.buttons |= 16; + b |= 16; else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - mousestate.buttons &= ~16; + b &= ~16; + + mouse_set_buttons_ex(b); if (state.usButtonFlags & RI_MOUSE_WHEEL) { - mousestate.dwheel += (SHORT) state.usButtonData / 120; - } + delta_z = (SHORT) state.usButtonData / 120; + mouse_set_z(delta_z); + } else + delta_z = 0; if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { /* absolute mouse, i.e. RDP or VNC * seems to work fine for RDP on Windows 10 * Not sure about other environments. */ - mousestate.dx += (state.lLastX - x) / 25; - mousestate.dy += (state.lLastY - y) / 25; + delta_x = (state.lLastX - x) / 25; + delta_y = (state.lLastY - y) / 25; x = state.lLastX; y = state.lLastY; } else { /* relative mouse, i.e. regular mouse */ - mousestate.dx += state.lLastX; - mousestate.dy += state.lLastY; + delta_x = state.lLastX; + delta_y = state.lLastY; } + + mouse_scale(delta_x, delta_y); } void @@ -124,27 +123,3 @@ win_mouse_close(void) ridev.usUsage = 0x02; RegisterRawInputDevices(&ridev, 1, sizeof(ridev)); } - -void -mouse_poll(void) -{ - static int b = 0; - if (mouse_capture || video_fullscreen) { - if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) { - mouse_x += mousestate.dx; - mouse_y += mousestate.dy; - mouse_z = mousestate.dwheel; - - mousestate.dx = 0; - mousestate.dy = 0; - mousestate.dwheel = 0; - - // pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); - } - - if (b != mousestate.buttons) { - mouse_buttons = mousestate.buttons; - b = mousestate.buttons; - } - } -} diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 2666608269..d0a245a456 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -41,7 +41,7 @@ static unsigned char *empty; static int create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) { - FILE *f; + FILE *fp; uint32_t magic = 0x46423638; uint16_t version = 0x020C; @@ -67,9 +67,9 @@ create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) tflags |= (disk_size.rpm << 5); /* RPM. */ switch (disk_size.hole) { + default: case 0: case 1: - default: switch (rpm_mode) { case 1: array_size = 25250; @@ -108,13 +108,13 @@ create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) memset(tarray, 0, 2048); memset(empty, 0, array_size); - f = plat_fopen(file_name, "wb"); - if (!f) + fp = plat_fopen(file_name, "wb"); + if (!fp) return 0; - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&dflags, 2, 1, f); + fwrite(&magic, 4, 1, fp); + fwrite(&version, 2, 1, fp); + fwrite(&dflags, 2, 1, fp); track_size = array_size + 6; @@ -126,17 +126,17 @@ create_86f(char *file_name, disk_size_t disk_size, uint8_t rpm_mode) for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) tarray[i] = track_base + (i * track_size); - fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); + fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, fp); for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, f); - fwrite(&index_hole_pos, 4, 1, f); - fwrite(empty, 1, array_size, f); + fwrite(&tflags, 2, 1, fp); + fwrite(&index_hole_pos, 4, 1, fp); + fwrite(empty, 1, array_size, fp); } free(empty); - fclose(f); + fclose(fp); return 1; } @@ -147,7 +147,7 @@ static int is_mo; static int create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) { - FILE *f; + FILE *fp; uint32_t total_size = 0; uint32_t total_sectors = 0; uint32_t sector_bytes = 0; @@ -158,8 +158,8 @@ create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) uint32_t zero_bytes = 0; uint16_t base = 0x1000; - f = plat_fopen(file_name, "wb"); - if (!f) + fp = plat_fopen(file_name, "wb"); + if (!fp) return 0; sector_bytes = (128 << disk_size.sector_len); @@ -184,7 +184,7 @@ create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - fwrite(empty, 1, base, f); + fwrite(empty, 1, base, fp); free(empty); } @@ -241,10 +241,10 @@ create_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_fdi) empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF; } - fwrite(empty, 1, total_size, f); + fwrite(empty, 1, total_size, fp); free(empty); - fclose(f); + fclose(fp); return 1; } @@ -253,7 +253,7 @@ static int create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, HWND hwnd) { HWND h; - FILE *f; + FILE *fp; uint32_t total_size = 0; uint32_t total_sectors = 0; uint32_t sector_bytes = 0; @@ -266,8 +266,8 @@ create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, uint32_t pbar_max = 0; MSG msg; - f = plat_fopen(file_name, "wb"); - if (!f) + fp = plat_fopen(file_name, "wb"); + if (!fp) return 0; sector_bytes = (128 << disk_size.sector_len); @@ -316,7 +316,7 @@ create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - fwrite(empty, 1, 2048, f); + fwrite(empty, 1, 2048, fp); SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { @@ -324,7 +324,7 @@ create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, DispatchMessage(&msg); } - fwrite(&empty[0x0800], 1, 2048, f); + fwrite(&empty[0x0800], 1, 2048, fp); free(empty); SendMessage(h, PBM_SETPOS, (WPARAM) 2, (LPARAM) 0); @@ -468,7 +468,7 @@ create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, } for (uint32_t i = 0; i < pbar_max; i++) { - fwrite(&empty[i << 11], 1, 2048, f); + fwrite(&empty[i << 11], 1, 2048, fp); SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { @@ -479,7 +479,7 @@ create_zip_sector_image(char *file_name, disk_size_t disk_size, uint8_t is_zdi, free(empty); - fclose(f); + fclose(fp); return 1; } @@ -488,7 +488,7 @@ static int create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND hwnd) { HWND h; - FILE *f; + FILE *fp; const mo_type_t *dp = &mo_types[disk_size]; uint8_t *empty; uint8_t *empty2 = NULL; @@ -502,8 +502,8 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h uint32_t j; MSG msg; - f = plat_fopen(file_name, "wb"); - if (!f) + fp = plat_fopen(file_name, "wb"); + if (!fp) return 0; sector_bytes = dp->bytes_per_sector; @@ -551,7 +551,7 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; - fwrite(empty, 1, 2048, f); + fwrite(empty, 1, 2048, fp); SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { @@ -559,7 +559,7 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h DispatchMessage(&msg); } - fwrite(&empty[0x0800], 1, 2048, f); + fwrite(&empty[0x0800], 1, 2048, fp); free(empty); SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); @@ -579,7 +579,7 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h } for (uint32_t i = 0; i < blocks_num; i++) { - fwrite(empty, 1, 1048576, f); + fwrite(empty, 1, 1048576, fp); SendMessage(h, PBM_SETPOS, (WPARAM) i + j, (LPARAM) 0); @@ -590,7 +590,7 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h } if (total_size2 > 0) { - fwrite(empty2, 1, total_size2, f); + fwrite(empty2, 1, total_size2, fp); SendMessage(h, PBM_SETPOS, (WPARAM) pbar_max - 1, (LPARAM) 0); @@ -604,7 +604,7 @@ create_mo_sector_image(char *file_name, int8_t disk_size, uint8_t is_mdi, HWND h free(empty2); free(empty); - fclose(f); + fclose(fp); return 1; } @@ -653,21 +653,21 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { - HWND h; - int i = 0; - int wcs_len; - int ext_offs; - wchar_t *ext; - uint8_t disk_size; - uint8_t rpm_mode; - int ret; - FILE *f; - int zip_types; - int mo_types; - int floppy_types; - wchar_t *twcs; + HWND h; + int i = 0; + int wcs_len; + int ext_offs; + const wchar_t *ext; + uint8_t disk_size; + uint8_t rpm_mode; + int ret; + FILE *fp; + int zip_types; + int mo_types; + int floppy_types; + wchar_t *twcs; switch (message) { case WM_INITDIALOG: @@ -739,7 +739,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) new_floppy_msgbox_header(hdlg, MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); return TRUE; } - /*FALLTHROUGH*/ + fallthrough; case IDCANCEL: EndDialog(hdlg, 0); plat_pause(0); @@ -763,9 +763,9 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } } h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) { - fclose(f); + fp = _wfopen(wopenfilestring, L"rb"); + if (fp != NULL) { + fclose(fp); if (new_floppy_msgbox_ex(hdlg, MBX_QUESTION, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ return FALSE; } diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 1f866d2735..094b3d063b 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -236,9 +236,9 @@ handle_window_messages(UINT message, WPARAM wParam, LPARAM lParam, int fullscree PRAWINPUT raw = NULL; /* Here we read the raw input data */ - GetRawInputData((HRAWINPUT) (LPARAM) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); raw = (PRAWINPUT) malloc(size); - if (GetRawInputData((HRAWINPUT) (LPARAM) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { + if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)) == size) { switch (raw->header.dwType) { case RIM_TYPEKEYBOARD: keyboard_handle(raw); @@ -447,8 +447,8 @@ opengl_fail(void) window = NULL; } - wchar_t *message = plat_get_string(IDS_2153); - wchar_t *header = plat_get_string(IDS_2154); + const wchar_t *message = plat_get_string(IDS_2153); + const wchar_t *header = plat_get_string(IDS_2154); MessageBox(parent, header, message, MB_OK); WaitForSingleObject(sync_objects.closing, INFINITE); @@ -456,7 +456,7 @@ opengl_fail(void) _endthread(); } -static void __stdcall opengl_debugmsg_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +static void __stdcall opengl_debugmsg_callback(UNUSED(GLenum source), UNUSED(GLenum type), UNUSED(GLuint id), UNUSED(GLenum severity), UNUSED(GLsizei length), const GLchar *message, UNUSED(const void *userParam)) { pclog("OpenGL: %s\n", message); } @@ -468,7 +468,7 @@ static void __stdcall opengl_debugmsg_callback(GLenum source, GLenum type, GLuin * Events are used to synchronize communication. */ static void -opengl_main(void *param) +opengl_main(UNUSED(void *param)) { /* Initialize COM library for this thread before SDL does so. */ CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -638,7 +638,7 @@ opengl_main(void *param) } while (wait_result == WAIT_TIMEOUT); - HANDLE sync_event = sync_objects.asArray[wait_result - WAIT_OBJECT_0]; + const HANDLE sync_event = sync_objects.asArray[wait_result - WAIT_OBJECT_0]; if (sync_event == sync_objects.closing) { closing = 1; @@ -902,7 +902,7 @@ opengl_init(HWND hwnd) write_pos = 0; - thread = thread_create(opengl_main, (void *) NULL); + thread = thread_create(opengl_main, NULL); atexit(opengl_close); @@ -936,7 +936,7 @@ opengl_close(void) for (int i = 0; i < sizeof(sync_objects) / sizeof(HANDLE); i++) { CloseHandle(sync_objects.asArray[i]); - sync_objects.asArray[i] = (HANDLE) NULL; + sync_objects.asArray[i] = NULL; } parent = NULL; diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index 47cc755dcb..9689f3ab22 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -50,8 +50,8 @@ in vec2 VertexCoord;\n\ in vec2 TexCoord;\n\ out vec2 tex;\n\ void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ + gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ + tex = TexCoord;\n\ }\n"; /** @@ -62,7 +62,7 @@ in vec2 tex;\n\ uniform sampler2D texsampler;\n\ out vec4 color;\n\ void main() {\n\ - color = texture(texsampler, tex);\n\ + color = texture(texsampler, tex);\n\ }\n"; /** @@ -82,15 +82,15 @@ typedef enum { static char * read_file_to_string(const char *path) { - FILE *file_handle = plat_fopen(path, "rb"); + FILE *fp = plat_fopen(path, "rb"); - if (file_handle != NULL) { + if (fp != NULL) { /* get file size */ - fseek(file_handle, 0, SEEK_END); + fseek(fp, 0, SEEK_END); - size_t file_size = (size_t) ftell(file_handle); + size_t file_size = (size_t) ftell(fp); - fseek(file_handle, 0, SEEK_SET); + fseek(fp, 0, SEEK_SET); /* read to buffer and close */ char *content = (char *) malloc(sizeof(char) * (file_size + 1)); @@ -98,9 +98,9 @@ read_file_to_string(const char *path) if (!content) return NULL; - size_t length = fread(content, sizeof(char), file_size, file_handle); + size_t length = fread(content, sizeof(char), file_size, fp); - fclose(file_handle); + fclose(fp); content[length] = 0; @@ -179,11 +179,11 @@ load_custom_shaders(const char *path) /* Check if the shader program defines version directive */ char *version_start = strstr(shader, "#version"); - /* If the shader program contains a version directive, + /* If the shader program contains a version directive, it must be captured and placed as the first statement. */ if (version_start != NULL) { /* Version directive found, search the line end */ - char *version_end = strchr(version_start, '\n'); + const char *version_end = strchr(version_start, '\n'); if (version_end != NULL) { char version[30] = ""; @@ -197,7 +197,7 @@ load_custom_shaders(const char *path) fragment_sources[0] = version; } - /* Comment out the original version directive + /* Comment out the original version directive as only one is allowed. */ memset(version_start, '/', 2); } diff --git a/src/win/win_preferences.c b/src/win/win_preferences.c index d095dcd315..ee93321a89 100644 --- a/src/win/win_preferences.c +++ b/src/win/win_preferences.c @@ -45,7 +45,7 @@ int c; HWND hwndPreferences; BOOL CALLBACK -EnumResLangProc(HMODULE hModule, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIDLanguage, LONG_PTR lParam) +EnumResLangProc(UNUSED(HMODULE hModule), UNUSED(LPCTSTR lpszType), UNUSED(LPCTSTR lpszName), WORD wIDLanguage, LONG_PTR lParam) { wchar_t temp[LOCALE_NAME_MAX_LENGTH + 1]; LCIDToLocaleName(wIDLanguage, temp, LOCALE_NAME_MAX_LENGTH, 0); @@ -205,7 +205,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +PreferencesDlgProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { switch (message) { case WM_INITDIALOG: diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index cae5f8147a..ea9c8455d7 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -188,8 +188,8 @@ sdl_stretch(int *w, int *h, int *x, int *y) hsr = hw / hh; switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: default: + case FULLSCR_SCALE_FULL: *w = sdl_w; *h = sdl_h; *x = 0; @@ -256,7 +256,7 @@ sdl_blit(int x, int y, int w, int h, int monitor_index) SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), 2048 * sizeof(uint32_t)); if (monitors[0].mon_screenshots) - video_screenshot((uint32_t *) buffer32->dat, x, y, 2048); + video_screenshot(buffer32->dat, x, y, 2048); video_blit_complete(); @@ -276,7 +276,7 @@ sdl_blit(int x, int y, int w, int h, int monitor_index) } static void -sdl_blit_ex(int x, int y, int w, int h, int monitor_index) +sdl_blit_ex(int x, int y, int w, int h, UNUSED(int monitor_index)) { SDL_Rect r_src; void *pixeldata; @@ -465,7 +465,9 @@ sdl_set_fs(int fs) else sdl_flags &= ~RENDERER_FULL_SCREEN; - // sdl_reinit_texture(); +#if 0 + sdl_reinit_texture(); +#endif sdl_enabled = 1; SDL_UnlockMutex(sdl_mutex); } @@ -528,19 +530,19 @@ sdl_init_common(int flags) } int -sdl_inits(HWND h) +sdl_inits(UNUSED(HWND h)) { return sdl_init_common(0); } int -sdl_inith(HWND h) +sdl_inith(UNUSED(HWND h)) { return sdl_init_common(RENDERER_HARDWARE); } int -sdl_initho(HWND h) +sdl_initho(UNUSED(HWND h)) { return sdl_init_common(RENDERER_HARDWARE | RENDERER_OPENGL); } diff --git a/src/win/win_serial_passthrough.c b/src/win/win_serial_passthrough.c index cfe920aa70..b2d09b1d0e 100644 --- a/src/win/win_serial_passthrough.c +++ b/src/win/win_serial_passthrough.c @@ -38,11 +38,13 @@ #define LOG_PREFIX "serial_passthrough: " void -plat_serpt_close(void *p) +plat_serpt_close(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; - // fclose(dev->master_fd); +#if 0 + fclose(dev->master_fd); +#endif FlushFileBuffers((HANDLE) dev->master_fd); if (dev->mode == SERPT_MODE_VCON) DisconnectNamedPipe((HANDLE) dev->master_fd); @@ -56,31 +58,34 @@ plat_serpt_close(void *p) static void plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) { - /* fd_set wrfds; - * int res; - */ +#if 0 + fd_set wrfds; + int res; +#endif /* We cannot use select here, this would block the hypervisor! */ - /* FD_ZERO(&wrfds); - FD_SET(ctx->master_fd, &wrfds); +#if 0 + FD_ZERO(&wrfds); + FD_SET(ctx->master_fd, &wrfds); - res = select(ctx->master_fd + 1, NULL, &wrfds, NULL, NULL); + res = select(ctx->master_fd + 1, NULL, &wrfds, NULL, NULL); - if (res <= 0) { - return; - } - */ + if (res <= 0) + return; +#endif /* just write it out */ - // fwrite(dev->master_fd, &data, 1); +#if 0 + fwrite(dev->master_fd, &data, 1); +#endif DWORD bytesWritten = 0; WriteFile((HANDLE) dev->master_fd, &data, 1, &bytesWritten, NULL); } void -plat_serpt_set_params(void *p) +plat_serpt_set_params(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + const serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode == SERPT_MODE_HOSTSER) { DCB serialattr = {}; @@ -123,9 +128,9 @@ plat_serpt_set_params(void *p) } void -plat_serpt_write(void *p, uint8_t data) +plat_serpt_write(void *priv, uint8_t data) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { case SERPT_MODE_VCON: @@ -146,9 +151,9 @@ plat_serpt_read_vcon(serial_passthrough_t *dev, uint8_t *data) } int -plat_serpt_read(void *p, uint8_t *data) +plat_serpt_read(void *priv, uint8_t *data) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; int res = 0; switch (dev->mode) { @@ -212,9 +217,9 @@ open_host_serial_port(serial_passthrough_t *dev) } int -plat_serpt_open_device(void *p) +plat_serpt_open_device(void *priv) { - serial_passthrough_t *dev = (serial_passthrough_t *) p; + serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { case SERPT_MODE_VCON: diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 020dca31b3..139c387a8f 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -371,8 +371,8 @@ win_settings_init(void) temp_gfxcard[0] = gfxcard[0]; temp_gfxcard[1] = gfxcard[1]; temp_voodoo = voodoo_enabled; - temp_ibm8514 = ibm8514_enabled; - temp_xga = xga_enabled; + temp_ibm8514 = ibm8514_standalone_enabled; + temp_xga = xga_standalone_enabled; /* Input devices category */ temp_mouse = mouse_type; @@ -501,8 +501,8 @@ win_settings_changed(void) i = i || (gfxcard[0] != temp_gfxcard[0]); i = i || (gfxcard[1] != temp_gfxcard[1]); i = i || (voodoo_enabled != temp_voodoo); - i = i || (ibm8514_enabled != temp_ibm8514); - i = i || (xga_enabled != temp_xga); + i = i || (ibm8514_standalone_enabled != temp_ibm8514); + i = i || (xga_standalone_enabled != temp_xga); /* Input devices category */ i = i || (mouse_type != temp_mouse); @@ -592,11 +592,11 @@ win_settings_save(void) time_sync = temp_sync; /* Video category */ - gfxcard[0] = temp_gfxcard[0]; - gfxcard[1] = temp_gfxcard[1]; - voodoo_enabled = temp_voodoo; - ibm8514_enabled = temp_ibm8514; - xga_enabled = temp_xga; + gfxcard[0] = temp_gfxcard[0]; + gfxcard[1] = temp_gfxcard[1]; + voodoo_enabled = temp_voodoo; + ibm8514_standalone_enabled = temp_ibm8514; + xga_standalone_enabled = temp_xga; /* Input devices category */ mouse_type = temp_mouse; @@ -664,12 +664,12 @@ win_settings_save(void) } memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); for (uint8_t i = 0; i < ZIP_NUM; i++) { - zip_drives[i].f = NULL; + zip_drives[i].fp = NULL; zip_drives[i].priv = NULL; } memcpy(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t)); for (uint8_t i = 0; i < MO_NUM; i++) { - mo_drives[i].f = NULL; + mo_drives[i].fp = NULL; mo_drives[i].priv = NULL; } @@ -688,6 +688,18 @@ win_settings_save(void) pc_reset_hard_init(); } +static void +win_settings_machine_recalc_softfloat(HWND hdlg) +{ + if (temp_fpu == FPU_NONE) { + settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); + settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, FALSE); + } else { + settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? TRUE : temp_fpu_softfloat)); + settings_enable_window(hdlg, IDC_CHECK_SOFTFLOAT, (machine_has_flags(temp_machine, MACHINE_SOFTFLOAT_ONLY) ? FALSE : TRUE)); + } +} + static void win_settings_machine_recalc_fpu(HWND hdlg) { @@ -701,7 +713,7 @@ win_settings_machine_recalc_fpu(HWND hdlg) settings_reset_content(hdlg, IDC_COMBO_FPU); c = 0; while (1) { - stransi = (char *) fpu_get_name_from_index(temp_cpu_f, temp_cpu, c); + stransi = fpu_get_name_from_index(temp_cpu_f, temp_cpu, c); type = fpu_get_type_from_index(temp_cpu_f, temp_cpu, c); if (!stransi) break; @@ -714,11 +726,11 @@ win_settings_machine_recalc_fpu(HWND hdlg) c++; } - settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, temp_fpu_softfloat); - settings_enable_window(hdlg, IDC_COMBO_FPU, c > 1); temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); + + win_settings_machine_recalc_softfloat(hdlg); } static void @@ -736,7 +748,7 @@ win_settings_machine_recalc_cpu(HWND hdlg) cpu_flags = temp_cpu_f->cpus[temp_cpu].cpu_flags; if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) { + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || ((cpu_flags & CPU_REQUIRES_DYNAREC) && !cpu_override)) { if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) temp_dynarec = 0; if (cpu_flags & CPU_REQUIRES_DYNAREC) @@ -755,13 +767,13 @@ win_settings_machine_recalc_cpu(HWND hdlg) static void win_settings_machine_recalc_cpu_m(HWND hdlg) { - int c; - int i; - int first_eligible = -1; - int current_eligible = 0; - int last_eligible = 0; - LPTSTR lptsTemp; - char *stransi; + int c; + int i; + int first_eligible = -1; + int current_eligible = 0; + int last_eligible = 0; + LPTSTR lptsTemp; + const char *stransi; lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); @@ -801,14 +813,14 @@ win_settings_machine_recalc_cpu_m(HWND hdlg) static void win_settings_machine_recalc_machine(HWND hdlg) { - HWND h; - int c; - int i; - int current_eligible; - LPTSTR lptsTemp; - char *stransi; - UDACCEL accel; - device_t *d; + HWND h; + int c; + int i; + int current_eligible; + LPTSTR lptsTemp; + char *stransi; + UDACCEL accel; + const device_t *d; lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); @@ -909,7 +921,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { HWND h; HWND h2; @@ -944,7 +956,7 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) memset(listtomachine, 0x00, sizeof(listtomachine)); while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = machine_getname_ex(c); + stransi = (char *) machine_getname_ex(c); mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); listtomachine[d] = c; @@ -1001,7 +1013,7 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) memset(listtomachine, 0x00, sizeof(listtomachine)); while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { - stransi = machine_getname_ex(c); + stransi = (char *) machine_getname_ex(c); mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); listtomachine[d] = c; @@ -1045,6 +1057,7 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU)); } + win_settings_machine_recalc_softfloat(hdlg); break; case IDC_CONFIGURE_MACHINE: temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)]; @@ -1097,10 +1110,10 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } static void -generate_device_name(const device_t *device, char *internal_name, int bus) +generate_device_name(const device_t *device, const char *internal_name, int bus) { - char temp[512]; - WCHAR *wtemp; + char temp[512]; + const WCHAR *wtemp; memset(device_name, 0x00, 512 * sizeof(WCHAR)); memset(temp, 0x00, 512); @@ -1123,7 +1136,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { int c = 0; int d = 0; @@ -1346,12 +1359,12 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { - wchar_t str[128]; - char *joy_name; - int c; - int d; + wchar_t str[128]; + const char *joy_name; + int c; + int d; switch (message) { case WM_INITDIALOG: @@ -1407,7 +1420,7 @@ win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDC_COMBO_JOYSTICK: temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK); - for (c = 0; c < 4; c++) + for (c = 0; c < MAX_JOYSTICKS; c++) settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c); break; @@ -1440,17 +1453,17 @@ mpu401_present(void) int mpu401_standalone_allow(void) { - char *md; - char *mdin; + const char *mdout; + const char *mdin; if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA)) return 0; - md = midi_out_device_get_internal_name(temp_midi_output_device); - mdin = midi_in_device_get_internal_name(temp_midi_input_device); + mdout = midi_out_device_get_internal_name(temp_midi_output_device); + mdin = midi_in_device_get_internal_name(temp_midi_input_device); - if (md != NULL) { - if (!strcmp(md, "none") && !strcmp(mdin, "none")) + if (mdout != NULL) { + if (!strcmp(mdout, "none") && !strcmp(mdin, "none")) return 0; } @@ -1462,7 +1475,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { uint16_t c; uint16_t d; @@ -1798,12 +1811,12 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { - int c; - int i; - char *s; - LPTSTR lptsTemp; + int c; + int i; + const char *s; + LPTSTR lptsTemp; switch (message) { case WM_INITDIALOG: @@ -1812,7 +1825,7 @@ win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) for (i = 0; i < PARALLEL_MAX; i++) { c = 0; while (1) { - s = lpt_device_get_name(c); + s = (char *) lpt_device_get_name(c); if (!s) break; @@ -1876,7 +1889,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { int c; int d; @@ -2002,9 +2015,10 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter); settings_enable_window(hdlg, IDC_CHECK_IDE_QUA, is_at); settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua); + settings_enable_window(hdlg, IDC_CHECK_CASSETTE, machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE)); settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter); settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua); - settings_set_check(hdlg, IDC_CHECK_CASSETTE, temp_cassette); + settings_set_check(hdlg, IDC_CHECK_CASSETTE, (temp_cassette && machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE))); free(stransi); free(lptsTemp); @@ -2100,7 +2114,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { int c; int d; @@ -2446,7 +2460,7 @@ recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) settings_show_window(hdlg, IDC_COMBO_HD_ID, TRUE); if (assign_id) - next_free_scsi_id((uint8_t *) (is_add_dlg ? &(new_hdd.scsi_id) : &(temp_hdd[lv1_current_sel].scsi_id))); + next_free_scsi_id((is_add_dlg ? &(new_hdd.scsi_id) : &(temp_hdd[lv1_current_sel].scsi_id))); settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, is_add_dlg ? new_hdd.scsi_id : temp_hdd[lv1_current_sel].scsi_id); } } @@ -2461,8 +2475,8 @@ bus_full(uint64_t *tracking, int count) int full = 0; switch (count) { - case 2: default: + case 2: full = (*tracking & 0xFF00LL); full = full && (*tracking & 0x00FFLL); break; @@ -2818,14 +2832,14 @@ set_edit_box_contents(HWND hdlg, int id, uint32_t val) h = GetDlgItem(hdlg, id); wsprintf(szText, plat_get_string(IDS_2107), val); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); + SendMessage(h, WM_SETTEXT, wcslen(szText), (LPARAM) szText); } static void set_edit_box_text_contents(HWND hdlg, int id, WCHAR *text) { HWND h = GetDlgItem(hdlg, id); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(text), (LPARAM) text); + SendMessage(h, WM_SETTEXT, wcslen(text), (LPARAM) text); } static void @@ -2874,11 +2888,11 @@ recalc_selection(HWND hdlg) HWND vhd_progress_hdlg; static void -vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors) +vhd_progress_callback(uint32_t current_sector, UNUSED(uint32_t total_sectors)) { MSG msg; HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETPOS, (WPARAM) current_sector, (LPARAM) 0); + SendMessage(h, PBM_SETPOS, current_sector, (LPARAM) 0); while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { TranslateMessage(&msg); DispatchMessage(&msg); @@ -3027,10 +3041,10 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { HWND h; - FILE *f; + FILE *fp; uint32_t temp; uint32_t i = 0; uint32_t sector_size = 512; @@ -3196,38 +3210,38 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT); if (img_format < IMG_FMT_VHD_FIXED) { - f = _wfopen(hd_file_name, L"wb"); + fp = _wfopen(hd_file_name, L"wb"); } else { - f = (FILE *) 0; + fp = (FILE *) 0; } if (img_format == IMG_FMT_HDI) { /* HDI file */ if (size >= 0x100000000LL) { - fclose(f); + fclose(fp); settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104); return TRUE; } - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, fp); /* 00000000: Zero/unknown */ + fwrite(&zero, 1, 4, fp); /* 00000004: Zero/unknown */ + fwrite(&base, 1, 4, fp); /* 00000008: Offset at which data starts */ + fwrite(&size, 1, 4, fp); /* 0000000C: Full size of the data (32-bit) */ + fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ for (i = 0; i < 0x3f8; i++) - fwrite(&zero, 1, 4, f); + fwrite(&zero, 1, 4, fp); } else if (img_format == IMG_FMT_HDX) { /* HDX file */ - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + fwrite(&signature, 1, 8, fp); /* 00000000: Signature */ + fwrite(&size, 1, 8, fp); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, fp); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, fp); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, fp); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, fp); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, fp); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, fp); /* 00000004: [Translation] Heads per cylinder */ } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ MVHDGeom _86box_geometry; block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; @@ -3280,18 +3294,18 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); if (size) { - if (f) { - fwrite(big_buf, 1, size, f); + if (fp) { + fwrite(big_buf, 1, size, fp); } SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); } if (r) { for (i = 0; i < r; i++) { - if (f) { - fwrite(big_buf, 1, 1048576, f); + if (fp) { + fwrite(big_buf, 1, 1048576, fp); } - SendMessage(h, PBM_SETPOS, (WPARAM) (i + 1), (LPARAM) 0); + SendMessage(h, PBM_SETPOS, (i + 1), (LPARAM) 0); settings_process_messages(); } @@ -3299,8 +3313,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM free(big_buf); - if (f) { - fclose(f); + if (fp) { + fclose(fp); } settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); } @@ -3328,36 +3342,36 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM } if (!(existing & 1)) { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) { - fclose(f); + fp = _wfopen(wopenfilestring, L"rb"); + if (fp != NULL) { + fclose(fp); if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ return FALSE; } } - f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (f == NULL) { + fp = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); + if (fp == NULL) { hdd_add_file_open_error: - fclose(f); + fclose(fp); settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); return TRUE; } if (existing & 1) { if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); + fseeko64(fp, 0x10, SEEK_SET); + fread(§or_size, 1, 4, fp); if (sector_size != 512) { settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4119, (wchar_t *) IDS_4109); - fclose(f); + fclose(fp); return TRUE; } spt = hpc = tracks = 0; - fread(&spt, 1, 4, f); - fread(&hpc, 1, 4, f); - fread(&tracks, 1, 4, f); + fread(&spt, 1, 4, fp); + fread(&hpc, 1, 4, fp); + fread(&tracks, 1, 4, fp); } else if (image_is_vhd(openfilestring, 1)) { - fclose(f); + fclose(fp); MVHDMeta *vhd = mvhd_open(openfilestring, 0, &vhd_error); if (vhd == NULL) { settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); @@ -3384,8 +3398,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM size = (uint64_t) tracks * hpc * spt * 512; mvhd_close(vhd); } else { - fseeko64(f, 0, SEEK_END); - size = ftello64(f); + fseeko64(fp, 0, SEEK_END); + size = ftello64(fp); if (((size % 17) == 0) && (size <= 142606336)) { spt = 17; if (size <= 26738688) @@ -3430,7 +3444,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM no_update = 0; } - fclose(f); + fclose(fp); } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); @@ -3621,8 +3635,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM hdd_ptr->bus = b; switch (hdd_ptr->bus) { - case HDD_BUS_DISABLED: default: + case HDD_BUS_DISABLED: max_spt = max_hpc = max_tracks = 0; break; case HDD_BUS_MFM: @@ -3966,11 +3980,11 @@ combo_id_to_format_string_id(int combo_id) static BOOL win_settings_floppy_drives_recalc_list(HWND hdlg) { - LVITEM lvI; - char s[256]; - char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + LVITEM lvI; + char s[256]; + const char *t; + WCHAR szText[256]; + HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvI.stateMask = lvI.state = 0; @@ -4026,8 +4040,8 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg) lvI.iSubItem = 0; switch (temp_cdrom[i].bus_type) { - case CDROM_BUS_DISABLED: default: + case CDROM_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4061,7 +4075,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; -/* +#if 0 lvI.iSubItem = 2; lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); lvI.iItem = i; @@ -4069,7 +4083,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; -*/ +#endif } return TRUE; @@ -4092,8 +4106,8 @@ win_settings_mo_drives_recalc_list(HWND hdlg) lvI.iSubItem = 0; switch (temp_mo_drives[i].bus_type) { - case MO_BUS_DISABLED: default: + case MO_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4154,8 +4168,8 @@ win_settings_zip_drives_recalc_list(HWND hdlg) lvI.iSubItem = 0; switch (temp_zip_drives[i].bus_type) { - case ZIP_BUS_DISABLED: default: + case ZIP_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4382,7 +4396,7 @@ win_settings_mo_drives_init_columns(HWND hdlg) static void win_settings_zip_drives_resize_columns(HWND hdlg) { - int width[C_COLUMNS_MO_DRIVES] = { + int width[C_COLUMNS_ZIP_DRIVES] = { C_COLUMNS_ZIP_DRIVES_BUS, C_COLUMNS_ZIP_DRIVES_TYPE }; @@ -4448,11 +4462,11 @@ get_selected_drive(HWND hdlg, int id, int max) static void win_settings_floppy_drives_update_item(HWND hdlg, int i) { - LVITEM lvI; - char s[256]; - char *t; - WCHAR szText[256]; - HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + LVITEM lvI; + char s[256]; + const char *t; + WCHAR szText[256]; + HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvI.stateMask = lvI.iSubItem = lvI.state = 0; @@ -4506,8 +4520,8 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i) fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type); switch (temp_cdrom[i].bus_type) { - case CDROM_BUS_DISABLED: default: + case CDROM_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4539,7 +4553,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i) if (ListView_SetItem(hwndList, &lvI) == -1) return; -/* +#if 0 lvI.iSubItem = 2; lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061); lvI.iItem = i; @@ -4547,7 +4561,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i) if (ListView_SetItem(hwndList, &lvI) == -1) return; -*/ +#endif } static void @@ -4569,8 +4583,8 @@ win_settings_mo_drives_update_item(HWND hdlg, int i) fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type); switch (temp_mo_drives[i].bus_type) { - case MO_BUS_DISABLED: default: + case MO_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4627,8 +4641,8 @@ win_settings_zip_drives_update_item(HWND hdlg, int i) fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); switch (temp_zip_drives[i].bus_type) { - case ZIP_BUS_DISABLED: default: + case ZIP_BUS_DISABLED: lvI.pszText = plat_get_string(fsid); lvI.iImage = 0; break; @@ -4698,12 +4712,14 @@ cdrom_recalc_location_controls(HWND hdlg, int assign_id) settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, FALSE); settings_show_window(hdlg, IDC_COMBO_CD_SPEED, bus != CDROM_BUS_DISABLED); settings_show_window(hdlg, IDT_CD_SPEED, bus != CDROM_BUS_DISABLED); -/* - settings_show_window(hdlg, IDC_CHECKEARLY, bus != CDROM_BUS_DISABLED); -*/ +#if 0 + settings_show_window(hdlg, IDC_COMBO_CD_TYPE, bus != CDROM_BUS_DISABLED); +#endif if (bus != CDROM_BUS_DISABLED) { settings_set_cur_sel(hdlg, IDC_COMBO_CD_SPEED, temp_cdrom[lv2_current_sel].speed - 1); -// settings_set_check(hdlg, IDC_CHECKEARLY, temp_cdrom[lv2_current_sel].early); +#if 0 + settings_set_check(hdlg, IDC_COMBO_CD_TYPE, temp_cdrom[lv2_current_sel].early); +#endif } switch (bus) { @@ -4721,7 +4737,7 @@ cdrom_recalc_location_controls(HWND hdlg, int assign_id) settings_show_window(hdlg, IDC_COMBO_CD_ID, TRUE); if (assign_id) - next_free_scsi_id((uint8_t *) &temp_cdrom[lv2_current_sel].scsi_device_id); + next_free_scsi_id(&temp_cdrom[lv2_current_sel].scsi_device_id); settings_set_cur_sel(hdlg, IDC_COMBO_CD_ID, temp_cdrom[lv2_current_sel].scsi_device_id); break; @@ -4799,7 +4815,7 @@ mo_recalc_location_controls(HWND hdlg, int assign_id) settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE); if (assign_id) - next_free_scsi_id((uint8_t *) &temp_mo_drives[lv1_current_sel].scsi_device_id); + next_free_scsi_id(&temp_mo_drives[lv1_current_sel].scsi_device_id); settings_set_cur_sel(hdlg, IDC_COMBO_MO_ID, temp_mo_drives[lv1_current_sel].scsi_device_id); break; @@ -4861,7 +4877,7 @@ zip_recalc_location_controls(HWND hdlg, int assign_id) settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE); if (assign_id) - next_free_scsi_id((uint8_t *) &temp_zip_drives[lv2_current_sel].scsi_device_id); + next_free_scsi_id(&temp_zip_drives[lv2_current_sel].scsi_device_id); settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_ID, temp_zip_drives[lv2_current_sel].scsi_device_id); break; @@ -4908,7 +4924,7 @@ static void mo_track(uint8_t id) { if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking |= (1 << (temp_zip_drives[id].ide_channel << 3)); + ide_tracking |= (1 << (temp_mo_drives[id].ide_channel << 3)); else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] |= (1 << (temp_mo_drives[id].scsi_device_id & 0x07)); } @@ -4917,7 +4933,7 @@ static void mo_untrack(uint8_t id) { if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI) - ide_tracking &= ~(1 << (temp_zip_drives[id].ide_channel << 3)); + ide_tracking &= ~(1 << (temp_mo_drives[id].ide_channel << 3)); else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI) scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_mo_drives[id].scsi_device_id & 0x07)); } @@ -4969,8 +4985,8 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam cdrom_add_locations(hdlg); switch (temp_cdrom[lv2_current_sel].bus_type) { - case CDROM_BUS_DISABLED: default: + case CDROM_BUS_DISABLED: b = 0; break; case CDROM_BUS_ATAPI: @@ -5010,8 +5026,8 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam ignore_change = 1; switch (temp_cdrom[lv2_current_sel].bus_type) { - case CDROM_BUS_DISABLED: default: + case CDROM_BUS_DISABLED: b = 0; break; case CDROM_BUS_ATAPI: @@ -5093,12 +5109,12 @@ win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); break; -/* - case IDC_CHECKEARLY: - temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_CHECKEARLY); +#if 0 + case IDC_COMBO_CD_TYPE:: + temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_COMBO_CD_TYPE:); win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel); break; -*/ +#endif } ignore_change = 0; @@ -5141,8 +5157,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam mo_add_locations(hdlg); switch (temp_mo_drives[lv1_current_sel].bus_type) { - case MO_BUS_DISABLED: default: + case MO_BUS_DISABLED: b = 0; break; case MO_BUS_ATAPI: @@ -5165,8 +5181,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam zip_add_locations(hdlg); switch (temp_zip_drives[lv2_current_sel].bus_type) { - case ZIP_BUS_DISABLED: default: + case ZIP_BUS_DISABLED: b = 0; break; case ZIP_BUS_ATAPI: @@ -5196,8 +5212,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam ignore_change = 1; switch (temp_mo_drives[lv1_current_sel].bus_type) { - case MO_BUS_DISABLED: default: + case MO_BUS_DISABLED: b = 0; break; case MO_BUS_ATAPI: @@ -5219,8 +5235,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam ignore_change = 1; switch (temp_zip_drives[lv2_current_sel].bus_type) { - case ZIP_BUS_DISABLED: default: + case ZIP_BUS_DISABLED: b = 0; break; case ZIP_BUS_ATAPI: @@ -5349,7 +5365,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { int c; int d; @@ -5415,7 +5431,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa } settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); - settings_set_check(hdlg, IDC_CHECK_BUGGER, temp_bugger); + settings_set_check(hdlg, IDC_CHECK_BUGGER, (temp_bugger && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard); free(stransi); diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 641a83a5cd..5297661bf2 100644 --- a/src/win/win_snd_gain.c +++ b/src/win/win_snd_gain.c @@ -39,7 +39,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lParam)) { HWND h; @@ -47,7 +47,7 @@ SoundGainDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: old_gain = sound_gain; h = GetDlgItem(hdlg, IDC_SLIDER_GAIN); - SendMessage(h, TBM_SETRANGE, (WPARAM) 1, (LPARAM) MAKELONG(0, 9)); + SendMessage(h, TBM_SETRANGE, (WPARAM) 1, MAKELONG(0, 9)); SendMessage(h, TBM_SETPOS, (WPARAM) 1, 9 - (sound_gain >> 1)); SendMessage(h, TBM_SETTICFREQ, (WPARAM) 1, 0); SendMessage(h, TBM_SETLINESIZE, (WPARAM) 0, 1); diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index 48e7801a53..5bedb846dc 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -178,7 +178,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM break; } - return (FALSE); + return FALSE; } void diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 73f2d7231d..2cf8d84f4b 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -493,22 +493,22 @@ ui_sb_set_ready(int ready) void ui_sb_update_panes(void) { - int i; - int id; - int cart_int; - int mfm_int; - int xta_int; - int esdi_int; - int ide_int; - int scsi_int; - int edge = 0; - int c_mfm; - int c_esdi; - int c_xta; - int c_ide; - int c_scsi; - int do_net; - char *hdc_name; + int i; + int id; + int cart_int; + int mfm_int; + int xta_int; + int esdi_int; + int ide_int; + int scsi_int; + int edge = 0; + int c_mfm; + int c_esdi; + int c_xta; + int c_ide; + int c_scsi; + int do_net; + const char *hdc_name; if (!config_changed) return; @@ -522,7 +522,7 @@ ui_sb_update_panes(void) xta_int = machine_has_flags(machine, MACHINE_XTA) ? 1 : 0; esdi_int = machine_has_flags(machine, MACHINE_ESDI) ? 1 : 0; ide_int = machine_has_flags(machine, MACHINE_IDE_QUAD) ? 1 : 0; - scsi_int = machine_has_flags(machine, MACHINE_SCSI_DUAL) ? 1 : 0; + scsi_int = machine_has_flags(machine, MACHINE_SCSI) ? 1 : 0; c_mfm = hdd_count(HDD_BUS_MFM); c_esdi = hdd_count(HDD_BUS_ESDI); @@ -833,7 +833,7 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id) pt.x = id * icon_width; /* Justify to the left. */ pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, (LPPOINT) &pt); + ClientToScreen(hwnd, &pt); switch (sb_part_meanings[id] & 0xF0) { case SB_CASSETTE: @@ -865,7 +865,7 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id) /* API: Load status bar icons */ void -StatusBarLoadIcon(HINSTANCE hInst) +StatusBarLoadIcon(UNUSED(HINSTANCE hInst)) { win_load_icon_set(); } @@ -891,19 +891,19 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT) &rc); + GetClientRect(hwnd, &rc); pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) + if (PtInRect(&rc, pt)) StatusBarPopupMenu(hwnd, pt, (pt.x / icon_width)); break; case WM_LBUTTONDBLCLK: - GetClientRect(hwnd, (LPRECT) &rc); + GetClientRect(hwnd, &rc); pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); item_id = (pt.x / icon_width); - if (PtInRect((LPRECT) &rc, pt) && (item_id < sb_parts)) { + if (PtInRect(&rc, pt) && (item_id < sb_parts)) { if (sb_part_meanings[item_id] == SB_SOUND) SoundGainDialogCreate(hwndMain); } @@ -1052,6 +1052,7 @@ ui_sb_bugui(char *str) /* API */ void -ui_sb_mt32lcd(char *str) +ui_sb_mt32lcd(UNUSED(char *str)) { + // } diff --git a/src/win/win_thread.c b/src/win/win_thread.c index faacca74fe..e874c49412 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -37,9 +37,10 @@ typedef struct { } win_event_t; thread_t * -thread_create(void (*func)(void *param), void *param) +thread_create_named(void (*func)(void *param), void *param, const char *name) { uintptr_t bt = _beginthread(func, 0, param); + plat_set_thread_name((void *) bt, name); return ((thread_t *) bt); } diff --git a/src/win/win_ui.c b/src/win/win_ui.c index e9485f7ee8..207158b298 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -57,20 +57,20 @@ #define TIMER_1SEC 1 /* ID of the one-second timer */ /* Platform Public data, specific. */ -HWND hwndMain = NULL; /* application main window */ -HWND hwndRender = NULL; /* machine render window */ -HWND hwndRender2 = NULL; /* machine second screen render window */ -HMENU menuMain; /* application main menu */ -RECT oldclip; /* mouse rect */ -int sbar_height = 23; /* statusbar height */ -int tbar_height = 23; /* toolbar height */ -int minimized = 0; -int infocus = 1; -int button_down = 0; -int rctrl_is_lalt = 0; -int user_resize = 0; -int fixed_size_x = 0; -int fixed_size_y = 0; +HWND hwndMain = NULL; /* application main window */ +HWND hwndRender = NULL; /* machine render window */ +HWND hwndRender2 = NULL; /* machine second screen render window */ +HMENU menuMain; /* application main menu */ +RECT oldclip; /* mouse rect */ +int sbar_height = 23; /* statusbar height */ +int tbar_height = 23; /* toolbar height */ +int minimized = 0; +int infocus = 1; +int button_down = 0; +int rctrl_is_lalt = 0; +int user_resize = 0; +int fixed_size_x = 0; +int fixed_size_y = 0; int kbd_req_capture = 0; int hide_status_bar = 0; int hide_tool_bar = 0; @@ -396,10 +396,14 @@ plat_power_off(void) /* Cleanly terminate all of the emulator's components so as to avoid things like threads getting stuck. */ - // do_stop(); +#if 0 + do_stop(); +#endif cpu_thread_run = 0; - // exit(-1); +#if 0 + exit(-1); +#endif } #ifdef MTR_ENABLED @@ -422,7 +426,7 @@ static LRESULT CALLBACK #else static BOOL CALLBACK #endif -input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +input_proc(UNUSED(HWND hwnd), UINT message, UNUSED(WPARAM wParam), LPARAM lParam) { switch (message) { case WM_INPUT: @@ -476,8 +480,8 @@ input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) default: return 1; #if 0 - return(CallWindowProc((WNDPROC)input_orig_proc, - hwnd, message, wParam, lParam)); + return(CallWindowProc((WNDPROC)input_orig_proc, + hwnd, message, wParam, lParam)); #endif } @@ -499,7 +503,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) int temp_y; if (input_proc(hwnd, message, wParam, lParam) == 0) - return (0); + return 0; switch (message) { case WM_CREATE: @@ -876,7 +880,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) media_menu_proc(hwnd, message, wParam, lParam); break; } - return (0); + return 0; case WM_ENTERMENULOOP: break; @@ -914,7 +918,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (IsIconic(hwndMain)) { plat_vidapi_enable(0); minimized = 1; - return (0); + return 0; } else if (minimized) { minimized = 0; video_force_resize_set(1); @@ -970,7 +974,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) plat_vidapi_enable(2); } - return (0); + return 0; case WM_TIMER: if (wParam == TIMER_1SEC) @@ -988,7 +992,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: - return (0); + return 0; case WM_CLOSE: win_notify_dlg_open(); @@ -1137,7 +1141,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; } - return (0); + return 0; } static LRESULT CALLBACK @@ -1182,7 +1186,7 @@ SDLSubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } static HRESULT CALLBACK -TaskDialogProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) +TaskDialogProcedure(HWND hwnd, UINT message, UNUSED(WPARAM wParam), LPARAM lParam, UNUSED(LONG_PTR lpRefData)) { switch (message) { case TDN_HYPERLINK_CLICKED: @@ -1242,7 +1246,7 @@ ui_init(int nCmdShow) tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return (6); + return 6; } /* Load the desired language */ @@ -1251,7 +1255,7 @@ ui_init(int nCmdShow) set_language(helper_lang); win_settings_open(NULL); - return (0); + return 0; } #ifdef DISCORD @@ -1286,19 +1290,19 @@ ui_init(int nCmdShow) ExtractIconExW(path, 0, &wincl.hIcon, &wincl.hIconSm, 1); if (!RegisterClassEx(&wincl)) - return (2); + return 2; wincl.lpszClassName = SUB_CLASS_NAME; wincl.lpfnWndProc = SubWindowProcedure; if (!RegisterClassEx(&wincl)) - return (2); + return 2; wincl.lpszClassName = SDL_CLASS_NAME; wincl.lpfnWndProc = SDLMainWindowProcedure; if (!RegisterClassEx(&wincl)) - return (2); + return 2; wincl.lpszClassName = SDL_SUB_CLASS_NAME; wincl.lpfnWndProc = SDLSubWindowProcedure; if (!RegisterClassEx(&wincl)) - return (2); + return 2; /* Now create our main window. */ swprintf_s(title, sizeof_w(title), L"%hs - %s %s", vm_name, EMU_NAME_W, EMU_VERSION_FULL_W); @@ -1378,7 +1382,7 @@ ui_init(int nCmdShow) /* Warn the user about unsupported configs. */ if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void *) IDS_2146, (void *) IDS_2147, (void *) IDS_2148, (void *) IDS_2120, NULL)) { DestroyWindow(hwnd); - return (0); + return 0; } GetClipCursor(&oldclip); @@ -1392,7 +1396,7 @@ ui_init(int nCmdShow) if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { tdconfig.pszContent = MAKEINTRESOURCE(IDS_2106); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return (4); + return 4; } keyboard_getkeymap(); @@ -1401,7 +1405,7 @@ ui_init(int nCmdShow) if (haccel == NULL) { tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return (3); + return 3; } /* Initialize the mouse module. */ @@ -1420,14 +1424,14 @@ ui_init(int nCmdShow) tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2121); tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return (6); + return 6; } /* Initialize the configured Video API. */ if (!plat_setvid(vid_api)) { tdconfig.pszContent = MAKEINTRESOURCE(IDS_2090); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return (5); + return 5; } /* Set up the current window size. */ @@ -1493,7 +1497,7 @@ ui_init(int nCmdShow) if (!fs_off_signal && video_fullscreen && keyboard_isfsexit()) { /* Signal "exit fullscreen mode". */ fs_off_signal = 1; - } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_down()) { + } else if (fs_off_signal && video_fullscreen && keyboard_isfsexit_up()) { plat_setfullscreen(0); fs_off_signal = 0; } @@ -1501,7 +1505,7 @@ ui_init(int nCmdShow) if (!fs_on_signal && !video_fullscreen && keyboard_isfsenter()) { /* Signal "enter fullscreen mode". */ fs_on_signal = 1; - } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_down()) { + } else if (fs_on_signal && !video_fullscreen && keyboard_isfsenter_up()) { plat_setfullscreen(1); fs_on_signal = 0; } @@ -1640,13 +1644,13 @@ plat_mouse_capture(int on) } void -ui_init_monitor(int monitor_index) +ui_init_monitor(UNUSED(int monitor_index)) { // Nothing done here yet } void -ui_deinit_monitor(int monitor_index) +ui_deinit_monitor(UNUSED(int monitor_index)) { // Nothing done here yet } diff --git a/vcpkg.json b/vcpkg.json index 890aeed46c..d7d7ffd82e 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.0", + "version-string": "4.1.1", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", @@ -8,7 +8,9 @@ "freetype", "libpng", "sdl2", - "rtmidi" + "rtmidi", + "libslirp", + "fluidsynth" ], "features": { "qt-ui": { @@ -46,12 +48,6 @@ "libmt32emu" ] }, - "slirp": { - "description": "Slirp network support", - "dependencies": [ - "libslirp" - ] - }, "openal": { "description": "OpenAL sound backend", "dependencies": [